@humanforest/slidev-theme 0.1.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.
- package/LICENSE +67 -0
- package/README.md +577 -0
- package/assetUrl.js +38 -0
- package/components/Alert.vue +209 -0
- package/components/AreaBox.vue +152 -0
- package/components/AreaChart.vue +145 -0
- package/components/Avatar.vue +267 -0
- package/components/AvatarGroup.vue +94 -0
- package/components/BadgeStrip.vue +203 -0
- package/components/Bars.vue +207 -0
- package/components/BoroughShape.vue +127 -0
- package/components/BrowserFrame.vue +484 -0
- package/components/CalendarGrid.vue +480 -0
- package/components/Card.vue +70 -0
- package/components/Carousel.vue +266 -0
- package/components/ChartFrame.vue +426 -0
- package/components/ChordChart.vue +264 -0
- package/components/ComposedChart.vue +187 -0
- package/components/Contents.vue +86 -0
- package/components/DataTable.vue +244 -0
- package/components/DeckMap.vue +409 -0
- package/components/DeviceFrame.vue +331 -0
- package/components/DonutChart.vue +103 -0
- package/components/DottedMap.vue +126 -0
- package/components/Endorsement.vue +76 -0
- package/components/Grid.vue +169 -0
- package/components/GroupedBarChart.vue +141 -0
- package/components/IconTile.vue +116 -0
- package/components/Kpi.vue +188 -0
- package/components/LineChart.vue +133 -0
- package/components/Logo.vue +203 -0
- package/components/LondonMap.vue +348 -0
- package/components/MarkPair.vue +109 -0
- package/components/Marquee.vue +263 -0
- package/components/NestedDonutChart.vue +295 -0
- package/components/Placeholder.vue +88 -0
- package/components/SankeyChart.vue +223 -0
- package/components/ScatterChart.vue +142 -0
- package/components/StackedBarChart.vue +143 -0
- package/components/StatCard.vue +134 -0
- package/components/StatusTrack.vue +334 -0
- package/components/Timeline.vue +249 -0
- package/components/TimelineChart.vue +329 -0
- package/components/TreemapChart.vue +267 -0
- package/components/backgrounds.js +135 -0
- package/components/boroughGeometry.ts +59 -0
- package/components/chartData.ts +277 -0
- package/components/chartTip.ts +201 -0
- package/components/codeTheme.ts +239 -0
- package/components/deckPalette.ts +157 -0
- package/components/dottedMapGeometry.js +60 -0
- package/components/iconSlugs.js +55 -0
- package/components/iconUrl.js +51 -0
- package/components/mermaidTheme.ts +972 -0
- package/components/motionDuration.ts +41 -0
- package/components/tableRules.ts +257 -0
- package/confidential-mark.vue +151 -0
- package/custom-nav-controls.vue +79 -0
- package/endorsements/b-corp-black.svg +30 -0
- package/endorsements/b-corp-white.svg +30 -0
- package/global-top.vue +1662 -0
- package/icons/forest/bike-asterisk.svg +21 -0
- package/icons/forest/bike-down.svg +19 -0
- package/icons/forest/bike-off.svg +20 -0
- package/icons/forest/bike-up.svg +19 -0
- package/icons/forest/bike-x.svg +19 -0
- package/icons/forest/bike.svg +18 -0
- package/icons/forest/mark-fill.svg +6 -0
- package/icons/forest/mark.svg +6 -0
- package/icons/forest/parking.svg +3 -0
- package/icons/forest/star-fill.svg +4 -0
- package/icons/forest/star.svg +4 -0
- package/icons/forest/traffic-light-caution.svg +8 -0
- package/icons/forest/traffic-light-go.svg +8 -0
- package/icons/forest/traffic-light-lit.svg +8 -0
- package/icons/forest/traffic-light-stop.svg +8 -0
- package/icons/forest/traffic-light.svg +8 -0
- package/icons/lucide/battery.svg +1 -0
- package/icons/lucide/bike.svg +1 -0
- package/icons/lucide/chart-line.svg +1 -0
- package/icons/lucide/check.svg +1 -0
- package/icons/lucide/circle-check.svg +1 -0
- package/icons/lucide/clock.svg +1 -0
- package/icons/lucide/code.svg +1 -0
- package/icons/lucide/component.svg +1 -0
- package/icons/lucide/frame.svg +1 -0
- package/icons/lucide/layout-grid.svg +1 -0
- package/icons/lucide/map-pin.svg +1 -0
- package/icons/lucide/map.svg +1 -0
- package/icons/lucide/palette.svg +1 -0
- package/icons/lucide/table.svg +1 -0
- package/icons/lucide/triangle-alert.svg +1 -0
- package/icons/lucide/type.svg +1 -0
- package/icons/lucide/wrench.svg +1 -0
- package/layouts/bleed.vue +317 -0
- package/layouts/cover.vue +1514 -0
- package/layouts/default.vue +187 -0
- package/layouts/divider.vue +286 -0
- package/layouts/end.vue +384 -0
- package/layouts/quote.vue +218 -0
- package/layouts/split.vue +1875 -0
- package/layouts/stack.vue +944 -0
- package/layouts/statement.vue +67 -0
- package/manifest/chrome.ts +36 -0
- package/manifest/components.ts +49 -0
- package/manifest/index.ts +57 -0
- package/manifest/layouts.ts +37 -0
- package/manifest/manifest.json +6514 -0
- package/manifest/presets.ts +635 -0
- package/notch.js +458 -0
- package/notchPath.js +188 -0
- package/package.json +77 -0
- package/section.js +110 -0
- package/setup/mermaid-renderer.ts +2120 -0
- package/setup/mermaid.ts +30 -0
- package/setup/shiki.ts +44 -0
- package/setup/shortcuts.ts +28 -0
- package/slide-bottom.vue +305 -0
- package/slide-top.vue +268 -0
- package/styles/base.css +2611 -0
- package/styles/index.ts +71 -0
- package/styles/tokens.css +144 -0
- package/uno.config.ts +231 -0
- package/useNotchCuts.js +200 -0
package/slide-top.vue
ADDED
|
@@ -0,0 +1,268 @@
|
|
|
1
|
+
<script setup>
|
|
2
|
+
/*
|
|
3
|
+
Running chrome, mounted PER SLIDE — the top half. slide-bottom.vue documents why this is a
|
|
4
|
+
per-slide hook rather than a global overlay switching on layout name; the same reasoning applies
|
|
5
|
+
here, so it is not restated.
|
|
6
|
+
|
|
7
|
+
Two pills, top-left: the page number (always, once chrome is showing at all) and the section —
|
|
8
|
+
which slide-bottom.vue in Task 4's shape had no way to know, because a slide's section is not
|
|
9
|
+
something the SLIDE carries. It is the nearest PRECEDING divider's title: derived from the deck's
|
|
10
|
+
own slide list, not read off this slide's own frontmatter. See ./section.js for the derivation
|
|
11
|
+
and the two indexing/precedence traps it guards.
|
|
12
|
+
|
|
13
|
+
One tile, top-right: the Forest mark. `<Logo variant="mark">` is already self-contained — its own
|
|
14
|
+
doc comment calls it "the rounded green tile with the white tree" — so no wrapper is needed to
|
|
15
|
+
make it read as a tile; it already is one.
|
|
16
|
+
|
|
17
|
+
Both pills route through BadgeStrip rather than a hand-rolled `<span>` + scoped CSS: BadgeStrip's
|
|
18
|
+
`.badge-strip-item` already IS "--deck-radius-control, the overline type role, the chip token
|
|
19
|
+
pair" — the exact three things this step is required to use — because it is the same pill this
|
|
20
|
+
deck already ships for tags. Reaching for a second, near-identical implementation here would be
|
|
21
|
+
exactly the drift `backgrounds.js`'s own doc comment warns about: two copies of one shape that can
|
|
22
|
+
now disagree. Passing BOTH labels as one `items` array (rather than two separate <BadgeStrip>
|
|
23
|
+
calls) also gets "no pill when section is empty" for free — BadgeStrip already renders one <span>
|
|
24
|
+
per array entry, so filtering the empty string out of the array IS the "no pill" behaviour,
|
|
25
|
+
not a v-if bolted on beside it.
|
|
26
|
+
|
|
27
|
+
The pill does not take BadgeStrip's own default (`accent-dark`, --forest-950), and that is a
|
|
28
|
+
MEASURED choice rather than a preference: --deck-bg-accent-dark resolves to var(--forest-950), and
|
|
29
|
+
.deck-dark's own --deck-bg is ALSO var(--forest-950) — PINNED halves are declared once at :root and
|
|
30
|
+
are never re-pointed under .dark/.deck-dark, so an accent-dark pill would sit at exactly the ground
|
|
31
|
+
colour on any dark-register slide that doesn't opt out of chrome: an invisible-edged pill the
|
|
32
|
+
geometry audit cannot see either way. The chrome takes --deck-accent instead, which moves with
|
|
33
|
+
the register and reads against both the light ground (--warm-50) and the dark one (--forest-950).
|
|
34
|
+
|
|
35
|
+
★ FIX ROUND 1, CRITICAL 1 — `currentPage` must come from `injectionCurrentPage`, NOT
|
|
36
|
+
`useNav().currentPage`. `useNav()` is `createSharedComposable` (@slidev/client/composables/
|
|
37
|
+
useNav.ts:365) — ONE instance shared by the whole app — and its `currentPage` is
|
|
38
|
+
`currentSlideNo = hasPrimarySlide ? getSlide(params.no)?.no ?? 1 : 1`, a ROUTER value keyed off
|
|
39
|
+
`route.params.no` (useNav.ts:290-291). That param exists on the normal per-slide route, but NOT
|
|
40
|
+
on every route Slidev renders a slide through: `@slidev/client/setup/routes.ts` declares the
|
|
41
|
+
print route as `{ name: 'print', path: '/print' }` — no `:no` — and `apps/deck-template/
|
|
42
|
+
package.json`'s `export` script runs bare `slidev export`, whose one-piece PDF generator visits
|
|
43
|
+
exactly that route. On `/print`, `hasPrimarySlide` is false, so `useNav().currentPage` reads `1`
|
|
44
|
+
for EVERY slide simultaneously — `show` evaluated `1 > 1` as false on every page, and the
|
|
45
|
+
exported PDF carried no chrome at all. `/overview` is the same shape, param-less.
|
|
46
|
+
|
|
47
|
+
`injectionCurrentPage` is what SlideWrapper.vue actually provides PER SLIDE regardless of which
|
|
48
|
+
route rendered it — `provideLocal(injectionCurrentPage, ref(props.route.no))`
|
|
49
|
+
(@slidev/client/internals/SlideWrapper.vue:30) — exported from the same `constants.ts` module
|
|
50
|
+
`injectionFrontmatter` already comes from. `total` and `slides` stay on `useNav()`: those really
|
|
51
|
+
are deck-wide, not per-route.
|
|
52
|
+
*/
|
|
53
|
+
import { computed, inject } from 'vue';
|
|
54
|
+
import { useNav } from '@slidev/client';
|
|
55
|
+
import { injectionCurrentPage, injectionFrontmatter } from '@slidev/client/constants.ts';
|
|
56
|
+
import deckTokens from '@humanforest/tokens/deck/deck.json';
|
|
57
|
+
import { deriveSection } from './section.js';
|
|
58
|
+
import { chromeShows, coBrandFitted, darkChromeAt, darkChromeParts, darkRegister } from './notch.js';
|
|
59
|
+
import { backgroundStyle } from './components/backgrounds.js';
|
|
60
|
+
|
|
61
|
+
const { total, slides } = useNav();
|
|
62
|
+
const frontmatter = inject(injectionFrontmatter, {});
|
|
63
|
+
// Falls back to a ref(1), not a bare 1 — this is read as `currentPage.value` everywhere below,
|
|
64
|
+
// and SlideWrapper.vue always provides a real ref in practice; the fallback only matters for a
|
|
65
|
+
// component rendered completely outside a SlideWrapper (never happens in this theme, but inject's
|
|
66
|
+
// own default must still be the same shape as the real value or `.value` throws).
|
|
67
|
+
const currentPage = inject(injectionCurrentPage, computed(() => 1));
|
|
68
|
+
|
|
69
|
+
// Same opt-out as slide-bottom.vue, and the same slide-1 hide — a cover slide carries no page
|
|
70
|
+
// number worth reading and can never have a divider behind it. The predicate itself lives in
|
|
71
|
+
// ./notch.js now, not because this file needed it moved but because split.vue needs the SAME
|
|
72
|
+
// answer: a panel only cuts a notch when there is actually a mark to seat in it (task-15-brief.md's
|
|
73
|
+
// own named failure case — a notch on a `chrome: false` slide is a hole with nothing in it).
|
|
74
|
+
const show = computed(() => chromeShows(frontmatter, currentPage.value));
|
|
75
|
+
|
|
76
|
+
/*
|
|
77
|
+
★★ THE CHROME OPTS ITSELF INTO THE DARK REGISTER, because nothing else can put it there.
|
|
78
|
+
|
|
79
|
+
`deck-dark` lands on `.slidev-layout` — that is where both `class: deck-dark` and the layouts'
|
|
80
|
+
`dark` prop write it — and SlideWrapper renders this chrome as a SIBLING of the layout, not a
|
|
81
|
+
descendant. So every --deck-* role inside the chrome kept resolving on the LIGHT register while
|
|
82
|
+
the slide beside it was dark. Measured on a `dark: true` slide before this: the page pill painted
|
|
83
|
+
forest-700 with white ink, identical to its light-register self.
|
|
84
|
+
|
|
85
|
+
Reading the same frontmatter this component already injects and stamping the class on its own root
|
|
86
|
+
is the only place the two can be reconciled without moving `deck-dark` onto the page element,
|
|
87
|
+
which no layout can reach.
|
|
88
|
+
*/
|
|
89
|
+
// Delegated to notch.js: a cover can resolve a dark ground from its VARIANT without saying so in
|
|
90
|
+
// frontmatter, and this row is a sibling of the layout so it cannot read the classes that resolution
|
|
91
|
+
// lands as. See darkRegister() — the same module, and the same reason, as darkChromeParts below.
|
|
92
|
+
const isDarkRegister = computed(() => darkRegister(frontmatter));
|
|
93
|
+
// …and the HALVES. A bleeding `panelDark` panel is dark under one end of this row and light under
|
|
94
|
+
// the other, so the register lands per end rather than on the row. See darkChromeParts().
|
|
95
|
+
const darkParts = computed(() => darkChromeParts(frontmatter).top);
|
|
96
|
+
|
|
97
|
+
/*
|
|
98
|
+
★ THE MIRROR — chrome sits on the TEXT side, the mark sits on the PANEL side.
|
|
99
|
+
|
|
100
|
+
Jose: "if text is left or right, the notch position should adapt (and move the page to the other
|
|
101
|
+
side, along with the confidenciality chip)". `flip` is frontmatter, so this component can read it
|
|
102
|
+
exactly the way it already reads `chrome` — no new plumbing and no coupling to split.vue, which
|
|
103
|
+
reads the same key as its own prop and cuts its notch on the opposite side of the slide.
|
|
104
|
+
|
|
105
|
+
★ THAT MIRROR IS GONE. It flipped the row on a `flip: true` split so the mark could sit in the
|
|
106
|
+
notch cut from the figure's top-left corner. The mark is fixed top-right now and the notch is only
|
|
107
|
+
cut where it can reach — see the note above hasNotch in ./notch.js for the reasoning and what it
|
|
108
|
+
cost. What is left here is one arrangement, so this file no longer computes a side at all.
|
|
109
|
+
*/
|
|
110
|
+
// The arrangement is FIXED: pills left, mark right, on every slide. It used to flip on a
|
|
111
|
+
// `flip: true` split so the mark could sit in the notch cut from the figure's top-left corner —
|
|
112
|
+
// see the note above hasNotch in ./notch.js for why that went and what it cost.
|
|
113
|
+
|
|
114
|
+
|
|
115
|
+
const section = computed(() => deriveSection(slides.value, currentPage.value));
|
|
116
|
+
// Only the section rides in the BadgeStrip now. The page number is a CIRCLE, which is a different
|
|
117
|
+
// geometry from a text pill (equal on both axes, sized by its own line box rather than by its
|
|
118
|
+
// content's width), so it cannot be one of BadgeStrip's items without either stretching for a
|
|
119
|
+
// 3-digit number or clipping one. It keeps BadgeStrip's tone pair and type role so the two still
|
|
120
|
+
// read as one family — see .deck-page-dot below.
|
|
121
|
+
const sectionLabels = computed(() => [section.value].filter(Boolean));
|
|
122
|
+
|
|
123
|
+
// ★ THE MARK'S SIZE IS A TOKEN NOW, read rather than restated (task-15-brief.md). It used to be a
|
|
124
|
+
// literal here, on the reasoning that Logo's `size` prop takes a plain number (cover.vue :size="72",
|
|
125
|
+
// end.vue :size="88") and sets an SVG geometry scale rather than a CSS box, so no --deck-* property
|
|
126
|
+
// had the right shape. That reasoning held while this component was the only thing that cared. It
|
|
127
|
+
// no longer is: split.vue cuts a notch sized from this exact number, and a value only one of the two
|
|
128
|
+
// can see is precisely how a cut-out and its occupant drift apart. deck.json is the same generated
|
|
129
|
+
// artefact --deck-chrome-mark is emitted from, so the mark the chrome DRAWS and the mark the notch
|
|
130
|
+
// is CUT FOR cannot disagree — change MARK_PX in scripts/deck.ts and both move.
|
|
131
|
+
const MARK_SIZE = deckTokens.chrome.markPx;
|
|
132
|
+
|
|
133
|
+
/*
|
|
134
|
+
★ CO-BRANDING — `companion:` in a slide's own frontmatter.
|
|
135
|
+
|
|
136
|
+
THE OCCUPANT IS COMPUTED, NOT DRAWN AND THEN MEASURED. ./notch.js's coBrand() is a pure function
|
|
137
|
+
of the frontmatter plus deck.json's own chrome numbers, and split.vue/stack.vue call the SAME
|
|
138
|
+
function for the same slide — so the box this component draws and the cut those layouts make are
|
|
139
|
+
the same width by construction, not by two files agreeing to use the same literal. Nothing here
|
|
140
|
+
reads a rendered size back, which is what lets the mask be correct on the first frame.
|
|
141
|
+
|
|
142
|
+
--deck-notch-occupant-w is set INLINE, and ONLY when there is a companion. The escape hatch for
|
|
143
|
+
the width is a `class:` on the slide overriding the property, and an inline style on this element
|
|
144
|
+
outranks one. No companion, no declaration, so that override still reaches.
|
|
145
|
+
|
|
146
|
+
The HEIGHT never moves — a co-brand lockup shares ONE height
|
|
147
|
+
(packages/ui/src/logo/FSubLogo.vue's own rule, which sets both halves at the wordmark's height
|
|
148
|
+
and measures only the gap between them), so a companion's mark is as tall as the Forest mark and
|
|
149
|
+
only the width grows.
|
|
150
|
+
|
|
151
|
+
⚠ IT IS `object-fit: cover`, NOT `contain`. The square and its corner are the whole point of the
|
|
152
|
+
pairing, and `contain` letterboxes a non-square source inside that square, which puts the ragged
|
|
153
|
+
silhouette back. Whatever the file is, it is covered into a mark-sized tile so the two read as one
|
|
154
|
+
lockup.
|
|
155
|
+
*/
|
|
156
|
+
const companion = computed(() => coBrandFitted(frontmatter, currentPage.value, deckTokens));
|
|
157
|
+
/* The alt text is the author's `companionName`. The fallback is deliberately vague because the
|
|
158
|
+
theme cannot know what the file depicts — a partner's logo, an app icon, a customer's face — and
|
|
159
|
+
a specific wrong alt is worse than a generic right one. Name it. */
|
|
160
|
+
const companionLabel = computed(() => frontmatter?.companionName || 'Companion mark');
|
|
161
|
+
// Undefined — not an empty object and not a `null` value — when there is no companion: Vue drops an
|
|
162
|
+
// undefined :style binding entirely, where `{ '--x': null }` still writes an empty declaration.
|
|
163
|
+
const occupantStyle = computed(() =>
|
|
164
|
+
companion.value ? { '--deck-notch-occupant-w': `${companion.value.occupantPx}px` } : undefined,
|
|
165
|
+
);
|
|
166
|
+
</script>
|
|
167
|
+
|
|
168
|
+
<template>
|
|
169
|
+
<div v-if="show" :class="['deck-chrome-top', isDarkRegister ? 'deck-dark' : '']">
|
|
170
|
+
<!-- The page number LEFT this row (task: "the page number i think it can go at the bottom, other
|
|
171
|
+
extreme of the confidential chip"). It lives in slide-bottom.vue now, paired against the
|
|
172
|
+
confidentiality pill across the foot of the slide. What stays here is the section, which is
|
|
173
|
+
the one label a reader looks UP for — where they are, not how far in. -->
|
|
174
|
+
<div class="deck-chrome-pills" :class="darkChromeAt(darkParts, 'left') ? 'deck-dark' : ''">
|
|
175
|
+
<BadgeStrip v-if="sectionLabels.length" :items="sectionLabels" chrome />
|
|
176
|
+
</div>
|
|
177
|
+
<!-- The occupant. A BOX, not a bare mark — see .deck-chrome-mark below. Forest always leads,
|
|
178
|
+
and now so does the position: the mark holds the right-hand end of this row on every slide.
|
|
179
|
+
The attribute stays rather than being folded into the class, because useNotchCuts.js reads
|
|
180
|
+
the rendered corner rather than being told one, and a literal is the honest way to say a
|
|
181
|
+
value no longer varies. -->
|
|
182
|
+
<MarkPair
|
|
183
|
+
class="deck-chrome-mark"
|
|
184
|
+
:class="darkChromeAt(darkParts, 'right') ? 'deck-dark' : ''"
|
|
185
|
+
data-mark-side="right"
|
|
186
|
+
:style="occupantStyle"
|
|
187
|
+
:src="companion?.src ?? ''"
|
|
188
|
+
:label="companionLabel"
|
|
189
|
+
:size="MARK_SIZE"
|
|
190
|
+
/>
|
|
191
|
+
</div>
|
|
192
|
+
</template>
|
|
193
|
+
|
|
194
|
+
<style scoped>
|
|
195
|
+
.deck-chrome-top {
|
|
196
|
+
position: absolute;
|
|
197
|
+
/* task-14-brief.md — chrome is inset --deck-inset-chrome (36px, task-14b-brief.md's revision of
|
|
198
|
+
the original 40px/one-grid-unit figure) on every edge it touches, uniform with
|
|
199
|
+
slide-bottom.vue's pill and with the mark's own corner. Was --deck-space-3 (24px) top /
|
|
200
|
+
grid*2.5 (100px) sides — two different numbers for one kind of content (furniture); now one
|
|
201
|
+
token, one meaning. See base.css's `.slidev-layout` comment and scripts/deck.ts's INSET
|
|
202
|
+
comment for the full two-track reasoning this is half of. */
|
|
203
|
+
top: var(--deck-inset-chrome);
|
|
204
|
+
left: var(--deck-inset-chrome);
|
|
205
|
+
right: var(--deck-inset-chrome);
|
|
206
|
+
display: flex;
|
|
207
|
+
/* flex-START, not centre. The row is the MARK's height (72), the section pill is 49, so centring
|
|
208
|
+
put the pill's top at 47.5 — 11.5px below the mark's own 36. Invisible on a bare slide; obvious
|
|
209
|
+
the moment the pill sits on a stack band, whose top edge is also 36 and gives the eye a hard
|
|
210
|
+
line to judge against. Reported by eye: "why this sits not at the same level? i think it should
|
|
211
|
+
be 36 px". Top-aligning makes one shared edge at --deck-inset-chrome for the mark, the pill and
|
|
212
|
+
any panel or band below them, which is the thing the inset system is for. */
|
|
213
|
+
align-items: flex-start;
|
|
214
|
+
justify-content: space-between;
|
|
215
|
+
/* The band is the MARK's height, floor — so the mark's own top stays at --deck-inset-chrome (the
|
|
216
|
+
point split.vue and stack.vue cut their notch against) whatever else is in the row. A `min-`,
|
|
217
|
+
not a fixed height, because the documented escape hatch lets a slide override
|
|
218
|
+
--deck-notch-occupant-h for a taller occupant, and that one is meant to grow the band. */
|
|
219
|
+
min-height: var(--deck-chrome-mark);
|
|
220
|
+
z-index: 20;
|
|
221
|
+
/* Click-through, like slide-bottom.vue's chrome — this is a running label, never a control. */
|
|
222
|
+
pointer-events: none;
|
|
223
|
+
}
|
|
224
|
+
/*
|
|
225
|
+
THE OCCUPANT BOX — the mark's own size, expressed the way the notch reads it.
|
|
226
|
+
|
|
227
|
+
This is a wrapper rather than the class on <Logo> itself because the notch and the mark have to
|
|
228
|
+
agree on ONE box: split.vue cuts `occupant + gap`, reading the same two custom properties this
|
|
229
|
+
reads, so overriding --deck-notch-occupant-w/-h on a slide resizes the cut and its occupant
|
|
230
|
+
together — one mark, a forest+companion pair, an image, a content block. The `size` prop still
|
|
231
|
+
passes the token's own number so the SVG's intrinsic geometry matches the default box; the box is
|
|
232
|
+
what the notch is measured against.
|
|
233
|
+
|
|
234
|
+
`height: 100%; width: auto` on the mark, and the box aligned to its OUTER edge: a wider occupant
|
|
235
|
+
is wider because it holds MORE, not because the mark stretches. The default is a square box
|
|
236
|
+
holding a square mark, where none of this is visible — it only matters once the box is not.
|
|
237
|
+
*/
|
|
238
|
+
.deck-chrome-mark {
|
|
239
|
+
flex: none;
|
|
240
|
+
/* The row itself — display, alignment and the gap between the two halves — is MarkPair's, which
|
|
241
|
+
derives that gap from the `size` this component passes. --deck-chrome-pair-gap is still the
|
|
242
|
+
number both readers of the CUT use: ./notch.js's coBrand() adds it to reach the occupant width
|
|
243
|
+
and scripts/deck.ts adds it again to prove a forest+companion pair fits the narrowest ratio.
|
|
244
|
+
MarkPair reads the same two chrome numbers out of deck.json, so the lockup and the cut made for
|
|
245
|
+
it cannot drift. */
|
|
246
|
+
width: var(--deck-notch-occupant-w, var(--deck-chrome-mark));
|
|
247
|
+
height: var(--deck-notch-occupant-h, var(--deck-chrome-mark));
|
|
248
|
+
}
|
|
249
|
+
/* Only 'right' is emitted now. The 'left' rule went with the mirror rather than being left behind
|
|
250
|
+
as a selector nothing can match. */
|
|
251
|
+
.deck-chrome-mark[data-mark-side='right'] { justify-content: flex-end; }
|
|
252
|
+
/*
|
|
253
|
+
★★ THE PARTNER'S TILE IS NOT DRAWN HERE ANY MORE — components/MarkPair.vue draws it, and this
|
|
254
|
+
component passes the size. The rounded square, the ring in `currentColor`, the `cover` fit and the
|
|
255
|
+
gap between the two halves were all stated in this file with the chrome's own fixed px tokens;
|
|
256
|
+
cover.vue then drew the same pair twice more, and its poster — at 120px — inherited a corner and a
|
|
257
|
+
ring computed for a 72px tile. The geometry is one component's now, derived from `size`, and this
|
|
258
|
+
file keeps only what is about the CHROME: where the box sits, how wide the notch thinks it is, and
|
|
259
|
+
which register it is in.
|
|
260
|
+
*/
|
|
261
|
+
|
|
262
|
+
.deck-chrome-top.deck-dark,
|
|
263
|
+
.deck-chrome-pills.deck-dark,
|
|
264
|
+
.deck-chrome-mark.deck-dark,
|
|
265
|
+
.deck-chrome-confidential.deck-dark {
|
|
266
|
+
background: transparent;
|
|
267
|
+
}
|
|
268
|
+
</style>
|