@things-factory/figure-ui 10.1.175 → 10.1.177
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/client/modeller/editor-styles.ts +4 -6
- package/client/modeller/editor.ts +41 -39
- package/client/modeller/figure-links.ts +41 -12
- package/client/modeller/figure-parts.ts +31 -14
- package/client/modeller/figure-properties.ts +2 -2
- package/client/pages/figure-modeller-page.ts +34 -11
- package/dist-client/modeller/editor-styles.js +4 -6
- package/dist-client/modeller/editor-styles.js.map +1 -1
- package/dist-client/modeller/editor.d.ts +6 -10
- package/dist-client/modeller/editor.js +34 -37
- package/dist-client/modeller/editor.js.map +1 -1
- package/dist-client/modeller/figure-links.d.ts +7 -2
- package/dist-client/modeller/figure-links.js +45 -11
- package/dist-client/modeller/figure-links.js.map +1 -1
- package/dist-client/modeller/figure-parts.js +31 -14
- package/dist-client/modeller/figure-parts.js.map +1 -1
- package/dist-client/modeller/figure-properties.js +2 -2
- package/dist-client/modeller/figure-properties.js.map +1 -1
- package/dist-client/pages/figure-modeller-page.js +34 -11
- package/dist-client/pages/figure-modeller-page.js.map +1 -1
- package/dist-client/route.d.ts +1 -1
- package/dist-client/tsconfig.tsbuildinfo +1 -1
- package/package.json +6 -6
- package/test/browser/acceptance-page.js +2 -1
- package/test/browser/build.mjs +9 -1
- package/test/browser/editing-page.js +2 -1
- package/test/browser/links.check.mjs +24 -9
- package/test/browser/modeller.check.mjs +6 -0
- package/test/browser/parts.check.mjs +3 -12
- package/test/browser/places-mesh.check.mjs +4 -9
- package/test/browser/props.check.mjs +67 -12
- package/test/browser/row-preview.check.mjs +4 -0
- package/test/browser/screen.check.mjs +49 -19
- package/test/browser/serve-acceptance.mjs +2 -1
- package/test/place-words.test.ts +31 -0
- package/translations/en.json +6 -3
- package/translations/es.json +3 -0
- package/translations/ja.json +3 -0
- package/translations/ko.json +6 -3
- package/translations/ms.json +3 -0
- package/translations/zh.json +3 -0
|
@@ -263,15 +263,13 @@ export const EditorStyles = css`
|
|
|
263
263
|
/* The part's own numbers inside a group the links draw (size, place): one column, the panel's gap. */
|
|
264
264
|
div[group-fields] {
|
|
265
265
|
display: grid;
|
|
266
|
-
gap:
|
|
266
|
+
gap: 6px;
|
|
267
267
|
}
|
|
268
|
-
/*
|
|
269
|
-
section[more] > details > summary
|
|
270
|
-
section[capability] > details > summary {
|
|
268
|
+
/* The folded 「더 보기」: its title is the fold's handle, at the title's size. */
|
|
269
|
+
section[more] > details > summary {
|
|
271
270
|
padding: 0;
|
|
272
271
|
}
|
|
273
|
-
section[more] > details > summary > h3
|
|
274
|
-
section[capability] > details > summary > h3 {
|
|
272
|
+
section[more] > details > summary > h3 {
|
|
275
273
|
margin: 0;
|
|
276
274
|
}
|
|
277
275
|
div[more-body] {
|
|
@@ -72,12 +72,13 @@ import { groupMenu, GroupMenuStyles } from './group-menu.js'
|
|
|
72
72
|
|
|
73
73
|
|
|
74
74
|
/**
|
|
75
|
-
* The side's
|
|
76
|
-
*
|
|
77
|
-
*
|
|
78
|
-
*
|
|
75
|
+
* The side's six tabs (user 2026-10-17: up to six): properties -- the part's shape, place and look; 「반응형」 -- how it
|
|
76
|
+
* answers a size it is placed at (its size rules, a position that follows the size, its row; the figure's range);
|
|
77
|
+
* motion; what it does (its places); its data (ADR-0051); the verdict. The view is a menu over the canvas and the
|
|
78
|
+
* release history opens from the bar, since neither is about the part chosen. The verdict gives way to properties when
|
|
79
|
+
* a part is chosen; a tab about parts keeps showing the newly chosen part.
|
|
79
80
|
*/
|
|
80
|
-
type SideTab = 'properties' | 'motion' | 'data' | 'verdict'
|
|
81
|
+
type SideTab = 'properties' | 'response' | 'motion' | 'capability' | 'data' | 'verdict'
|
|
81
82
|
|
|
82
83
|
/** What opens over the work from the bar: the view settings or the release history, one at a time. */
|
|
83
84
|
type BarOverlay = 'view' | 'history'
|
|
@@ -134,8 +135,6 @@ export class FigureEditor extends LitElement {
|
|
|
134
135
|
@state() private tab: SideTab = 'properties'
|
|
135
136
|
/** The view settings or the release history, open over the work from the bar. */
|
|
136
137
|
@state() private overlay?: BarOverlay
|
|
137
|
-
/** The capability group open: the canvas marks the places only while their group is in sight. */
|
|
138
|
-
@state() private capabilityOpen = false
|
|
139
138
|
/** 「더 보기」 open, as this person left it last (chief architect 2026-10-16: kept per person). */
|
|
140
139
|
@state() private moreOpen = FigureEditor.storedMoreOpen()
|
|
141
140
|
private static storedMoreOpen(): boolean {
|
|
@@ -199,7 +198,7 @@ export class FigureEditor extends LitElement {
|
|
|
199
198
|
session: () => this.session,
|
|
200
199
|
selected: () => this.selected,
|
|
201
200
|
shown: () => this.shown(),
|
|
202
|
-
formsInSight: () => this.middle === 'edit' && this.tab === 'properties',
|
|
201
|
+
formsInSight: () => this.middle === 'edit' && (this.tab === 'properties' || this.tab === 'response'),
|
|
203
202
|
said: error => this.said(error)
|
|
204
203
|
})
|
|
205
204
|
/**
|
|
@@ -752,12 +751,14 @@ export class FigureEditor extends LitElement {
|
|
|
752
751
|
}
|
|
753
752
|
}
|
|
754
753
|
/** Size response, fastening and motion for the selected part, as authoring commands. */
|
|
755
|
-
private renderLinks(unavailable: boolean, section: 'shape' | 'places' | 'motion', slotted: unknown = nothing) {
|
|
754
|
+
private renderLinks(unavailable: boolean, section: 'shape' | 'response' | 'places' | 'motion', slotted: unknown = nothing) {
|
|
756
755
|
const shown = this.shown()
|
|
757
756
|
if (!shown) return null
|
|
757
|
+
const tab: SideTab = section === 'shape' ? 'properties' : section === 'places' ? 'capability' : section
|
|
758
758
|
return html`<figure-links
|
|
759
759
|
.revision=${shown}
|
|
760
760
|
.section=${section}
|
|
761
|
+
.active=${this.tab === tab}
|
|
761
762
|
.partId=${this.selected}
|
|
762
763
|
?locked=${unavailable}
|
|
763
764
|
@command=${(e: CustomEvent) => this.linkCommand(e.detail.action)}
|
|
@@ -772,9 +773,10 @@ export class FigureEditor extends LitElement {
|
|
|
772
773
|
>${slotted}</figure-links>`
|
|
773
774
|
}
|
|
774
775
|
/**
|
|
775
|
-
* A part's groups in one order whatever its state (chief architect 2026-10-16): its size, its place
|
|
776
|
-
*
|
|
777
|
-
*
|
|
776
|
+
* A part's groups in one order whatever its state (chief architect 2026-10-16): its size, its place. The links draw
|
|
777
|
+
* the groups; the part's own numbers go into them by slot. How the part answers a size -- its rules, a position that
|
|
778
|
+
* follows, its row -- is the 「반응형」 tab's. A fastened part's place and turn are its fastening's: the place group
|
|
779
|
+
* says it in one line and the locked cells are not drawn (user 2026-10-16).
|
|
778
780
|
*/
|
|
779
781
|
private renderPartGroups(shown: FigureRevision | undefined, geometry: readonly { id: string }[], fields: FieldLike[], unavailable: boolean, held?: HeldValues) {
|
|
780
782
|
const groups = this.withSizeRow(groupFields(fields, this.selected), held)
|
|
@@ -795,28 +797,12 @@ export class FigureEditor extends LitElement {
|
|
|
795
797
|
: nothing}
|
|
796
798
|
${place.length && !placeLocked
|
|
797
799
|
? html`<div slot="place" group-fields>${place.map(g => this.renderVector(g, unavailable, held))}${this.renderHeldAxes(place)}</div>`
|
|
798
|
-
: nothing}
|
|
799
|
-
${this.renderRepeat(shown, geometry, unavailable)}`
|
|
800
|
+
: nothing}`
|
|
800
801
|
)
|
|
801
802
|
}
|
|
802
|
-
/**
|
|
803
|
-
|
|
804
|
-
|
|
805
|
-
*/
|
|
806
|
-
private renderCapability(asset: FigureAsset | undefined, unavailable: boolean) {
|
|
807
|
-
return html`<section capability>
|
|
808
|
-
<details capability-fold ?open=${this.capabilityOpen} @toggle=${(e: Event) => (this.capabilityOpen = (e.target as HTMLDetailsElement).open)}>
|
|
809
|
-
<summary><h3>${i18next.t('figure.label.tab-capability')}</h3></summary>
|
|
810
|
-
${this.selected ? this.renderLinks(unavailable, 'places') : nothing}
|
|
811
|
-
<figure-capability-panel
|
|
812
|
-
.asset=${asset}
|
|
813
|
-
.selected=${this.selected}
|
|
814
|
-
?locked=${unavailable}
|
|
815
|
-
@select-part=${(e: CustomEvent) => this.choose(e.detail.id)}
|
|
816
|
-
@part-edit=${(e: CustomEvent) => this.run(() => this.session!.edit(e.detail.edit))}
|
|
817
|
-
></figure-capability-panel>
|
|
818
|
-
</details>
|
|
819
|
-
</section>`
|
|
803
|
+
/** The 「반응형」 tab of a part: the links' response groups, its row's own section put in by slot. */
|
|
804
|
+
private renderResponse(shown: FigureRevision | undefined, geometry: readonly { id: string }[], unavailable: boolean) {
|
|
805
|
+
return this.renderLinks(unavailable, 'response', this.renderRepeat(shown, geometry, unavailable))
|
|
820
806
|
}
|
|
821
807
|
/**
|
|
822
808
|
* 「더 보기」: what few parts need, folded by default and left as this person last left it (chief architect
|
|
@@ -1747,7 +1733,7 @@ export class FigureEditor extends LitElement {
|
|
|
1747
1733
|
@configure-size=${async (e: CustomEvent<{ part: string }>) => {
|
|
1748
1734
|
this.middle = 'edit'
|
|
1749
1735
|
this.selected = e.detail.part
|
|
1750
|
-
this.tab = '
|
|
1736
|
+
this.tab = 'response'
|
|
1751
1737
|
await this.updateComplete
|
|
1752
1738
|
this.renderRoot.querySelector('figure-links')?.scrollIntoView({ block: 'nearest' })
|
|
1753
1739
|
}}
|
|
@@ -1764,7 +1750,7 @@ export class FigureEditor extends LitElement {
|
|
|
1764
1750
|
.fan=${this.fanOf(shown, live)}
|
|
1765
1751
|
.ghost=${this.previewShown().ghost}
|
|
1766
1752
|
.highlight=${this.previewShown().highlight}
|
|
1767
|
-
.marks=${this.tab === '
|
|
1753
|
+
.marks=${this.tab === 'capability' ? this.slotMarks(view, asset) : NO_MARKS}
|
|
1768
1754
|
.palette=${view.palette ?? {}}
|
|
1769
1755
|
.context=${view.context ?? ''}
|
|
1770
1756
|
.selected=${this.selected}
|
|
@@ -1778,7 +1764,9 @@ export class FigureEditor extends LitElement {
|
|
|
1778
1764
|
<aside slot="end">
|
|
1779
1765
|
<div tabs>
|
|
1780
1766
|
${this.renderTab('properties', 'tune', i18next.t('figure.label.properties'))}
|
|
1767
|
+
${this.renderTab('response', 'aspect_ratio', i18next.t('figure.label.tab-response'))}
|
|
1781
1768
|
${this.renderTab('motion', 'animation', i18next.t('figure.label.motion'))}
|
|
1769
|
+
${this.renderTab('capability', 'conveyor_belt', i18next.t('figure.label.tab-capability'))}
|
|
1782
1770
|
${this.renderTab('data', 'sensors', i18next.t('figure.label.tab-data'))}
|
|
1783
1771
|
${this.renderTab('verdict', 'insights', i18next.t('figure.label.maturity'), this.instances)}
|
|
1784
1772
|
</div>
|
|
@@ -1809,7 +1797,6 @@ export class FigureEditor extends LitElement {
|
|
|
1809
1797
|
@part-edit=${(e: CustomEvent) => this.run(() => this.session!.edit(e.detail.edit))}
|
|
1810
1798
|
@part-live=${(e: CustomEvent) => this.hold({}, e.detail.edit)}
|
|
1811
1799
|
></figure-material-panel>
|
|
1812
|
-
${this.renderCapability(asset, unavailable)}
|
|
1813
1800
|
${this.renderMore(part, view.palette ?? {}, unavailable)}`
|
|
1814
1801
|
: view.geometry.length === 0
|
|
1815
1802
|
? html`${this.renderSubject()}<section empty-figure>
|
|
@@ -1819,16 +1806,31 @@ export class FigureEditor extends LitElement {
|
|
|
1819
1806
|
<slot name="figure"></slot>
|
|
1820
1807
|
</details>
|
|
1821
1808
|
</section>`
|
|
1822
|
-
: html`${this.renderSubject()}<slot name="figure"></slot
|
|
1823
|
-
|
|
1824
|
-
|
|
1825
|
-
|
|
1809
|
+
: html`${this.renderSubject()}<slot name="figure"></slot>`}
|
|
1810
|
+
</div>
|
|
1811
|
+
<div panel ?off=${tab !== 'response'}>
|
|
1812
|
+
${this.renderSubject()}
|
|
1813
|
+
${this.selected && part
|
|
1814
|
+
? this.renderResponse(shown, view.geometry, unavailable)
|
|
1815
|
+
: html`${this.renderGroups(groupFields(common), 'figure.label.group-figure-size', 'figure.label.design-inputs', unavailable)}
|
|
1816
|
+
${this.renderInstanceRange(shown, unavailable)}`}
|
|
1826
1817
|
</div>
|
|
1827
1818
|
<div panel ?off=${tab !== 'motion'}>
|
|
1828
1819
|
${this.renderSubject()}
|
|
1829
1820
|
${this.selected && part ? this.renderLinks(unavailable, 'motion') : html`<section><p hint>${i18next.t('figure.text.choose-a-part-to-move')}</p></section>`}
|
|
1830
1821
|
${this.renderControls(view, unavailable)}
|
|
1831
1822
|
</div>
|
|
1823
|
+
<div panel ?off=${tab !== 'capability'}>
|
|
1824
|
+
${this.renderSubject()}
|
|
1825
|
+
${this.selected && part ? this.renderLinks(unavailable, 'places') : nothing}
|
|
1826
|
+
<figure-capability-panel
|
|
1827
|
+
.asset=${asset}
|
|
1828
|
+
.selected=${this.selected}
|
|
1829
|
+
?locked=${unavailable}
|
|
1830
|
+
@select-part=${(e: CustomEvent) => this.choose(e.detail.id)}
|
|
1831
|
+
@part-edit=${(e: CustomEvent) => this.run(() => this.session!.edit(e.detail.edit))}
|
|
1832
|
+
></figure-capability-panel>
|
|
1833
|
+
</div>
|
|
1832
1834
|
<div panel ?off=${tab !== 'data'}>
|
|
1833
1835
|
${this.renderSubject()}
|
|
1834
1836
|
<figure-data-panel
|
|
@@ -121,8 +121,10 @@ export class FigureLinks extends localize(i18next)(LitElement) {
|
|
|
121
121
|
flex: 1;
|
|
122
122
|
margin: 0;
|
|
123
123
|
}
|
|
124
|
-
|
|
125
|
-
|
|
124
|
+
/* Opening the form is an action: the primary colour, at the line's end. */
|
|
125
|
+
div[fastened-summary] > button[act] {
|
|
126
|
+
flex: none;
|
|
127
|
+
margin: 0 -6px 0 0;
|
|
126
128
|
}
|
|
127
129
|
/* The measure's name, then its rule: X, or a cylinder's 반지름 · 길이, on one line. */
|
|
128
130
|
div[row] > b {
|
|
@@ -182,7 +184,12 @@ export class FigureLinks extends localize(i18next)(LitElement) {
|
|
|
182
184
|
@property() partId = ''
|
|
183
185
|
@property({ type: Boolean }) locked = false
|
|
184
186
|
/** Which ties this shows: the part's shape (size and placement, in 속성), its places (자리·능력) or its motion (움직임). */
|
|
185
|
-
@property() section: 'shape' | 'places' | 'motion' = 'shape'
|
|
187
|
+
@property() section: 'shape' | 'response' | 'places' | 'motion' = 'shape'
|
|
188
|
+
/**
|
|
189
|
+
* Its tab is the one shown. Two sections speak of what a command would draw -- the properties' fastening and the
|
|
190
|
+
* response's row -- and only the one in sight may: the hidden one's silence would clear what the shown one draws.
|
|
191
|
+
*/
|
|
192
|
+
@property({ type: Boolean }) active = true
|
|
186
193
|
/** What the fastening command would do, in words (the editor works it out: `command-preview.ts`). */
|
|
187
194
|
@property({ attribute: false }) previewWords: string[] = []
|
|
188
195
|
/** Where the selected part's motion takes it, at both ends of its range (the editor draws them on the canvas). */
|
|
@@ -229,6 +236,8 @@ export class FigureLinks extends localize(i18next)(LitElement) {
|
|
|
229
236
|
fastening it has" over an empty target (2026-09-27, :3391, the doors). */
|
|
230
237
|
private loadedFor?: string
|
|
231
238
|
willUpdate(changed: Map<string, unknown>) {
|
|
239
|
+
/* Its tab shown again: what it would draw is said again, over whatever the other tab left. */
|
|
240
|
+
if (changed.has('active') && this.active && changed.get('active') === false) this.told = ''
|
|
232
241
|
/* What 고치기 said is about the figure as it was: another step or another part, and it no longer holds. */
|
|
233
242
|
if (changed.has('asset') || changed.has('partId')) this.fixNote = ''
|
|
234
243
|
if (this.asset && this.partId && this.partId !== this.loadedFor) {
|
|
@@ -246,9 +255,10 @@ export class FigureLinks extends localize(i18next)(LitElement) {
|
|
|
246
255
|
}
|
|
247
256
|
|
|
248
257
|
updated() {
|
|
249
|
-
/* Only the
|
|
250
|
-
others' silence cleared what it showed (2026-09-27, :3391). */
|
|
251
|
-
|
|
258
|
+
/* Only the sections that hold a form speak of what it would do, and only while their tab is shown: the panel has
|
|
259
|
+
one of these per section, and the others' silence cleared what it showed (2026-09-27, :3391). */
|
|
260
|
+
const speaks = this.active && (this.section === 'shape' || this.section === 'response')
|
|
261
|
+
if (!speaks) return
|
|
252
262
|
const said = JSON.stringify(this.candidate ?? null)
|
|
253
263
|
if (said === this.told) return
|
|
254
264
|
this.told = said
|
|
@@ -299,12 +309,33 @@ export class FigureLinks extends localize(i18next)(LitElement) {
|
|
|
299
309
|
*/
|
|
300
310
|
/* Fastened, by a face or by an origin: either can be taken off, from the place group's 「⋯」. */
|
|
301
311
|
const held = !!heldBy(asset, this.partId) || !!(this.revision && fasteningOf(this.revision, this.partId)?.atOrigin)
|
|
312
|
+
if (this.section === 'response') {
|
|
313
|
+
/*
|
|
314
|
+
How the part answers a size it is placed at (user 2026-10-17, the 「반응형」 tab): its own measures, where it
|
|
315
|
+
stands, and the row it may make -- what Build Once, Fit Anywhere is authored with, in one place.
|
|
316
|
+
*/
|
|
317
|
+
const positions = positionsWorkedOut(asset, this.partId)
|
|
318
|
+
const response = html`
|
|
319
|
+
<section size-response>
|
|
320
|
+
<h3>${i18next.t('figure.label.group-size')}</h3>
|
|
321
|
+
<p group-question>${i18next.t('figure.label.resize-intent')}</p>
|
|
322
|
+
${canFollow(asset, this.partId) ? this.renderDimensions(asset) : html`<p hint>${i18next.t('figure.text.links-need-a-box')}</p>`}
|
|
323
|
+
</section>
|
|
324
|
+
${positions.length
|
|
325
|
+
? html`<section position-response>
|
|
326
|
+
<h3>${i18next.t('figure.label.group-position-response')}</h3>
|
|
327
|
+
${this.renderPositions(asset)}
|
|
328
|
+
</section>`
|
|
329
|
+
: nothing}
|
|
330
|
+
${rowOf(asset, this.partId) ? html`<slot name="row"></slot>` : this.renderRow(asset)}
|
|
331
|
+
`
|
|
332
|
+
this.candidate = this.working === 'row' && this.rowCandidate ? { action: this.rowCandidate } : undefined
|
|
333
|
+
return response
|
|
334
|
+
}
|
|
302
335
|
const shown = html`
|
|
303
336
|
<section size>
|
|
304
337
|
<h3>${i18next.t('figure.label.group-size')}</h3>
|
|
305
338
|
<slot name="size"></slot>
|
|
306
|
-
<p group-question>${i18next.t('figure.label.resize-intent')}</p>
|
|
307
|
-
${canFollow(asset, this.partId) ? this.renderDimensions(asset) : html`<p hint>${i18next.t('figure.text.links-need-a-box')}</p>`}
|
|
308
339
|
</section>
|
|
309
340
|
<section fastening ?spotlit=${this.spotlit} @focusin=${() => (this.working = 'fasten')}>
|
|
310
341
|
<h3>
|
|
@@ -312,12 +343,10 @@ export class FigureLinks extends localize(i18next)(LitElement) {
|
|
|
312
343
|
${groupMenu([{ label: i18next.t('figure.button.detach'), icon: 'link_off', disabled: this.locked || !held, run: () => this.command({ kind: 'detach', part: this.partId }) }])}
|
|
313
344
|
</h3>${this.help.hint('figure.text.fastening-explained')}
|
|
314
345
|
<slot name="place"></slot>
|
|
315
|
-
${this.renderPositions(asset)}
|
|
316
346
|
${canFasten(asset, this.partId) ? this.renderFastening(asset) : html`<p hint>${i18next.t('figure.text.links-need-a-box')}</p>`}
|
|
317
347
|
</section>
|
|
318
|
-
${rowOf(asset, this.partId) ? html`<slot name="row"></slot>` : this.renderRow(asset)}
|
|
319
348
|
`
|
|
320
|
-
this.candidate = this.
|
|
349
|
+
this.candidate = this.fastenCandidate
|
|
321
350
|
return shown
|
|
322
351
|
}
|
|
323
352
|
|
|
@@ -667,7 +696,7 @@ export class FigureLinks extends localize(i18next)(LitElement) {
|
|
|
667
696
|
${overhang}
|
|
668
697
|
<div fastened-summary>
|
|
669
698
|
<p fasten-sentence>${this.sentenceOf(myFace, f.toPlane ? planeWord : `${f.target}의 ${i18next.t('figure.label.face-' + targetFace)}`, mode)}</p>
|
|
670
|
-
<button
|
|
699
|
+
<button act change-fastening ?disabled=${this.locked} @click=${() => (this.changingFastening = true)}>${i18next.t('figure.button.change-fastening')}</button>
|
|
671
700
|
</div>
|
|
672
701
|
${this.renderDetachWords()}
|
|
673
702
|
`
|
|
@@ -140,6 +140,7 @@ export class FigureParts extends localize(i18next)(LitElement) {
|
|
|
140
140
|
outline: 2px solid var(--md-sys-color-primary);
|
|
141
141
|
outline-offset: 1px;
|
|
142
142
|
}
|
|
143
|
+
/* The cost line as a line, not a card; lit under the hand like the rest of the list. */
|
|
143
144
|
button[budget] {
|
|
144
145
|
display: flex;
|
|
145
146
|
align-items: flex-start;
|
|
@@ -153,8 +154,8 @@ export class FigureParts extends localize(i18next)(LitElement) {
|
|
|
153
154
|
text-align: left;
|
|
154
155
|
color: var(--md-sys-color-on-surface-variant);
|
|
155
156
|
background: none;
|
|
156
|
-
border: 1px solid
|
|
157
|
-
border-radius:
|
|
157
|
+
border: 1px solid transparent;
|
|
158
|
+
border-radius: 4px;
|
|
158
159
|
cursor: pointer;
|
|
159
160
|
}
|
|
160
161
|
button[budget]:hover {
|
|
@@ -202,17 +203,20 @@ export class FigureParts extends localize(i18next)(LitElement) {
|
|
|
202
203
|
font-size: var(--ui-t-micro, 11px);
|
|
203
204
|
color: var(--md-sys-color-on-surface-variant);
|
|
204
205
|
}
|
|
205
|
-
/*
|
|
206
|
+
/* A field in the side panel's look (side-panel-styles): 26px, a quiet ground, its line only under the hand. */
|
|
206
207
|
div[level] select {
|
|
207
208
|
min-width: 0;
|
|
208
|
-
min-height:
|
|
209
|
+
min-height: 26px;
|
|
209
210
|
padding: 2px 4px;
|
|
210
211
|
font: inherit;
|
|
211
212
|
font-size: var(--ui-t-small, 11.5px);
|
|
212
213
|
color: var(--md-sys-color-on-surface);
|
|
213
|
-
background: var(--md-sys-color-surface-container-
|
|
214
|
-
border: 1px solid
|
|
215
|
-
border-radius:
|
|
214
|
+
background: var(--md-sys-color-surface-container-low);
|
|
215
|
+
border: 1px solid transparent;
|
|
216
|
+
border-radius: 4px;
|
|
217
|
+
}
|
|
218
|
+
div[level] select:hover:not(:disabled) {
|
|
219
|
+
border-color: var(--md-sys-color-outline-variant);
|
|
216
220
|
}
|
|
217
221
|
small[copies] {
|
|
218
222
|
color: var(--md-sys-color-on-surface-variant);
|
|
@@ -229,6 +233,7 @@ export class FigureParts extends localize(i18next)(LitElement) {
|
|
|
229
233
|
grid-template-columns: repeat(3, minmax(0, 1fr));
|
|
230
234
|
gap: 3px;
|
|
231
235
|
}
|
|
236
|
+
/* A tile with no outline: its icon and name, lit under the hand -- ten outlined tiles were the boxiest part of the screen (user 2026-10-17). */
|
|
232
237
|
button[shape] {
|
|
233
238
|
display: flex;
|
|
234
239
|
flex-direction: column;
|
|
@@ -241,37 +246,49 @@ export class FigureParts extends localize(i18next)(LitElement) {
|
|
|
241
246
|
line-height: 1.2;
|
|
242
247
|
text-align: center;
|
|
243
248
|
overflow-wrap: anywhere;
|
|
249
|
+
/* A tile's name on one line, so the nine stand one height; a long name ends in an ellipsis, its title says it all. */
|
|
250
|
+
white-space: nowrap;
|
|
244
251
|
color: var(--md-sys-color-on-surface-variant, var(--md-sys-color-on-surface));
|
|
245
252
|
background: none;
|
|
246
|
-
border: 1px solid
|
|
247
|
-
border-radius:
|
|
253
|
+
border: 1px solid transparent;
|
|
254
|
+
border-radius: 4px;
|
|
248
255
|
cursor: pointer;
|
|
249
256
|
}
|
|
250
257
|
/*
|
|
251
258
|
A file brought in is not a starting shape: its own row under the nine, its words on one line. As a tenth tile its
|
|
252
259
|
two-word name broke onto two lines and stood it taller than the rest (2026-10-16).
|
|
253
260
|
*/
|
|
261
|
+
button[shape] > span {
|
|
262
|
+
max-width: 100%;
|
|
263
|
+
overflow: hidden;
|
|
264
|
+
text-overflow: ellipsis;
|
|
265
|
+
}
|
|
254
266
|
button[shape][import] {
|
|
255
267
|
grid-column: 1 / -1;
|
|
256
268
|
flex-direction: row;
|
|
257
269
|
justify-content: center;
|
|
258
270
|
gap: 6px;
|
|
259
|
-
min-height:
|
|
271
|
+
min-height: 26px;
|
|
260
272
|
padding: 0 8px;
|
|
261
273
|
}
|
|
274
|
+
/* An action in the side panel's look: icon and words in the primary colour, no pill. */
|
|
262
275
|
button[recipe-catalog] {
|
|
263
276
|
display: inline-flex;
|
|
264
277
|
align-items: center;
|
|
265
278
|
gap: 4px;
|
|
266
|
-
padding: 4px
|
|
279
|
+
padding: 4px 6px;
|
|
280
|
+
margin-left: -6px;
|
|
267
281
|
font: inherit;
|
|
268
282
|
font-size: var(--ui-t-small, 11.5px);
|
|
269
|
-
color: var(--md-sys-color-
|
|
283
|
+
color: var(--md-sys-color-primary);
|
|
270
284
|
background: none;
|
|
271
|
-
border: 1px solid
|
|
272
|
-
border-radius:
|
|
285
|
+
border: 1px solid transparent;
|
|
286
|
+
border-radius: 4px;
|
|
273
287
|
cursor: pointer;
|
|
274
288
|
}
|
|
289
|
+
button[recipe-catalog]:hover:not(:disabled) {
|
|
290
|
+
background: var(--md-sys-color-surface-container);
|
|
291
|
+
}
|
|
275
292
|
button[shape]:hover:not([disabled]) {
|
|
276
293
|
color: var(--md-sys-color-on-primary-container);
|
|
277
294
|
background-color: var(--md-sys-color-primary-container);
|
|
@@ -50,10 +50,10 @@ export class FigureProperties extends localize(i18next)(LitElement) {
|
|
|
50
50
|
div[row] > select {
|
|
51
51
|
flex: 1;
|
|
52
52
|
}
|
|
53
|
+
/* Words as wide as themselves (side-panel-styles' action): stretched over the row, their label floated in the middle. */
|
|
53
54
|
div[row] > button[act] {
|
|
54
|
-
flex:
|
|
55
|
+
flex: none;
|
|
55
56
|
width: auto;
|
|
56
|
-
margin-top: 0;
|
|
57
57
|
}
|
|
58
58
|
div[row] > span {
|
|
59
59
|
flex: 1;
|
|
@@ -59,25 +59,48 @@ export class FigureModellerPage extends PageView {
|
|
|
59
59
|
min-width: 0;
|
|
60
60
|
min-height: 0;
|
|
61
61
|
}
|
|
62
|
-
/*
|
|
62
|
+
/*
|
|
63
|
+
The first field of the properties tab, in the side panel's look (side-panel-styles): its label and its field on one
|
|
64
|
+
line, the field a line under its value. It is slotted into the figure panel, so the panel's measures reach it by
|
|
65
|
+
inheritance.
|
|
66
|
+
*/
|
|
63
67
|
label[type-field] {
|
|
64
68
|
display: grid;
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
69
|
+
grid-template-columns: var(--figure-label-width, 72px) minmax(0, 1fr);
|
|
70
|
+
align-items: center;
|
|
71
|
+
gap: 4px 8px;
|
|
72
|
+
margin: 0;
|
|
73
|
+
font-size: var(--ui-t-small, 11.5px);
|
|
68
74
|
color: var(--md-sys-color-on-surface-variant);
|
|
69
75
|
}
|
|
76
|
+
label[type-field] > :not(span) {
|
|
77
|
+
grid-column: 2;
|
|
78
|
+
}
|
|
70
79
|
label[type-field] input,
|
|
71
80
|
label[type-field] code {
|
|
72
81
|
box-sizing: border-box;
|
|
73
|
-
min-height:
|
|
74
|
-
padding:
|
|
82
|
+
min-height: var(--figure-control-height, 26px);
|
|
83
|
+
padding: 2px 2px;
|
|
75
84
|
font-family: var(--ui-mono, ui-monospace, monospace);
|
|
76
|
-
font-size:
|
|
85
|
+
font-size: var(--ui-t-small, 11.5px);
|
|
86
|
+
line-height: calc(var(--figure-control-height, 26px) - 6px);
|
|
77
87
|
color: var(--md-sys-color-on-surface);
|
|
78
|
-
background:
|
|
79
|
-
border:
|
|
80
|
-
border-
|
|
88
|
+
background: transparent;
|
|
89
|
+
border: 0;
|
|
90
|
+
border-bottom: 1px solid var(--md-sys-color-outline-variant, #c4c7c5);
|
|
91
|
+
border-radius: 0;
|
|
92
|
+
}
|
|
93
|
+
/* Fixed once released: its value with no line under it, read not edited. */
|
|
94
|
+
label[type-field] code {
|
|
95
|
+
border-bottom-color: transparent;
|
|
96
|
+
}
|
|
97
|
+
label[type-field] input:hover:not(:focus) {
|
|
98
|
+
border-bottom-color: var(--md-sys-color-on-surface-variant);
|
|
99
|
+
}
|
|
100
|
+
label[type-field] input:focus {
|
|
101
|
+
outline: none;
|
|
102
|
+
border-bottom-color: var(--md-sys-color-primary);
|
|
103
|
+
box-shadow: inset 0 -1px 0 var(--md-sys-color-primary);
|
|
81
104
|
}
|
|
82
105
|
label[type-field] small {
|
|
83
106
|
color: var(--md-sys-color-on-surface-variant);
|
|
@@ -85,7 +108,7 @@ export class FigureModellerPage extends PageView {
|
|
|
85
108
|
p[fit-error] {
|
|
86
109
|
margin: 0;
|
|
87
110
|
padding: 8px 12px;
|
|
88
|
-
font-size:
|
|
111
|
+
font-size: var(--ui-t-small, 11.5px);
|
|
89
112
|
color: var(--md-sys-color-error);
|
|
90
113
|
}
|
|
91
114
|
label[type-field] small[role='alert'] {
|
|
@@ -262,15 +262,13 @@ export const EditorStyles = css `
|
|
|
262
262
|
/* The part's own numbers inside a group the links draw (size, place): one column, the panel's gap. */
|
|
263
263
|
div[group-fields] {
|
|
264
264
|
display: grid;
|
|
265
|
-
gap:
|
|
265
|
+
gap: 6px;
|
|
266
266
|
}
|
|
267
|
-
/*
|
|
268
|
-
section[more] > details > summary
|
|
269
|
-
section[capability] > details > summary {
|
|
267
|
+
/* The folded 「더 보기」: its title is the fold's handle, at the title's size. */
|
|
268
|
+
section[more] > details > summary {
|
|
270
269
|
padding: 0;
|
|
271
270
|
}
|
|
272
|
-
section[more] > details > summary > h3
|
|
273
|
-
section[capability] > details > summary > h3 {
|
|
271
|
+
section[more] > details > summary > h3 {
|
|
274
272
|
margin: 0;
|
|
275
273
|
}
|
|
276
274
|
div[more-body] {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"editor-styles.js","sourceRoot":"","sources":["../../client/modeller/editor-styles.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAE,MAAM,KAAK,CAAA;AAEzB,gHAAgH;AAChH,MAAM,CAAC,MAAM,YAAY,GAAG,GAAG,CAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAmZ9B,CAAA","sourcesContent":["import { css } from 'lit'\n\n/** The modeller editor's own styles: the bar's tools, the panes, the start card, the side's tabs and panels. */\nexport const EditorStyles = css`\n :host {\n position: relative;\n display: flex;\n flex-direction: column;\n min-height: 0;\n height: 100%;\n /* The editor folds by the width it is given, not the window's (UX ruling, 2026-09-24). */\n container-type: inline-size;\n /* The app's one face (its typography theme's --theme-font) at the body size: a bare sans-serif here put a second\n face under everything the editor draws, beside the parts list and the shell in the app's own (2026-10-16). */\n font-family: var(--theme-font, ui-sans-serif, system-ui, sans-serif);\n font-size: var(--ui-t-body, 13px);\n color: var(--md-sys-color-on-surface);\n }\n /* The bar over the work is ox-canvas-bar (ADR-0060 decision 8): the folds at its edges, undo, redo and\n fit in the suite's places. What the editor puts in it - the mode switch, the status, save - is styled here. */\n ox-canvas-bar button[mode] {\n height: 28px;\n border: 1px solid transparent;\n padding: 0 10px;\n border-radius: 999em;\n border-color: transparent;\n background: none;\n }\n ox-canvas-bar button[mode][aria-pressed='true'] {\n border-color: var(--md-sys-color-primary);\n }\n /* The gizmo's tools, drawn as the bar's own icon buttons (undo, redo, fit). */\n ox-canvas-bar .gizmo-tools {\n display: inline-flex;\n gap: 2px;\n padding-left: 4px;\n border-left: 1px solid var(--md-sys-color-outline-variant);\n }\n ox-canvas-bar button[tool] {\n display: inline-grid;\n place-items: center;\n width: 32px;\n height: 32px;\n padding: 0;\n border: none;\n border-radius: var(--md-sys-shape-corner-small, 8px);\n background: transparent;\n color: var(--md-sys-color-on-surface-variant);\n cursor: pointer;\n }\n ox-canvas-bar button[tool]:hover:not(:disabled) {\n background: var(--md-sys-color-surface-container-high);\n color: var(--md-sys-color-on-surface);\n }\n ox-canvas-bar button[tool][aria-pressed='true'] {\n background: var(--md-sys-color-secondary-container);\n color: var(--md-sys-color-on-secondary-container);\n }\n ox-canvas-bar button[tool]:disabled {\n opacity: 0.38;\n cursor: default;\n }\n /*\n Slotted into the bar from here, the tools do not get the bar's own icon size (20px, set inside its shadow): they\n showed at md-icon's 24px, heavier than undo, redo and fit beside them. The same size, and the bar's focus ring.\n */\n ox-canvas-bar button[tool] md-icon {\n --md-icon-size: 20px;\n }\n ox-canvas-bar button[tool]:focus-visible {\n outline: 2px solid var(--md-sys-color-primary);\n outline-offset: 1px;\n }\n figure-preview {\n min-width: 0;\n min-height: 0;\n }\n /* The edit canvas stays standing while the preview is in front (a 3D scene costs a third of a second to make), out of sight. */\n div[middle][hidden] {\n display: none;\n }\n /* The preview, once made, stays standing out of sight too: its 3D scene is not made again each time it is asked for. */\n figure-preview[hidden] {\n display: none;\n }\n ox-canvas-bar .status {\n padding: 0 8px;\n color: var(--md-sys-color-on-surface-variant);\n }\n ox-canvas-bar .status[dirty] {\n color: var(--md-sys-color-primary);\n font-weight: 600;\n }\n ox-canvas-bar button[save] {\n height: 32px;\n padding: 0 14px;\n border: none;\n border-radius: 999em;\n color: var(--md-sys-color-on-primary);\n background: var(--md-sys-color-primary);\n }\n /* The three panes are ox-three-pane's (ADR-0060 decision 8): widths 200 | 1fr | 340, 160 | 300 under\n 860px and one column with the middle first under 560px are the frame's, as are the dividers. */\n ox-three-pane {\n flex: 1;\n min-height: 0;\n }\n figure-parts {\n min-height: 0;\n }\n figure-canvas {\n flex: 1;\n min-width: 0;\n min-height: 0;\n }\n div[middle] {\n position: relative;\n display: flex;\n min-width: 0;\n min-height: 0;\n }\n /* A new figure's first question, over the empty canvas. */\n div[start] {\n position: absolute;\n inset: 50% auto auto 50%;\n z-index: 10;\n color: var(--md-sys-color-on-surface);\n transform: translate(-50%, -50%);\n width: min(440px, calc(100% - 32px));\n box-sizing: border-box;\n padding: 20px;\n border-radius: 12px;\n background: var(--md-sys-color-surface, #fff);\n box-shadow: 0 6px 24px rgba(0, 0, 0, 0.18);\n }\n div[start] button[start-button] {\n width: auto;\n margin: 0;\n font-size: var(--ui-t-body);\n height: 36px;\n padding: 0 16px;\n border: 1px solid var(--md-sys-color-outline);\n border-radius: 999em;\n color: var(--md-sys-color-primary);\n background: var(--md-sys-color-surface, #fff);\n cursor: pointer;\n }\n div[start] button[start-button]:hover:not(:disabled) {\n background: var(--md-sys-color-primary-container);\n }\n div[start] button[start-button][pressed] {\n color: var(--md-sys-color-on-primary);\n background: var(--md-sys-color-primary);\n border-color: var(--md-sys-color-primary);\n }\n div[start] button[start-button]:disabled {\n opacity: 0.5;\n cursor: default;\n }\n div[start] h2 {\n margin: 0 0 12px;\n font-size: var(--ui-t-title);\n }\n div[start-paths] {\n display: grid;\n gap: 14px;\n }\n div[start-paths] h3 {\n margin: 0 0 6px;\n font-size: var(--ui-t-body);\n }\n div[start-shapes] {\n display: flex;\n gap: 8px;\n flex-wrap: wrap;\n }\n div[start] small {\n display: block;\n margin-top: 4px;\n color: var(--md-sys-color-on-surface-variant);\n }\n /* The side: tabs over one panel at a time, each using the whole height. */\n /*\n The side's words at the panel's size (side-panel-styles: titles body, the rest small). The editor's host is at body\n for the bar, and the fields the editor drew itself -- the part's name -- stood a step larger than every other field.\n */\n aside {\n display: flex;\n flex-direction: column;\n min-height: 0;\n font-size: var(--ui-t-small, 11.5px);\n background: var(--md-sys-color-surface-container-lowest);\n }\n div[tabs] {\n display: flex;\n flex: none;\n border-bottom: 1px solid var(--md-sys-color-outline-variant);\n }\n button[tab] {\n flex: 1;\n position: relative;\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n gap: 1px;\n min-width: 0;\n height: 48px;\n padding: 0;\n border: none;\n border-radius: 0;\n border-bottom: 2px solid transparent;\n background: none;\n color: var(--md-sys-color-on-surface-variant);\n }\n button[tab]:hover:not([on]) {\n background: var(--md-sys-color-surface-container);\n }\n button[tab][on] {\n color: var(--md-sys-color-primary);\n border-bottom-color: var(--md-sys-color-primary);\n }\n button[tab] md-icon {\n font-size: 20px;\n width: 20px;\n height: 20px;\n }\n button[tab] span[tab-label] {\n max-width: 100%;\n overflow: hidden;\n font-size: var(--ui-t-micro, 11px);\n line-height: 1.2;\n white-space: nowrap;\n text-overflow: ellipsis;\n }\n span[badge] {\n position: absolute;\n top: 3px;\n right: 2px;\n padding: 0 5px;\n font-size: var(--ui-t-micro, 11px);\n font-weight: 700;\n line-height: 1.5;\n color: var(--md-sys-color-on-primary-container);\n background: var(--md-sys-color-primary-container);\n border-radius: 999em;\n pointer-events: none;\n }\n /* The sections inside carry the margins (side-panel-styles); the panel only scrolls. */\n div[panel] {\n flex: 1;\n min-height: 0;\n overflow: auto;\n padding: 0;\n }\n div[panel][flush] {\n padding: 0;\n }\n /* Hidden, not removed: a panel keeps what it holds (the verdict its last answer) while another tab is open. */\n [off] {\n display: none !important;\n }\n /* The part's own numbers inside a group the links draw (size, place): one column, the panel's gap. */\n div[group-fields] {\n display: grid;\n gap: 8px;\n }\n /* A folded group (capability, 「더 보기」): its title is the fold's handle, at the title's size. */\n section[more] > details > summary,\n section[capability] > details > summary {\n padding: 0;\n }\n section[more] > details > summary > h3,\n section[capability] > details > summary > h3 {\n margin: 0;\n }\n div[more-body] {\n display: grid;\n gap: 16px;\n margin-top: 12px;\n }\n /*\n The view settings and the release history, opened from the bar over the right of the work: neither is about the\n part chosen, so neither takes a tab beside the part's (chief architect 2026-10-16).\n */\n :host {\n position: relative;\n }\n div[bar-overlay-panel] {\n position: absolute;\n top: var(--figure-bar-height, 44px);\n right: 8px;\n z-index: 5;\n display: flex;\n flex-direction: column;\n width: min(360px, calc(100% - 16px));\n max-height: calc(100% - var(--figure-bar-height, 44px) - 16px);\n background: var(--md-sys-color-surface-container-lowest);\n border: 1px solid var(--md-sys-color-outline-variant);\n border-radius: 8px;\n box-shadow: 0 6px 20px rgba(0, 0, 0, 0.16);\n }\n div[overlay-head] {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 8px 8px 8px 12px;\n border-bottom: 1px solid var(--md-sys-color-outline-variant);\n }\n div[overlay-head] h3 {\n margin: 0;\n }\n div[overlay-head] button[quiet] {\n margin-left: 0;\n }\n div[overlay-body] {\n min-height: 0;\n overflow: auto;\n }\n /* Which part the panel speaks of. */\n div[subject] {\n position: sticky;\n top: 0;\n z-index: 1;\n display: grid;\n gap: 4px;\n padding: 10px 12px;\n background: var(--md-sys-color-surface-container-lowest);\n border-bottom: 1px solid var(--md-sys-color-outline-variant);\n }\n /* The panel's three sizes (side-panel-styles): the part's kind at the title's, its two lines at the hint's. */\n div[subject-summary] {\n display: grid;\n gap: 2px;\n }\n div[subject-summary] b {\n font-size: var(--ui-t-body, 13px);\n font-weight: 600;\n }\n div[subject-summary] b span {\n font-weight: 400;\n color: var(--md-sys-color-on-surface-variant);\n }\n div[subject-summary] small {\n color: var(--md-sys-color-on-surface-variant);\n }\n /*\n No rule here draws every button as a box: the side's buttons take the shared panel rules (SidePanelStyles), one\n height with the fields beside them, and only the bar's publish keeps an outline (user 2026-10-16: 「버튼 박스도\n 과하게 사용되어서」 -- a bare 「button」 rule had put a 32px box round every button the editor drew).\n */\n button {\n font: inherit;\n box-sizing: border-box;\n color: inherit;\n min-width: 0;\n cursor: pointer;\n }\n /* What blocks release, beside 「발행」: one red word button, and its list under the bar. */\n ox-canvas-bar button[release-blocked] {\n display: inline-flex;\n align-items: center;\n gap: 4px;\n height: 32px;\n padding: 0 10px;\n border: none;\n border-radius: 6px;\n color: var(--md-sys-color-on-error-container);\n background: var(--md-sys-color-error-container);\n }\n ox-canvas-bar button[release-blocked] md-icon {\n --md-icon-size: 18px;\n }\n div[release-blockers] {\n position: absolute;\n top: 46px;\n right: 8px;\n z-index: 6;\n width: min(340px, calc(100% - 16px));\n padding: 8px 10px 10px;\n box-sizing: border-box;\n background: var(--md-sys-color-surface);\n border: 1px solid var(--md-sys-color-outline-variant);\n border-radius: 8px;\n box-shadow: var(--md-sys-elevation-2, 0 2px 8px #0003);\n }\n ox-canvas-bar button[publish] {\n height: 32px;\n padding: 0 8px;\n border: 1px solid var(--md-sys-color-outline-variant);\n border-radius: 6px;\n background: var(--md-sys-color-surface);\n }\n button:disabled {\n opacity: 0.45;\n cursor: default;\n }\n button[aria-pressed='true'] {\n background: var(--md-sys-color-secondary-container);\n color: var(--md-sys-color-on-secondary-container);\n border-color: var(--md-sys-color-primary);\n }\n .hint {\n color: var(--md-sys-color-on-surface-variant);\n line-height: 1.5;\n }\n`\n"]}
|
|
1
|
+
{"version":3,"file":"editor-styles.js","sourceRoot":"","sources":["../../client/modeller/editor-styles.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAE,MAAM,KAAK,CAAA;AAEzB,gHAAgH;AAChH,MAAM,CAAC,MAAM,YAAY,GAAG,GAAG,CAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAiZ9B,CAAA","sourcesContent":["import { css } from 'lit'\n\n/** The modeller editor's own styles: the bar's tools, the panes, the start card, the side's tabs and panels. */\nexport const EditorStyles = css`\n :host {\n position: relative;\n display: flex;\n flex-direction: column;\n min-height: 0;\n height: 100%;\n /* The editor folds by the width it is given, not the window's (UX ruling, 2026-09-24). */\n container-type: inline-size;\n /* The app's one face (its typography theme's --theme-font) at the body size: a bare sans-serif here put a second\n face under everything the editor draws, beside the parts list and the shell in the app's own (2026-10-16). */\n font-family: var(--theme-font, ui-sans-serif, system-ui, sans-serif);\n font-size: var(--ui-t-body, 13px);\n color: var(--md-sys-color-on-surface);\n }\n /* The bar over the work is ox-canvas-bar (ADR-0060 decision 8): the folds at its edges, undo, redo and\n fit in the suite's places. What the editor puts in it - the mode switch, the status, save - is styled here. */\n ox-canvas-bar button[mode] {\n height: 28px;\n border: 1px solid transparent;\n padding: 0 10px;\n border-radius: 999em;\n border-color: transparent;\n background: none;\n }\n ox-canvas-bar button[mode][aria-pressed='true'] {\n border-color: var(--md-sys-color-primary);\n }\n /* The gizmo's tools, drawn as the bar's own icon buttons (undo, redo, fit). */\n ox-canvas-bar .gizmo-tools {\n display: inline-flex;\n gap: 2px;\n padding-left: 4px;\n border-left: 1px solid var(--md-sys-color-outline-variant);\n }\n ox-canvas-bar button[tool] {\n display: inline-grid;\n place-items: center;\n width: 32px;\n height: 32px;\n padding: 0;\n border: none;\n border-radius: var(--md-sys-shape-corner-small, 8px);\n background: transparent;\n color: var(--md-sys-color-on-surface-variant);\n cursor: pointer;\n }\n ox-canvas-bar button[tool]:hover:not(:disabled) {\n background: var(--md-sys-color-surface-container-high);\n color: var(--md-sys-color-on-surface);\n }\n ox-canvas-bar button[tool][aria-pressed='true'] {\n background: var(--md-sys-color-secondary-container);\n color: var(--md-sys-color-on-secondary-container);\n }\n ox-canvas-bar button[tool]:disabled {\n opacity: 0.38;\n cursor: default;\n }\n /*\n Slotted into the bar from here, the tools do not get the bar's own icon size (20px, set inside its shadow): they\n showed at md-icon's 24px, heavier than undo, redo and fit beside them. The same size, and the bar's focus ring.\n */\n ox-canvas-bar button[tool] md-icon {\n --md-icon-size: 20px;\n }\n ox-canvas-bar button[tool]:focus-visible {\n outline: 2px solid var(--md-sys-color-primary);\n outline-offset: 1px;\n }\n figure-preview {\n min-width: 0;\n min-height: 0;\n }\n /* The edit canvas stays standing while the preview is in front (a 3D scene costs a third of a second to make), out of sight. */\n div[middle][hidden] {\n display: none;\n }\n /* The preview, once made, stays standing out of sight too: its 3D scene is not made again each time it is asked for. */\n figure-preview[hidden] {\n display: none;\n }\n ox-canvas-bar .status {\n padding: 0 8px;\n color: var(--md-sys-color-on-surface-variant);\n }\n ox-canvas-bar .status[dirty] {\n color: var(--md-sys-color-primary);\n font-weight: 600;\n }\n ox-canvas-bar button[save] {\n height: 32px;\n padding: 0 14px;\n border: none;\n border-radius: 999em;\n color: var(--md-sys-color-on-primary);\n background: var(--md-sys-color-primary);\n }\n /* The three panes are ox-three-pane's (ADR-0060 decision 8): widths 200 | 1fr | 340, 160 | 300 under\n 860px and one column with the middle first under 560px are the frame's, as are the dividers. */\n ox-three-pane {\n flex: 1;\n min-height: 0;\n }\n figure-parts {\n min-height: 0;\n }\n figure-canvas {\n flex: 1;\n min-width: 0;\n min-height: 0;\n }\n div[middle] {\n position: relative;\n display: flex;\n min-width: 0;\n min-height: 0;\n }\n /* A new figure's first question, over the empty canvas. */\n div[start] {\n position: absolute;\n inset: 50% auto auto 50%;\n z-index: 10;\n color: var(--md-sys-color-on-surface);\n transform: translate(-50%, -50%);\n width: min(440px, calc(100% - 32px));\n box-sizing: border-box;\n padding: 20px;\n border-radius: 12px;\n background: var(--md-sys-color-surface, #fff);\n box-shadow: 0 6px 24px rgba(0, 0, 0, 0.18);\n }\n div[start] button[start-button] {\n width: auto;\n margin: 0;\n font-size: var(--ui-t-body);\n height: 36px;\n padding: 0 16px;\n border: 1px solid var(--md-sys-color-outline);\n border-radius: 999em;\n color: var(--md-sys-color-primary);\n background: var(--md-sys-color-surface, #fff);\n cursor: pointer;\n }\n div[start] button[start-button]:hover:not(:disabled) {\n background: var(--md-sys-color-primary-container);\n }\n div[start] button[start-button][pressed] {\n color: var(--md-sys-color-on-primary);\n background: var(--md-sys-color-primary);\n border-color: var(--md-sys-color-primary);\n }\n div[start] button[start-button]:disabled {\n opacity: 0.5;\n cursor: default;\n }\n div[start] h2 {\n margin: 0 0 12px;\n font-size: var(--ui-t-title);\n }\n div[start-paths] {\n display: grid;\n gap: 14px;\n }\n div[start-paths] h3 {\n margin: 0 0 6px;\n font-size: var(--ui-t-body);\n }\n div[start-shapes] {\n display: flex;\n gap: 8px;\n flex-wrap: wrap;\n }\n div[start] small {\n display: block;\n margin-top: 4px;\n color: var(--md-sys-color-on-surface-variant);\n }\n /* The side: tabs over one panel at a time, each using the whole height. */\n /*\n The side's words at the panel's size (side-panel-styles: titles body, the rest small). The editor's host is at body\n for the bar, and the fields the editor drew itself -- the part's name -- stood a step larger than every other field.\n */\n aside {\n display: flex;\n flex-direction: column;\n min-height: 0;\n font-size: var(--ui-t-small, 11.5px);\n background: var(--md-sys-color-surface-container-lowest);\n }\n div[tabs] {\n display: flex;\n flex: none;\n border-bottom: 1px solid var(--md-sys-color-outline-variant);\n }\n button[tab] {\n flex: 1;\n position: relative;\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n gap: 1px;\n min-width: 0;\n height: 48px;\n padding: 0;\n border: none;\n border-radius: 0;\n border-bottom: 2px solid transparent;\n background: none;\n color: var(--md-sys-color-on-surface-variant);\n }\n button[tab]:hover:not([on]) {\n background: var(--md-sys-color-surface-container);\n }\n button[tab][on] {\n color: var(--md-sys-color-primary);\n border-bottom-color: var(--md-sys-color-primary);\n }\n button[tab] md-icon {\n font-size: 20px;\n width: 20px;\n height: 20px;\n }\n button[tab] span[tab-label] {\n max-width: 100%;\n overflow: hidden;\n font-size: var(--ui-t-micro, 11px);\n line-height: 1.2;\n white-space: nowrap;\n text-overflow: ellipsis;\n }\n span[badge] {\n position: absolute;\n top: 3px;\n right: 2px;\n padding: 0 5px;\n font-size: var(--ui-t-micro, 11px);\n font-weight: 700;\n line-height: 1.5;\n color: var(--md-sys-color-on-primary-container);\n background: var(--md-sys-color-primary-container);\n border-radius: 999em;\n pointer-events: none;\n }\n /* The sections inside carry the margins (side-panel-styles); the panel only scrolls. */\n div[panel] {\n flex: 1;\n min-height: 0;\n overflow: auto;\n padding: 0;\n }\n div[panel][flush] {\n padding: 0;\n }\n /* Hidden, not removed: a panel keeps what it holds (the verdict its last answer) while another tab is open. */\n [off] {\n display: none !important;\n }\n /* The part's own numbers inside a group the links draw (size, place): one column, the panel's gap. */\n div[group-fields] {\n display: grid;\n gap: 6px;\n }\n /* The folded 「더 보기」: its title is the fold's handle, at the title's size. */\n section[more] > details > summary {\n padding: 0;\n }\n section[more] > details > summary > h3 {\n margin: 0;\n }\n div[more-body] {\n display: grid;\n gap: 16px;\n margin-top: 12px;\n }\n /*\n The view settings and the release history, opened from the bar over the right of the work: neither is about the\n part chosen, so neither takes a tab beside the part's (chief architect 2026-10-16).\n */\n :host {\n position: relative;\n }\n div[bar-overlay-panel] {\n position: absolute;\n top: var(--figure-bar-height, 44px);\n right: 8px;\n z-index: 5;\n display: flex;\n flex-direction: column;\n width: min(360px, calc(100% - 16px));\n max-height: calc(100% - var(--figure-bar-height, 44px) - 16px);\n background: var(--md-sys-color-surface-container-lowest);\n border: 1px solid var(--md-sys-color-outline-variant);\n border-radius: 8px;\n box-shadow: 0 6px 20px rgba(0, 0, 0, 0.16);\n }\n div[overlay-head] {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 8px 8px 8px 12px;\n border-bottom: 1px solid var(--md-sys-color-outline-variant);\n }\n div[overlay-head] h3 {\n margin: 0;\n }\n div[overlay-head] button[quiet] {\n margin-left: 0;\n }\n div[overlay-body] {\n min-height: 0;\n overflow: auto;\n }\n /* Which part the panel speaks of. */\n div[subject] {\n position: sticky;\n top: 0;\n z-index: 1;\n display: grid;\n gap: 4px;\n padding: 10px 12px;\n background: var(--md-sys-color-surface-container-lowest);\n border-bottom: 1px solid var(--md-sys-color-outline-variant);\n }\n /* The panel's three sizes (side-panel-styles): the part's kind at the title's, its two lines at the hint's. */\n div[subject-summary] {\n display: grid;\n gap: 2px;\n }\n div[subject-summary] b {\n font-size: var(--ui-t-body, 13px);\n font-weight: 600;\n }\n div[subject-summary] b span {\n font-weight: 400;\n color: var(--md-sys-color-on-surface-variant);\n }\n div[subject-summary] small {\n color: var(--md-sys-color-on-surface-variant);\n }\n /*\n No rule here draws every button as a box: the side's buttons take the shared panel rules (SidePanelStyles), one\n height with the fields beside them, and only the bar's publish keeps an outline (user 2026-10-16: 「버튼 박스도\n 과하게 사용되어서」 -- a bare 「button」 rule had put a 32px box round every button the editor drew).\n */\n button {\n font: inherit;\n box-sizing: border-box;\n color: inherit;\n min-width: 0;\n cursor: pointer;\n }\n /* What blocks release, beside 「발행」: one red word button, and its list under the bar. */\n ox-canvas-bar button[release-blocked] {\n display: inline-flex;\n align-items: center;\n gap: 4px;\n height: 32px;\n padding: 0 10px;\n border: none;\n border-radius: 6px;\n color: var(--md-sys-color-on-error-container);\n background: var(--md-sys-color-error-container);\n }\n ox-canvas-bar button[release-blocked] md-icon {\n --md-icon-size: 18px;\n }\n div[release-blockers] {\n position: absolute;\n top: 46px;\n right: 8px;\n z-index: 6;\n width: min(340px, calc(100% - 16px));\n padding: 8px 10px 10px;\n box-sizing: border-box;\n background: var(--md-sys-color-surface);\n border: 1px solid var(--md-sys-color-outline-variant);\n border-radius: 8px;\n box-shadow: var(--md-sys-elevation-2, 0 2px 8px #0003);\n }\n ox-canvas-bar button[publish] {\n height: 32px;\n padding: 0 8px;\n border: 1px solid var(--md-sys-color-outline-variant);\n border-radius: 6px;\n background: var(--md-sys-color-surface);\n }\n button:disabled {\n opacity: 0.45;\n cursor: default;\n }\n button[aria-pressed='true'] {\n background: var(--md-sys-color-secondary-container);\n color: var(--md-sys-color-on-secondary-container);\n border-color: var(--md-sys-color-primary);\n }\n .hint {\n color: var(--md-sys-color-on-surface-variant);\n line-height: 1.5;\n }\n`\n"]}
|
|
@@ -61,8 +61,6 @@ export declare class FigureEditor extends LitElement {
|
|
|
61
61
|
private tab;
|
|
62
62
|
/** The view settings or the release history, open over the work from the bar. */
|
|
63
63
|
private overlay?;
|
|
64
|
-
/** The capability group open: the canvas marks the places only while their group is in sight. */
|
|
65
|
-
private capabilityOpen;
|
|
66
64
|
/** 「더 보기」 open, as this person left it last (chief architect 2026-10-16: kept per person). */
|
|
67
65
|
private moreOpen;
|
|
68
66
|
private static storedMoreOpen;
|
|
@@ -203,16 +201,14 @@ export declare class FigureEditor extends LitElement {
|
|
|
203
201
|
/** Size response, fastening and motion for the selected part, as authoring commands. */
|
|
204
202
|
private renderLinks;
|
|
205
203
|
/**
|
|
206
|
-
* A part's groups in one order whatever its state (chief architect 2026-10-16): its size, its place
|
|
207
|
-
*
|
|
208
|
-
*
|
|
204
|
+
* A part's groups in one order whatever its state (chief architect 2026-10-16): its size, its place. The links draw
|
|
205
|
+
* the groups; the part's own numbers go into them by slot. How the part answers a size -- its rules, a position that
|
|
206
|
+
* follows, its row -- is the 「반응형」 tab's. A fastened part's place and turn are its fastening's: the place group
|
|
207
|
+
* says it in one line and the locked cells are not drawn (user 2026-10-16).
|
|
209
208
|
*/
|
|
210
209
|
private renderPartGroups;
|
|
211
|
-
/**
|
|
212
|
-
|
|
213
|
-
* whose marks on the canvas show while it is open. A verdict that finds it empty still says where it is.
|
|
214
|
-
*/
|
|
215
|
-
private renderCapability;
|
|
210
|
+
/** The 「반응형」 tab of a part: the links' response groups, its row's own section put in by slot. */
|
|
211
|
+
private renderResponse;
|
|
216
212
|
/**
|
|
217
213
|
* 「더 보기」: what few parts need, folded by default and left as this person last left it (chief architect
|
|
218
214
|
* 2026-10-16) -- the section, its corners and inside; transparency, glow and segments; the mirrored copy and the
|