@motion-proto/live-tokens 0.6.2 → 0.8.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.
Files changed (232) hide show
  1. package/README.md +14 -13
  2. package/dist-plugin/index.cjs +854 -226
  3. package/dist-plugin/index.d.cts +2 -1
  4. package/dist-plugin/index.d.ts +2 -1
  5. package/dist-plugin/index.js +852 -225
  6. package/package.json +26 -40
  7. package/src/{styles → app}/site.css +1 -1
  8. package/src/{component-editor → editor/component-editor}/BadgeEditor.svelte +8 -82
  9. package/src/{component-editor → editor/component-editor}/CalloutEditor.svelte +4 -4
  10. package/src/{component-editor → editor/component-editor}/CardEditor.svelte +28 -76
  11. package/src/{component-editor → editor/component-editor}/CollapsibleSectionEditor.svelte +37 -30
  12. package/src/{component-editor → editor/component-editor}/CornerBadgeEditor.svelte +31 -93
  13. package/src/{component-editor → editor/component-editor}/DialogEditor.svelte +60 -57
  14. package/src/editor/component-editor/ImageEditor.svelte +30 -0
  15. package/src/{component-editor → editor/component-editor}/InlineEditActionsEditor.svelte +6 -4
  16. package/src/editor/component-editor/MenuSelectEditor.svelte +160 -0
  17. package/src/{component-editor → editor/component-editor}/NotificationEditor.svelte +67 -38
  18. package/src/{component-editor → editor/component-editor}/ProgressBarEditor.svelte +5 -4
  19. package/src/{component-editor → editor/component-editor}/RadioButtonEditor.svelte +3 -3
  20. package/src/editor/component-editor/SectionDividerEditor.svelte +565 -0
  21. package/src/{component-editor → editor/component-editor}/SegmentedControlEditor.svelte +2 -2
  22. package/src/{component-editor → editor/component-editor}/StandardButtonsEditor.svelte +29 -21
  23. package/src/{component-editor → editor/component-editor}/TabBarEditor.svelte +9 -14
  24. package/src/{component-editor → editor/component-editor}/TableEditor.svelte +9 -18
  25. package/src/{component-editor → editor/component-editor}/TooltipEditor.svelte +11 -47
  26. package/src/editor/component-editor/editors.d.ts +10 -0
  27. package/src/{component-editor → editor/component-editor}/registry.ts +28 -18
  28. package/src/{component-editor → editor/component-editor}/scaffolding/AngleDial.svelte +54 -15
  29. package/src/{component-editor → editor/component-editor}/scaffolding/ComponentEditorBase.svelte +3 -51
  30. package/src/{component-editor → editor/component-editor}/scaffolding/ComponentFileManager.svelte +151 -424
  31. package/src/{component-editor → editor/component-editor}/scaffolding/ComponentFileMenu.svelte +18 -170
  32. package/src/{component-editor → editor/component-editor}/scaffolding/ComponentsTab.svelte +2 -2
  33. package/src/{component-editor → editor/component-editor}/scaffolding/CopyFromMenu.svelte +44 -4
  34. package/src/{component-editor → editor/component-editor}/scaffolding/FieldsetWrapper.svelte +1 -1
  35. package/src/{component-editor → editor/component-editor}/scaffolding/LinkageChart.svelte +6 -6
  36. package/src/{component-editor → editor/component-editor}/scaffolding/LinkedBlock.svelte +6 -12
  37. package/src/editor/component-editor/scaffolding/NonStylableConfig.svelte +38 -0
  38. package/src/editor/component-editor/scaffolding/RadialShapePad.svelte +483 -0
  39. package/src/{component-editor → editor/component-editor}/scaffolding/SaveAsDialog.svelte +66 -12
  40. package/src/editor/component-editor/scaffolding/ShadowBackdrop.svelte +85 -0
  41. package/src/editor/component-editor/scaffolding/ShadowBackdropControls.svelte +132 -0
  42. package/src/editor/component-editor/scaffolding/StateBlock.svelte +345 -0
  43. package/src/{component-editor → editor/component-editor}/scaffolding/TokenLayout.svelte +17 -12
  44. package/src/{component-editor → editor/component-editor}/scaffolding/TypeEditor.svelte +13 -1
  45. package/src/editor/component-editor/scaffolding/VariantGroup.svelte +858 -0
  46. package/src/{component-editor → editor/component-editor}/scaffolding/buildTypeGroupTokens.ts +1 -0
  47. package/src/{component-editor → editor/component-editor}/scaffolding/editorContext.ts +19 -9
  48. package/src/{component-editor → editor/component-editor}/scaffolding/linkedBlock.ts +2 -2
  49. package/src/{component-editor → editor/component-editor}/scaffolding/types.ts +25 -0
  50. package/src/{lib → editor/core/components}/componentConfigKeys.ts +8 -0
  51. package/src/{lib → editor/core/components}/componentConfigService.ts +3 -3
  52. package/src/{lib → editor/core/components}/componentPersist.ts +11 -9
  53. package/src/editor/core/flashStatus.ts +30 -0
  54. package/src/{lib → editor/core/fonts}/fontLoader.ts +2 -2
  55. package/src/{lib → editor/core/fonts}/fontMigration.ts +4 -4
  56. package/src/{lib → editor/core/fonts}/fontParse.ts +1 -1
  57. package/src/editor/core/manifests/manifestService.ts +171 -0
  58. package/src/editor/core/palettes/familySwap.ts +99 -0
  59. package/src/{lib → editor/core/palettes}/paletteDerivation.ts +71 -2
  60. package/src/{lib → editor/core/palettes}/tokenRegistry.ts +9 -6
  61. package/src/editor/core/productionPulse.ts +37 -0
  62. package/src/{lib → editor/core/routing}/router.ts +1 -1
  63. package/src/{lib/files/versionedFileResource.ts → editor/core/storage/files/versionedFileResourceClient.ts} +8 -1
  64. package/src/{lib → editor/core/store}/editorCore.ts +24 -8
  65. package/src/{lib → editor/core/store}/editorPersistence.ts +3 -3
  66. package/src/{lib → editor/core/store}/editorRenderer.ts +2 -2
  67. package/src/{lib → editor/core/store}/editorStore.ts +222 -28
  68. package/src/{lib → editor/core/store}/editorTypes.ts +56 -13
  69. package/src/editor/core/store/gradientSource.ts +192 -0
  70. package/src/editor/core/themes/migrations/2026-05-19-collapsiblesection-drop-frame-surface.ts +28 -0
  71. package/src/editor/core/themes/migrations/2026-05-19-sectiondivider-rich-gradient.ts +35 -0
  72. package/src/editor/core/themes/migrations/2026-05-20-sectiondivider-slim-variants.ts +82 -0
  73. package/src/editor/core/themes/migrations/2026-05-21-sectiondivider-spacing-to-padding.ts +24 -0
  74. package/src/editor/core/themes/migrations/2026-05-22-sectiondivider-intrinsics-to-css.ts +81 -0
  75. package/src/{lib → editor/core/themes}/migrations/index.ts +10 -0
  76. package/src/{lib → editor/core/themes}/slices/columns.ts +2 -2
  77. package/src/{lib → editor/core/themes}/slices/components.ts +20 -6
  78. package/src/{lib → editor/core/themes}/slices/fonts.ts +1 -1
  79. package/src/{lib → editor/core/themes}/slices/gradients.ts +89 -14
  80. package/src/{lib → editor/core/themes}/slices/overlays.ts +1 -1
  81. package/src/{lib → editor/core/themes}/slices/palettes.ts +1 -1
  82. package/src/{lib → editor/core/themes}/slices/shadows.ts +3 -3
  83. package/src/{lib → editor/core/themes}/themeInit.ts +8 -8
  84. package/src/{lib → editor/core/themes}/themeService.ts +6 -6
  85. package/src/{lib → editor/core/themes}/themeTypes.ts +67 -8
  86. package/src/editor/index.ts +69 -0
  87. package/src/{lib → editor/overlay}/ColumnsOverlay.svelte +0 -1
  88. package/src/{lib → editor/overlay}/LiveEditorOverlay.svelte +80 -129
  89. package/src/{lib → editor/overlay}/columnsOverlay.ts +2 -2
  90. package/src/{pages → editor/pages}/ComponentEditorPage.svelte +12 -12
  91. package/src/{pages → editor/pages}/Editor.svelte +4 -4
  92. package/src/{pages → editor/pages}/EditorShell.svelte +18 -36
  93. package/src/{styles → editor/styles}/ui-editor.css +43 -22
  94. package/src/{styles → editor/styles}/ui-form-controls.css +23 -24
  95. package/src/{ui → editor/ui}/BezierCurveEditor.svelte +119 -68
  96. package/src/{ui → editor/ui}/ColorEditPanel.svelte +13 -13
  97. package/src/{ui → editor/ui}/EditorViewSwitcher.svelte +7 -6
  98. package/src/editor/ui/FileLoadList.svelte +367 -0
  99. package/src/editor/ui/FilePill.svelte +80 -0
  100. package/src/editor/ui/FontStackEditor.svelte +499 -0
  101. package/src/editor/ui/GradientEditor.svelte +690 -0
  102. package/src/{ui → editor/ui}/GradientStopPicker.svelte +12 -4
  103. package/src/editor/ui/ManifestFileManager.svelte +438 -0
  104. package/src/{ui → editor/ui}/PaletteEditor.svelte +180 -673
  105. package/src/editor/ui/ProjectFontsSection.svelte +638 -0
  106. package/src/{ui → editor/ui}/SurfacesTab.svelte +3 -3
  107. package/src/{ui → editor/ui}/TextTab.svelte +3 -3
  108. package/src/editor/ui/ThemeFileManager.svelte +783 -0
  109. package/src/{ui → editor/ui}/UICopyPopover.svelte +4 -4
  110. package/src/{ui → editor/ui}/UIFontFamilySelector.svelte +6 -7
  111. package/src/{ui → editor/ui}/UIFontSizeSelector.svelte +4 -1
  112. package/src/editor/ui/UIInfoPopover.svelte +243 -0
  113. package/src/editor/ui/UILetterSpacingSelector.svelte +65 -0
  114. package/src/{ui → editor/ui}/UILineHeightSelector.svelte +5 -5
  115. package/src/{ui → editor/ui}/UILinkToggle.svelte +2 -2
  116. package/src/{ui → editor/ui}/UIPaddingSelector.svelte +6 -6
  117. package/src/{ui → editor/ui}/UIPaletteSelector.svelte +57 -30
  118. package/src/editor/ui/UIPillButton.svelte +168 -0
  119. package/src/{ui → editor/ui}/UIRadio.svelte +2 -2
  120. package/src/{ui → editor/ui}/UIRelinkConfirmPopover.svelte +4 -4
  121. package/src/editor/ui/UISegmentedControl.svelte +114 -0
  122. package/src/editor/ui/UISquareButton.svelte +172 -0
  123. package/src/{ui → editor/ui}/UITokenSelector.svelte +14 -11
  124. package/src/{ui → editor/ui}/UIVariantSelector.svelte +1 -1
  125. package/src/{ui → editor/ui}/VariablesTab.svelte +46 -17
  126. package/src/{ui → editor/ui}/palette/GradientStopEditor.svelte +13 -13
  127. package/src/{ui → editor/ui}/palette/OverridesPanel.svelte +24 -47
  128. package/src/{ui → editor/ui}/palette/PaletteBase.svelte +11 -8
  129. package/src/{ui → editor/ui}/palette/paletteEditorState.ts +1 -1
  130. package/src/editor/ui/palette/paletteMath.ts +275 -0
  131. package/src/{ui → editor/ui}/sections/ColumnsSection.svelte +137 -18
  132. package/src/{ui → editor/ui}/sections/GradientsSection.svelte +8 -8
  133. package/src/{ui → editor/ui}/sections/OverlaysSection.svelte +18 -18
  134. package/src/{ui → editor/ui}/sections/ShadowsSection.svelte +23 -23
  135. package/src/{ui → editor/ui}/sections/TokenScaleTable.svelte +3 -3
  136. package/src/{components → system/components}/Badge.svelte +0 -36
  137. package/src/{components → system/components}/Button.svelte +2 -2
  138. package/src/{components → system/components}/Card.svelte +34 -60
  139. package/src/{components → system/components}/CollapsibleSection.svelte +25 -2
  140. package/src/{components → system/components}/CornerBadge.svelte +8 -24
  141. package/src/{components → system/components}/Dialog.svelte +1 -1
  142. package/src/system/components/FloatingTokenTags.css +275 -0
  143. package/src/system/components/FloatingTokenTags.svelte +543 -0
  144. package/src/{components → system/components}/InlineEditActions.svelte +6 -4
  145. package/src/system/components/MenuSelect.svelte +229 -0
  146. package/src/{components → system/components}/Notification.svelte +8 -1
  147. package/src/{components → system/components}/ProgressBar.svelte +29 -11
  148. package/src/system/components/SectionDivider.svelte +560 -0
  149. package/src/{components → system/components}/SegmentedControl.svelte +49 -43
  150. package/src/{components → system/components}/TabBar.svelte +81 -65
  151. package/src/{components → system/components}/Table.svelte +17 -3
  152. package/src/{components → system/components}/Tooltip.svelte +6 -4
  153. package/src/system/styles/CONVENTIONS.md +178 -0
  154. package/src/system/styles/fonts.css +20 -0
  155. package/src/system/styles/tokens.css +601 -0
  156. package/src/system/styles/tokens.generated.css +544 -0
  157. package/src/component-editor/ImageEditor.svelte +0 -74
  158. package/src/component-editor/SectionDividerEditor.svelte +0 -265
  159. package/src/component-editor/scaffolding/DividerEditor.svelte +0 -94
  160. package/src/component-editor/scaffolding/GradientCard.svelte +0 -296
  161. package/src/component-editor/scaffolding/NonStylableConfig.svelte +0 -62
  162. package/src/component-editor/scaffolding/ShadowBackdrop.svelte +0 -37
  163. package/src/component-editor/scaffolding/ShadowBackdropControls.svelte +0 -61
  164. package/src/component-editor/scaffolding/StateBlock.svelte +0 -132
  165. package/src/component-editor/scaffolding/VariantGroup.svelte +0 -310
  166. package/src/components/SectionDivider.svelte +0 -483
  167. package/src/data/google-fonts.json +0 -75
  168. package/src/lib/index.ts +0 -68
  169. package/src/lib/presetService.ts +0 -214
  170. package/src/lib/productionPulse.ts +0 -32
  171. package/src/styles/fonts.css +0 -30
  172. package/src/styles/tokens.css +0 -1324
  173. package/src/ui/FontStackEditor.svelte +0 -361
  174. package/src/ui/GradientEditor.svelte +0 -470
  175. package/src/ui/PresetFileManager.svelte +0 -1116
  176. package/src/ui/ProjectFontsSection.svelte +0 -645
  177. package/src/ui/ThemeFileManager.svelte +0 -1020
  178. package/src/ui/UnsavedComponentsDialog.svelte +0 -315
  179. /package/src/{component-editor → editor/component-editor}/index.ts +0 -0
  180. /package/src/{component-editor → editor/component-editor}/scaffolding/DemoHeader.svelte +0 -0
  181. /package/src/{component-editor → editor/component-editor}/scaffolding/componentSectionType.ts +0 -0
  182. /package/src/{component-editor → editor/component-editor}/scaffolding/componentSources.ts +0 -0
  183. /package/src/{component-editor → editor/component-editor}/scaffolding/defaultSections.ts +0 -0
  184. /package/src/{component-editor → editor/component-editor}/scaffolding/siblings.ts +0 -0
  185. /package/src/{lib → editor/core}/cssVarSync.ts +0 -0
  186. /package/src/{lib → editor/core/palettes}/oklch.ts +0 -0
  187. /package/src/{lib → editor/core/routing}/navLinkTypes.ts +0 -0
  188. /package/src/{lib → editor/core/routing}/parentRouteStore.ts +0 -0
  189. /package/src/{lib → editor/core/storage}/storage.ts +0 -0
  190. /package/src/{lib → editor/core/store}/editorConfig.ts +0 -0
  191. /package/src/{lib → editor/core/store}/editorConfigStore.ts +0 -0
  192. /package/src/{lib → editor/core/store}/editorKeybindings.ts +0 -0
  193. /package/src/{lib → editor/core/store}/editorViewStore.ts +0 -0
  194. /package/src/{lib → editor/core/themes}/migrations/2026-04-24-component-prefix-and-suffix-renames.ts +0 -0
  195. /package/src/{lib → editor/core/themes}/migrations/2026-04-24-legacy-keys-and-bg-to-canvas.ts +0 -0
  196. /package/src/{lib → editor/core/themes}/migrations/2026-04-27-segmentedcontrol-disabled-flatten.ts +0 -0
  197. /package/src/{lib → editor/core/themes}/migrations/2026-05-08-collapsiblesection-frame-and-cleanup.ts +0 -0
  198. /package/src/{lib → editor/core/themes}/migrations/2026-05-08-collapsiblesection-variant-namespace.ts +0 -0
  199. /package/src/{lib → editor/core/themes}/migrations/2026-05-10-sectiondivider-gradient-stops.ts +0 -0
  200. /package/src/{lib → editor/core/themes}/migrations/2026-05-13-primary-to-brand.ts +0 -0
  201. /package/src/{lib → editor/core/themes}/parsers/globalRootBlock.ts +0 -0
  202. /package/src/{lib → editor/core/themes}/slices/domainVars.ts +0 -0
  203. /package/src/{lib → editor/overlay}/overlayState.ts +0 -0
  204. /package/src/{pages → editor/pages}/ComponentEditorPage.svelte.d.ts +0 -0
  205. /package/src/{pages → editor/pages}/Editor.svelte.d.ts +0 -0
  206. /package/src/{ui → editor/ui}/Toggle.svelte +0 -0
  207. /package/src/{ui → editor/ui}/UIDialog.svelte +0 -0
  208. /package/src/{ui → editor/ui}/UIFontWeightSelector.svelte +0 -0
  209. /package/src/{ui → editor/ui}/UIOptionItem.svelte +0 -0
  210. /package/src/{ui → editor/ui}/UIOptionList.svelte +0 -0
  211. /package/src/{ui → editor/ui}/UIRadioGroup.svelte +0 -0
  212. /package/src/{lib → editor/ui}/copyPopover.ts +0 -0
  213. /package/src/{ui → editor/ui}/curveEngine.ts +0 -0
  214. /package/src/{ui → editor/ui}/index.ts +0 -0
  215. /package/src/{ui → editor/ui}/keepInViewport.ts +0 -0
  216. /package/src/{ui → editor/ui}/palette/ScaleCurveEditor.svelte +0 -0
  217. /package/src/{lib → editor/ui}/scrollSection.ts +0 -0
  218. /package/src/{ui → editor/ui}/sections/tokenScales.ts +0 -0
  219. /package/src/{ui → editor/ui}/variantScales.ts +0 -0
  220. /package/src/{assets → system/assets}/newspaper.webp +0 -0
  221. /package/src/{assets → system/assets}/offering.webp +0 -0
  222. /package/src/{components → system/components}/Callout.svelte +0 -0
  223. /package/src/{components → system/components}/Image.svelte +0 -0
  224. /package/src/{components → system/components}/RadioButton.svelte +0 -0
  225. /package/src/{components → system/components}/types.ts +0 -0
  226. /package/src/{styles → system/styles}/_padding.scss +0 -0
  227. /package/src/{styles → system/styles}/fonts/Fraunces/Fraunces-italic-latin-ext.woff2 +0 -0
  228. /package/src/{styles → system/styles}/fonts/Fraunces/Fraunces-italic-latin.woff2 +0 -0
  229. /package/src/{styles → system/styles}/fonts/Fraunces/Fraunces-roman-latin-ext.woff2 +0 -0
  230. /package/src/{styles → system/styles}/fonts/Fraunces/Fraunces-roman-latin.woff2 +0 -0
  231. /package/src/{styles → system/styles}/fonts/Manrope/Manrope-latin-ext.woff2 +0 -0
  232. /package/src/{styles → system/styles}/fonts/Manrope/Manrope-latin.woff2 +0 -0
@@ -11,7 +11,7 @@
11
11
  anchor?: CornerAnchor;
12
12
  size?: 'default' | 'small';
13
13
  icon?: string | undefined;
14
- /** Custom icon content. Falls back to `icon` prop's font-icon class. Renamed from `slot="icon"` in 0.5.0. */
14
+ /** Custom icon content; falls back to `icon` prop's font-icon class. */
15
15
  iconSlot?: Snippet;
16
16
  children?: Snippet;
17
17
  }
@@ -37,23 +37,10 @@
37
37
 
38
38
  $variants: primary, accent, neutral, alternate, canvas, special, success, warning, danger, info;
39
39
 
40
- // Per-variant token block kept flat (not collapsed via SCSS @each) so the
41
- // Layer-2 token-discovery parser (`extractGlobalRootBody` in
42
- // src/lib/parsers/globalRootBlock.ts) can read the .svelte source verbatim;
43
- // @each interpolation would make the parser see zero tokens here, even though
44
- // the rendered DOM would be identical. Same pattern as Badge.svelte / Notification.svelte.
45
- //
46
- // Role-based radii: each variable follows the badge's geometry regardless of anchor.
47
- // - outer: the corner flush with the parent's anchored corner
48
- // - inner: the diagonally opposite corner (deepest into the parent)
49
- // - h-axis: the on-axis corner along the horizontal edge shared with `outer`
50
- // - v-axis: the on-axis corner along the vertical edge shared with `outer`
51
- //
52
- // Padding + font props are corner-badge-specific (not inherited from the
53
- // sibling Badge variant), so corner-badge instances can carry their own
54
- // typography and sizing without dragging the inline Badge along. They default
55
- // to the same underlying global tokens Badge uses, so an unconfigured corner
56
- // badge still matches its inline badge counterpart visually.
40
+ // Flat per-variant blocks (no @each) so extractGlobalRootBody can parse them verbatim.
41
+ // Role-based radii follow badge geometry regardless of anchor:
42
+ // outer = flush corner, inner = diagonal, h-axis/v-axis = edges shared with outer.
43
+ // Padding + font are corner-badge-specific; defaults match Badge so unconfigured looks identical.
57
44
  :global(:root) {
58
45
  /* Primary */
59
46
  --corner-badge-primary-margin: var(--space-0);
@@ -182,11 +169,8 @@
182
169
  pointer-events: none;
183
170
  }
184
171
 
185
- // Per-variant: pull the variant's public tokens into private vars so the
186
- // anchor-based mappings below can read them without 4 × 10 explicit rules.
187
- // Padding + font props are forwarded directly onto the inner Badge so the
188
- // corner-badge tokens fully replace Badge's per-variant declarations
189
- // (otherwise Badge's own `.badge-#{$v}` rule wins by source order).
172
+ // Pull public tokens into private vars so anchor mappings below stay generic (avoids 4×10 rules).
173
+ // Padding + font forwarded onto inner Badge to override Badge's own `.badge-#{$v}` rule.
190
174
  @each $v in $variants {
191
175
  .corner-badge-#{$v} {
192
176
  --_margin: var(--corner-badge-#{$v}-margin);
@@ -210,7 +194,7 @@
210
194
  .corner-badge-top-right { top: var(--_margin); right: var(--_margin); }
211
195
  .corner-badge-top-left { top: var(--_margin); left: var(--_margin); }
212
196
 
213
- /* Map logical corner roles physical corners per anchor. */
197
+ /* Logical roles to physical corners, per anchor. */
214
198
  .corner-badge-bottom-right :global(.badge) {
215
199
  border-top-left-radius: var(--_inner-radius);
216
200
  border-top-right-radius: var(--_v-axis-radius);
@@ -2,7 +2,7 @@
2
2
  import { createEventDispatcher, tick } from 'svelte';
3
3
  import type { Snippet } from 'svelte';
4
4
  import Button from './Button.svelte';
5
- import { editorState } from '../lib/editorStore';
5
+ import { editorState } from '../../editor/core/store/editorStore';
6
6
  import type { ButtonVariant, DialogButtonSpec } from './types';
7
7
 
8
8
  const BUTTON_VARIANTS: readonly ButtonVariant[] = ['primary', 'secondary', 'outline', 'success', 'danger', 'warning'];
@@ -0,0 +1,275 @@
1
+ /*
2
+ * Decoupled from the design system: pills, knots, strings, balls, and
3
+ * animations are hardcoded so token edits don't repaint our chrome. The
4
+ * two exceptions are intentional and ARE the demo: the central box's
5
+ * surface/radius/border (set inline) and the dropdown (rendered through
6
+ * <MenuSelect>). File is global; keep selectors `ftt-` prefixed.
7
+ */
8
+
9
+ .ftt-stage {
10
+ position: relative;
11
+ width: 100%;
12
+ height: 100%;
13
+ /* No overflow clipping: the bottom tag's dropdown must extend past the
14
+ stage edge. */
15
+ }
16
+
17
+ /* --- Central box ---------------------------------------------------------- */
18
+ .ftt-box {
19
+ position: absolute;
20
+ left: 50%;
21
+ top: 50%;
22
+ translate: -50% -50%;
23
+ box-sizing: border-box;
24
+ padding: 0.75rem 1.5rem;
25
+ display: inline-flex;
26
+ width: 12rem;
27
+ align-items: center;
28
+ justify-content: center;
29
+ /* Defaults; overridden inline from the active token bindings. */
30
+ background: color-mix(in srgb, #264542 50%, transparent);
31
+ border-style: solid;
32
+ border-color: #52726e;
33
+ border-width: 2px;
34
+ border-radius: 0.25rem;
35
+ box-shadow: 3px 3px 6px 0px hsla(237, 18%, 3%, 0.9);
36
+ transition:
37
+ background 300ms ease,
38
+ border-color 300ms ease,
39
+ border-width 300ms ease,
40
+ border-radius 300ms ease;
41
+ z-index: 1;
42
+ }
43
+
44
+ .ftt-box-label {
45
+ font-family: Manrope, system-ui, -apple-system, sans-serif;
46
+ font-size: 1.25rem;
47
+ font-weight: 700;
48
+ color: rgba(255, 255, 255, 0.95);
49
+ white-space: nowrap;
50
+ user-select: none;
51
+ pointer-events: none;
52
+ text-shadow: 0 1px 2px rgba(0, 0, 0, 0.45);
53
+ }
54
+
55
+ .ftt-box.ftt-bloop {
56
+ animation: ftt-bloop 480ms ease-out;
57
+ }
58
+
59
+ @keyframes ftt-bloop {
60
+ 0% { scale: 1; filter: brightness(1); }
61
+ 30% { scale: 1.08; filter: brightness(1.8) saturate(1.4); }
62
+ 100% { scale: 1; filter: brightness(1); }
63
+ }
64
+
65
+ /* --- Kite strings --------------------------------------------------------- */
66
+ .ftt-strings {
67
+ position: absolute;
68
+ inset: 0;
69
+ width: 100%;
70
+ height: 100%;
71
+ pointer-events: none;
72
+ z-index: 2;
73
+ }
74
+
75
+ .ftt-string {
76
+ stroke: #d4ccc6;
77
+ stroke-width: 2;
78
+ stroke-linecap: round;
79
+ vector-effect: non-scaling-stroke;
80
+ opacity: 0.5;
81
+ transition: opacity 150ms ease, stroke 150ms ease;
82
+ }
83
+
84
+ .ftt-string.ftt-live {
85
+ stroke: #ff8eeb;
86
+ opacity: 1;
87
+ }
88
+
89
+ /* --- Anchor knots --------------------------------------------------------- */
90
+ .ftt-knot {
91
+ position: absolute;
92
+ width: 0.625rem;
93
+ height: 0.625rem;
94
+ translate: -50% -50%;
95
+ border-radius: 9999px;
96
+ background: #c4bcb6;
97
+ border: 1px solid #f0eae4;
98
+ pointer-events: none;
99
+ z-index: 3;
100
+ }
101
+
102
+ /* --- Energy ball ---------------------------------------------------------- */
103
+ /* Colour must match `.ftt-string.ftt-live` so the beam reads as a continuous
104
+ trail, not a colour-shifting projectile. */
105
+ .ftt-energy-ball {
106
+ position: absolute;
107
+ width: 0.875rem;
108
+ height: 0.875rem;
109
+ translate: -50% -50%;
110
+ border-radius: 9999px;
111
+ background: #ff8eeb;
112
+ box-shadow:
113
+ 0 0 8px 2px #ff8eeb,
114
+ 0 0 18px 4px #ff8eeb;
115
+ pointer-events: none;
116
+ opacity: 0;
117
+ z-index: 6;
118
+ }
119
+
120
+ /* --- Floating tag wrapper ------------------------------------------------- */
121
+ .ftt-float {
122
+ position: absolute;
123
+ translate: -50% -50%;
124
+ rotate: var(--ftt-rot, 0deg);
125
+ animation: ftt-bob var(--ftt-bob-duration, 7s) ease-in-out infinite;
126
+ z-index: 4;
127
+ pointer-events: none;
128
+ display: flex;
129
+ flex-direction: column;
130
+ align-items: center;
131
+ gap: 0.25rem;
132
+ width: 14rem;
133
+ }
134
+
135
+ /* Lift open tag so its dropdown paints over sibling tags. */
136
+ .ftt-float.ftt-open {
137
+ z-index: 20;
138
+ }
139
+
140
+ /* Bottom-placement chips mirror the top arc: chip first, eyebrow on the
141
+ outer (lower) side. Dropdown opens upward toward the box so the menu
142
+ doesn't fall off the stage. */
143
+ .ftt-float[data-placement="bottom"] {
144
+ flex-direction: column-reverse;
145
+ }
146
+
147
+ /* Pivot the tilt around the chip's right semicircular cap. The chip is
148
+ ~1.84rem tall so the cap center sits ~0.9rem from the chip's right edge
149
+ and ~0.9rem above its bottom — which (since the chip is the widest, last
150
+ in-flow element of the wrapper) coincides with `calc(100% - 0.9rem)` on
151
+ both axes of the wrapper. */
152
+ .ftt-float[data-pivot="right-cap"] {
153
+ transform-origin: calc(100% - 0.9rem) calc(100% - 0.9rem);
154
+ }
155
+
156
+ @keyframes ftt-bob {
157
+ 0%, 100% { translate: -50% -50%; }
158
+ 50% { translate: -50% calc(-50% + var(--ftt-bob-distance, -8px)); }
159
+ }
160
+
161
+ /* --- Property label paired with each tag ---------------------------------- */
162
+ /* Sits on the outer side of the chip: above for top-placement chips, below
163
+ for bottom-placement chips (see `.ftt-float[data-placement="bottom"]`). */
164
+ .ftt-float-property {
165
+ font-family: Manrope, system-ui, -apple-system, BlinkMacSystemFont, sans-serif;
166
+ font-size: 0.875rem;
167
+ font-weight: 700;
168
+ color: #ff8eeb;
169
+ white-space: nowrap;
170
+ }
171
+
172
+ /* --- Tag pill ------------------------------------------------------------- */
173
+ /* Hardcoded (not the Badge component) so badge-* token edits don't repaint. */
174
+ .ftt-tag {
175
+ display: inline-flex;
176
+ align-items: center;
177
+ gap: 0.25rem;
178
+ padding: 0.375rem 0.75rem;
179
+ background: linear-gradient(
180
+ 135deg,
181
+ #cccdcd 0%,
182
+ #7c7d7d 38%,
183
+ #b1b2b2 62%,
184
+ #626363 100%
185
+ );
186
+ color: rgba(0, 0, 0, 0.88);
187
+ border: 1px solid rgba(255, 255, 255, 0.55);
188
+ border-radius: 9999px;
189
+ font-family: Manrope, system-ui, -apple-system, sans-serif;
190
+ font-size: 0.875rem;
191
+ font-weight: 600;
192
+ line-height: 1.1;
193
+ white-space: nowrap;
194
+ }
195
+
196
+ .ftt-tag-icon {
197
+ display: inline-flex;
198
+ align-items: center;
199
+ font-size: 0.875em;
200
+ }
201
+
202
+ .ftt-tag-label {
203
+ display: inline-block;
204
+ }
205
+
206
+ /* --- Tag trigger (draggable button wrapping the pill) --------------------- */
207
+ .ftt-tag-trigger {
208
+ pointer-events: auto;
209
+ background: transparent;
210
+ border: none;
211
+ padding: 0;
212
+ margin: 0;
213
+ cursor: grab;
214
+ touch-action: none;
215
+ transition: filter 150ms ease, scale 150ms ease;
216
+ }
217
+ .ftt-tag-trigger:hover {
218
+ filter: brightness(1.2);
219
+ scale: 1.04;
220
+ }
221
+ .ftt-float.ftt-dragging .ftt-tag-trigger {
222
+ cursor: grabbing;
223
+ }
224
+ .ftt-float.ftt-dragging {
225
+ animation: none; /* pause bob while dragging */
226
+ z-index: 30;
227
+ }
228
+ .ftt-tag-trigger:focus-visible {
229
+ outline: 2px solid #f31fdb;
230
+ outline-offset: 3px;
231
+ border-radius: 9999px;
232
+ }
233
+
234
+ .ftt-float.ftt-flash .ftt-tag-trigger {
235
+ animation: ftt-tag-flash 500ms ease-out;
236
+ }
237
+
238
+ @keyframes ftt-tag-flash {
239
+ 0% { scale: 1; filter: brightness(1) drop-shadow(0 0 0 transparent); }
240
+ 25% { scale: 1.14; filter: brightness(1.8) drop-shadow(0 0 14px #fff5f0); }
241
+ 100% { scale: 1; filter: brightness(1) drop-shadow(0 0 0 transparent); }
242
+ }
243
+
244
+ /* --- Chip host ------------------------------------------------------------ */
245
+ /* Wraps the chip-trigger and (when open) the dropdown so the dropdown can
246
+ anchor directly to the chip's edges, not the float wrapper's. Without
247
+ this, `top: 100%` lands at the wrapper bottom — which is the eyebrow for
248
+ `data-placement="bottom"` — and the menu drifts off the chip. */
249
+ .ftt-chip-host {
250
+ position: relative;
251
+ display: inline-flex;
252
+ }
253
+
254
+ /* --- Dropdown menu -------------------------------------------------------- */
255
+ /* The wrap handles position/stacking only; the surface lives on
256
+ <MenuSelect> so menuselect-* token edits reshape the in-flight UI. */
257
+ .ftt-dropdown-wrap {
258
+ position: absolute;
259
+ top: calc(100% + 0.25rem);
260
+ left: 50%;
261
+ translate: -50% 0;
262
+ pointer-events: auto;
263
+ z-index: 10;
264
+ }
265
+
266
+ /* --- Reduced motion ------------------------------------------------------- */
267
+ @media (prefers-reduced-motion: reduce) {
268
+ .ftt-float {
269
+ animation: none;
270
+ }
271
+ .ftt-box.ftt-bloop,
272
+ .ftt-float.ftt-flash .ftt-tag-trigger {
273
+ animation: none;
274
+ }
275
+ }