@digilogiclabs/saas-factory-ui 1.30.1 → 1.30.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.mts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +22 -62
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +22 -62
- package/dist/index.mjs.map +1 -1
- package/dist/web/index.d.mts +1 -1
- package/dist/web/index.d.ts +1 -1
- package/dist/web/index.js +22 -62
- package/dist/web/index.js.map +1 -1
- package/dist/web/index.mjs +22 -62
- package/dist/web/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.d.mts
CHANGED
|
@@ -5293,7 +5293,7 @@ declare function FlowTree({ data, title, eyebrow, tagline, renderIcon: renderIco
|
|
|
5293
5293
|
* delta: it keeps connector strokes crisp under the pan/zoom transform's
|
|
5294
5294
|
* `scale()` (otherwise sub-1 fit-zoom renders them sub-pixel and invisible).
|
|
5295
5295
|
*/
|
|
5296
|
-
declare const FLOW_TREE_CSS = "\n@import url(\"https://fonts.googleapis.com/css2?family=Instrument+Serif:ital@0;1&family=Inter:wght@400;500;600&family=JetBrains+Mono:wght@400;500&display=swap\");\n\n.ft-shell {\n --ft-bg: oklch(0.165 0.008 80);\n --ft-panel: oklch(0.21 0.008 80);\n --ft-panel-2: oklch(0.25 0.01 80);\n --ft-fg: oklch(0.96 0.005 85);\n --ft-muted-fg: oklch(0.68 0.008 80);\n --ft-dim-fg: oklch(0.5 0.008 80);\n --ft-line: oklch(0.28 0.008 80);\n --ft-line-strong: oklch(0.4 0.008 80);\n --ft-grid-strong: oklch(0.24 0.008 80);\n --ft-tier-orange: #f16c25;\n --ft-tier-teal: #5fb7b8;\n --ft-tier-blue: oklch(0.72 0.12 240);\n --ft-tier-amber: oklch(0.8 0.14 75);\n --ft-tier-green: oklch(0.74 0.14 155);\n --ft-accent: var(--ft-tier-orange);\n --ft-serif: \"Instrument Serif\", Georgia, serif;\n --ft-sans: \"Inter\", system-ui, sans-serif;\n --ft-mono: \"JetBrains Mono\", ui-monospace, Menlo, monospace;\n\n /* Defensive shell sizing \u2014 fills flex parents (flex: 1) and block\n parents with definite dimensions (width/height: 100%). */\n flex: 1 1 auto;\n width: 100%;\n height: 100%;\n min-height: 420px;\n display: flex;\n flex-direction: column;\n background: var(--ft-bg);\n border: 1px solid var(--ft-line);\n border-radius: 2px;\n overflow: hidden;\n color: var(--ft-fg);\n font-family: var(--ft-sans);\n font-size: 14px;\n line-height: 1.5;\n -webkit-font-smoothing: antialiased;\n box-shadow: 0 30px 60px -30px oklch(0 0 0 / 0.5);\n}\n.ft-shell * { box-sizing: border-box; }\n.ft-shell .ft-mono {\n font-family: var(--ft-mono);\n font-size: 11px;\n letter-spacing: 0.02em;\n}\n\n.ft-header {\n padding: 22px 28px 20px;\n border-bottom: 1px solid var(--ft-line);\n background: linear-gradient(180deg, oklch(0.21 0.01 60) 0%, oklch(0.19 0.008 70) 100%);\n display: flex;\n flex-direction: column;\n gap: 6px;\n}\n.ft-header__eyebrow {\n font-family: var(--ft-mono);\n font-size: 10.5px;\n letter-spacing: 0.22em;\n text-transform: uppercase;\n color: var(--ft-tier-orange);\n}\n.ft-header__title {\n margin: 0;\n font-family: var(--ft-serif);\n font-weight: 400;\n font-size: 44px;\n line-height: 1;\n letter-spacing: -0.015em;\n color: var(--ft-fg);\n}\n.ft-header__tagline {\n margin: 6px 0 0;\n max-width: 76ch;\n color: var(--ft-muted-fg);\n font-size: 13px;\n}\n\n.ft-stage {\n position: relative;\n flex: 1;\n min-height: 0;\n overflow: hidden;\n background:\n radial-gradient(1200px 700px at 15% -10%, oklch(0.22 0.012 60), transparent 60%),\n radial-gradient(900px 600px at 110% 110%, oklch(0.2 0.02 200 / 0.5), transparent 65%);\n}\n\n.ft-svg {\n display: block;\n width: 100%;\n height: 100%;\n background: transparent;\n cursor: grab;\n touch-action: none;\n user-select: none;\n}\n.ft-svg.is-dragging { cursor: grabbing; }\n\n.ft-controls {\n position: absolute;\n top: 14px;\n right: 14px;\n z-index: 5;\n display: flex;\n align-items: center;\n gap: 6px;\n background: oklch(0.2 0.008 80 / 0.94);\n border: 1px solid var(--ft-line-strong);\n padding: 5px 8px;\n backdrop-filter: blur(8px);\n border-radius: 2px;\n}\n.ft-controls button {\n font-family: var(--ft-mono);\n font-size: 12px;\n width: 26px;\n height: 26px;\n background: transparent;\n border: 1px solid var(--ft-line);\n color: var(--ft-fg);\n cursor: pointer;\n padding: 0;\n}\n.ft-controls button:hover { border-color: var(--ft-tier-orange); }\n.ft-controls__reset {\n width: auto !important;\n padding: 0 10px !important;\n font-size: 9.5px !important;\n letter-spacing: 0.1em;\n text-transform: uppercase;\n}\n.ft-controls__hint {\n font-family: var(--ft-mono);\n font-size: 9.5px;\n color: var(--ft-muted-fg);\n letter-spacing: 0.04em;\n padding-left: 8px;\n margin-left: 2px;\n border-left: 1px solid var(--ft-line);\n}\n\n.ft-legend {\n position: absolute;\n left: 18px;\n bottom: 14px;\n z-index: 5;\n display: flex;\n flex-wrap: wrap;\n align-items: center;\n gap: 6px;\n font-family: var(--ft-mono);\n font-size: 10px;\n color: var(--ft-muted-fg);\n background: oklch(0.2 0.008 80 / 0.88);\n border: 1px solid var(--ft-line);\n padding: 6px 10px;\n backdrop-filter: blur(6px);\n max-width: calc(100% - 220px);\n}\n.ft-legend__chip {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n padding: 2px 6px;\n margin: -2px 0;\n background: transparent;\n border: none;\n color: inherit;\n font: inherit;\n letter-spacing: inherit;\n cursor: pointer;\n border-radius: 2px;\n transition: background 120ms, color 120ms;\n}\n.ft-legend__chip:hover {\n background: oklch(0.24 0.01 80);\n color: var(--ft-fg);\n}\n.ft-legend__chip:disabled {\n cursor: default;\n color: var(--ft-fg);\n}\n.ft-legend__chip:disabled:hover { background: transparent; }\n.ft-legend__dot {\n width: 5px;\n height: 5px;\n border-radius: 50%;\n background: var(--ft-tier-orange);\n flex-shrink: 0;\n}\n.ft-legend__sep {\n color: var(--ft-line-strong);\n margin: 0 2px;\n pointer-events: none;\n user-select: none;\n}\n\n/* edges */\n.ft-edge {\n fill: none;\n /* Keep stroke widths crisp under the SVG <g scale(z)> pan/zoom transform.\n Without this, fit-to-viewport (z \u2248 0.6-0.9) renders 1.6px strokes as\n sub-pixel and they visually disappear. */\n vector-effect: non-scaling-stroke;\n transition: stroke 260ms, opacity 260ms;\n}\n.ft-edge--off { stroke: var(--ft-line); stroke-width: 1; opacity: 0.55; }\n.ft-edge--on {\n stroke: var(--ft-tier-orange);\n /* Wider stroke than off-path so the dot pattern reads clearly on\n dense paths and on high-DPI displays where 1.6px antialiased to\n \"barely visible\". Cross-browser tested floor; renders a solid 3px\n dot (1px hard center + 1px round cap each side) every 13px. */\n stroke-width: 3;\n stroke-linecap: round;\n /* 1px hard dash + 12px gap. With stroke-linecap:round the cap\n extends each dash by half-stroke-width on each end, producing\n visible 4px round beads spaced 13px apart. The \"0.1 9\" pattern in\n 1.30.0 was below subpixel-antialiasing threshold in some\n renderers (particularly Chromium under fit-to-viewport zoom) and\n the dashes disappeared entirely \u2014 leaving the line visually\n \"plain\". 1px is the minimum value every browser renders. */\n stroke-dasharray: 1 12;\n opacity: 1;\n /* Drop-shadow drops a tier-tinted glow under the line. Cheap on\n desktop, slightly more expensive on mobile GPUs but well within\n budget for the handful of paths we render at once. */\n filter: drop-shadow(0 0 5px oklch(0.7 0.18 50 / 0.55));\n /* Animate stroke-dashoffset so beads visibly travel along the\n path. Speed tuned to ~30px/s on a typical card connector \u2014 fast\n enough to read as motion without becoming distracting. */\n animation: ftDashFlow 1.4s linear infinite;\n /* Keep the bead pattern crisp under fit-to-viewport scale()\n transforms \u2014 without this, sub-1 zoom turns 3px strokes into\n fractional pixels and the beads merge into a hairline. */\n vector-effect: non-scaling-stroke;\n}\n.ft-edge--on.ft-edge--solid {\n /* Fallback for any consumer that explicitly opts out of the bead\n pattern \u2014 keeps the legacy solid orange line. */\n stroke-dasharray: none;\n animation: none;\n}\n@keyframes ftDashFlow {\n /* -26 == 2 \u00D7 (1 + 12) so each cycle advances the bead exactly two\n full units, which reads as smooth perpetual flow at 1.4s. */\n to { stroke-dashoffset: -26; }\n}\n@media (prefers-reduced-motion: reduce) {\n .ft-edge--on {\n animation: none;\n /* When motion is suppressed, drop the dot pattern too so users\n see a clean solid line instead of a static frozen dash. */\n stroke-dasharray: none;\n }\n}\n\n/* card */\n.ft-card {\n --tier-local: var(--tier, var(--ft-line-strong));\n width: 100%;\n height: 100%;\n display: grid;\n grid-template-columns: 1fr auto;\n gap: 0;\n align-items: stretch;\n background: oklch(0.21 0.008 80);\n border: 1px solid var(--ft-line);\n border-left: 3px solid var(--tier-local);\n border-radius: 2px;\n transition:\n background 260ms cubic-bezier(.2,.8,.2,1),\n border-color 260ms, box-shadow 260ms,\n transform 260ms cubic-bezier(.2,.8,.2,1),\n filter 260ms, opacity 260ms, color 260ms;\n overflow: visible;\n animation: ftCardIn 320ms cubic-bezier(.2,.8,.2,1) backwards;\n}\n@keyframes ftCardIn {\n from { opacity: 0; transform: translateX(-6px); }\n to { opacity: 1; transform: translateX(0); }\n}\n.ft-card__main {\n display: grid;\n grid-template-columns: auto 1fr auto;\n gap: 10px;\n align-items: center;\n padding: 0 10px 0 12px;\n background: transparent;\n border: none;\n color: inherit;\n font-family: var(--ft-sans);\n font-size: 13px;\n text-align: left;\n cursor: pointer;\n min-width: 0;\n}\n.ft-card__main:hover { background: oklch(0.23 0.01 80 / 0.6); }\n.ft-card__icon {\n width: 24px;\n height: 24px;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n color: var(--tier-local);\n border: 1px solid var(--ft-line-strong);\n background: oklch(0.17 0.008 80);\n flex-shrink: 0;\n}\n.ft-card__body { display: flex; flex-direction: column; min-width: 0; gap: 1px; }\n.ft-card__label {\n font-family: var(--ft-serif);\n font-size: 15px;\n line-height: 1.15;\n color: var(--ft-fg);\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n display: flex;\n align-items: center;\n gap: 5px;\n}\n.ft-card__sub {\n font-family: var(--ft-mono);\n font-size: 9.5px;\n letter-spacing: 0.02em;\n color: var(--ft-muted-fg);\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n.ft-card__lock { color: var(--ft-muted-fg); display: inline-flex; }\n.ft-card__caret {\n width: 18px;\n height: 18px;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n font-family: var(--ft-mono);\n font-size: 12px;\n color: var(--ft-muted-fg);\n border: 1px solid var(--ft-line);\n}\n.ft-card--active .ft-card__caret {\n color: var(--tier-local);\n border-color: var(--tier-local);\n}\n\n.ft-card__rail {\n display: flex;\n flex-direction: column;\n border-left: 1px solid var(--ft-line);\n background: oklch(0.19 0.008 80);\n}\n.ft-card__mini {\n flex: 1;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 28px;\n min-height: 20px;\n background: transparent;\n border: none;\n color: var(--ft-muted-fg);\n cursor: pointer;\n transition: background 150ms, color 150ms;\n border-bottom: 1px solid var(--ft-line);\n padding: 0;\n text-decoration: none;\n}\n.ft-card__mini:last-child { border-bottom: none; }\n.ft-card__mini:hover { background: oklch(0.23 0.01 80); color: var(--tier-local); }\n.ft-card__mini.is-on { color: var(--tier-local); background: oklch(0.23 0.01 80); }\n\n/* states */\n.ft-card--active {\n background: oklch(0.25 0.015 60);\n box-shadow: 0 0 0 1px var(--tier-local), 0 14px 34px -16px oklch(0.5 0.18 50 / 0.55);\n transform: scale(1.02);\n}\n.ft-card--dim {\n filter: grayscale(0.85) brightness(0.82);\n opacity: 0.7;\n transform: scale(0.88);\n transform-origin: center left;\n}\n.ft-card--dim .ft-card__label { color: var(--ft-dim-fg); }\n.ft-card--dim:hover {\n filter: grayscale(0.3) brightness(0.96);\n opacity: 1;\n transform: scale(0.94);\n}\n.ft-card--cta {\n border-left-color: var(--ft-tier-orange);\n background: linear-gradient(180deg, oklch(0.23 0.02 55) 0%, oklch(0.2 0.015 60) 100%);\n}\n.ft-card--root {\n border-left-color: var(--ft-tier-orange);\n background: oklch(0.26 0.015 55);\n}\n.ft-card--root .ft-card__icon {\n color: var(--ft-tier-orange);\n border-color: var(--ft-tier-orange);\n}\n\n/* detail pop */\n.ft-detail {\n position: relative;\n margin-top: 0;\n padding: 16px 18px 14px;\n background: oklch(0.16 0.008 80);\n border: 1px solid var(--ft-line-strong);\n border-left: 2px solid var(--ft-tier-orange);\n border-radius: 3px;\n animation: ftDetailIn 220ms cubic-bezier(.2,.8,.2,1) backwards;\n color: var(--ft-fg);\n width: 320px;\n box-shadow: 0 18px 40px -8px rgba(0,0,0,0.6), 0 2px 8px rgba(0,0,0,0.4);\n}\n.ft-detail__head {\n display: flex;\n align-items: center;\n /* Clear room for the two stacked rail buttons in the top-right\n (expand + close). Bumped from 28px \u2192 58px to fit both. */\n margin: -2px 58px 10px 0;\n}\n.ft-detail__title {\n font-family: var(--ft-mono);\n font-size: 10px;\n letter-spacing: 0.14em;\n text-transform: uppercase;\n color: var(--ft-muted-fg);\n}\n.ft-detail__close,\n.ft-detail__expand {\n position: absolute;\n top: 8px;\n width: 22px;\n height: 22px;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n background: transparent;\n border: 1px solid var(--ft-line);\n border-radius: 2px;\n color: var(--ft-muted-fg);\n cursor: pointer;\n padding: 0;\n transition: color 120ms, border-color 120ms, background 120ms;\n}\n.ft-detail__close { right: 8px; }\n/* Expand button sits immediately to the left of close. */\n.ft-detail__expand { right: 36px; }\n.ft-detail__close:hover,\n.ft-detail__expand:hover {\n color: var(--ft-fg);\n border-color: var(--ft-tier-orange);\n background: oklch(0.22 0.008 80);\n}\n@keyframes ftDetailIn {\n from { opacity: 0; transform: translateY(-4px); }\n to { opacity: 1; transform: translateY(0); }\n}\n.ft-detail__lead {\n /* Inter (sans) at slightly larger size + medium weight reads\n dramatically better than serif italic on dark stages, while still\n looking distinct from the body paragraph. The orange accent\n border on the left preserves the \"pull-quote\" rhythm. */\n font-family: var(--ft-sans);\n font-size: 14.5px;\n line-height: 1.45;\n font-style: normal;\n font-weight: 500;\n color: var(--ft-fg);\n padding-left: 10px;\n border-left: 2px solid var(--ft-tier-orange);\n margin-bottom: 12px;\n}\n.ft-detail__body {\n margin: 0 0 10px;\n font-size: 12px;\n color: var(--ft-muted-fg);\n line-height: 1.5;\n}\n.ft-detail__bullets {\n margin: 0 0 10px;\n padding-left: 16px;\n font-size: 12px;\n color: var(--ft-fg);\n}\n.ft-detail__bullets li { margin-bottom: 3px; }\n.ft-detail__meta {\n margin: 0 0 10px;\n padding: 0;\n display: flex;\n flex-direction: column;\n gap: 4px;\n}\n.ft-detail__meta-row {\n display: grid;\n grid-template-columns: 96px 1fr;\n gap: 8px;\n font-size: 11px;\n}\n.ft-detail__meta-row dt {\n font-family: var(--ft-mono);\n font-size: 9.5px;\n letter-spacing: 0.1em;\n text-transform: uppercase;\n color: var(--ft-muted-fg);\n padding-top: 1px;\n}\n.ft-detail__meta-row dd { margin: 0; color: var(--ft-fg); }\n.ft-detail__actions {\n display: flex;\n gap: 6px;\n flex-wrap: wrap;\n margin-top: 8px;\n}\n\n.ft-btn {\n font-family: var(--ft-mono);\n font-size: 10px;\n letter-spacing: 0.1em;\n text-transform: uppercase;\n padding: 7px 10px;\n background: transparent;\n color: var(--ft-fg);\n border: 1px solid var(--ft-line-strong);\n text-decoration: none;\n cursor: pointer;\n display: inline-flex;\n gap: 5px;\n align-items: center;\n transition: border-color 150ms, background 150ms;\n}\n.ft-btn:hover { border-color: var(--ft-tier-orange); }\n.ft-btn--primary {\n background: var(--ft-tier-orange);\n color: oklch(0.18 0.01 50);\n border-color: var(--ft-tier-orange);\n}\n\n@media (max-width: 760px) {\n .ft-header { padding: 16px 18px 14px; }\n .ft-header__title { font-size: 32px; }\n .ft-controls__hint { display: none; }\n .ft-legend { max-width: calc(100% - 24px); left: 10px; bottom: 10px; }\n /* Larger touch targets on phones \u2014 bumps zoom controls from 26px\n to 36px to comfortably clear the 44px Apple HIG / Material 48dp\n minimum once you account for visual padding. */\n .ft-controls { padding: 6px 8px; }\n .ft-controls button { width: 36px; height: 36px; font-size: 16px; }\n .ft-controls__reset { padding: 0 14px !important; height: 36px; }\n /* Inline detail popup buttons are intentionally compact in the\n inline footprint \u2014 but on touch the user can promote to the\n fullscreen overlay which has 28px buttons by default. */\n .ft-detail__close, .ft-detail__expand { width: 28px; height: 28px; }\n .ft-detail__expand { right: 42px; }\n .ft-detail__head { margin-right: 70px; }\n}\n@media (max-width: 480px) {\n /* Phone-sized: shrink card width so 5+ depth levels still fit\n reasonably without forcing the user to scroll horizontally to\n read the labels. Cards still ellipsis-truncate when needed. */\n .ft-card { font-size: 12px; }\n .ft-card__label { font-size: 14px; }\n .ft-card__sub { font-size: 9px; }\n .ft-controls__hint { display: none; }\n}\n\n/* \u2500\u2500\u2500 Fullscreen detail overlay \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n Triggered by the expand button in any inline DetailPop. Renders\n inside .ft-stage as an absolutely-positioned scrim + scrollable\n panel. The inline pop stays mounted (cheaper React tree) but the\n user's focus and the pointer-events both transfer to the overlay\n while it's visible.\n*/\n.ft-detail-overlay {\n position: absolute;\n inset: 0;\n z-index: 20;\n display: flex;\n align-items: stretch;\n justify-content: center;\n /* Translucent backdrop blurs the flow tree behind so the focused\n content reads cleanly without losing the user's \"where am I\"\n spatial anchor. */\n background: oklch(0.12 0.008 80 / 0.78);\n backdrop-filter: blur(6px);\n animation: ftOverlayIn 200ms cubic-bezier(.2,.8,.2,1);\n}\n@keyframes ftOverlayIn {\n from { opacity: 0; }\n to { opacity: 1; }\n}\n.ft-detail-overlay__panel {\n position: relative;\n margin: 36px;\n flex: 1 1 auto;\n max-width: 760px;\n background: oklch(0.18 0.008 80);\n border: 1px solid var(--ft-line-strong);\n border-left: 3px solid var(--ft-tier-orange);\n border-radius: 4px;\n overflow: auto;\n padding: 26px 32px 28px;\n box-shadow: 0 30px 80px -10px oklch(0 0 0 / 0.7);\n animation: ftOverlayPanelIn 240ms cubic-bezier(.2,.8,.2,1);\n}\n@keyframes ftOverlayPanelIn {\n from { opacity: 0; transform: translateY(8px); }\n to { opacity: 1; transform: translateY(0); }\n}\n.ft-detail-overlay__panel .ft-detail__title {\n font-size: 11px;\n}\n.ft-detail-overlay__panel .ft-detail__lead {\n font-size: 18px;\n line-height: 1.5;\n padding-left: 14px;\n}\n.ft-detail-overlay__panel .ft-detail__body {\n font-size: 14px;\n color: var(--ft-fg);\n line-height: 1.65;\n}\n.ft-detail-overlay__panel .ft-detail__bullets {\n font-size: 14px;\n line-height: 1.55;\n padding-left: 20px;\n}\n.ft-detail-overlay__panel .ft-detail__bullets li { margin-bottom: 6px; }\n.ft-detail-overlay__panel .ft-detail__meta-row {\n font-size: 13px;\n grid-template-columns: 140px 1fr;\n}\n.ft-detail-overlay__panel .ft-detail__meta-row dt { font-size: 10.5px; }\n.ft-detail-overlay__panel .ft-btn { font-size: 11px; padding: 9px 14px; }\n.ft-detail-overlay__head {\n display: flex;\n align-items: center;\n margin: 0 0 14px;\n padding-right: 70px;\n}\n.ft-detail-overlay__title {\n font-family: var(--ft-mono);\n font-size: 11px;\n letter-spacing: 0.18em;\n text-transform: uppercase;\n color: var(--ft-tier-orange);\n}\n.ft-detail-overlay__close,\n.ft-detail-overlay__collapse {\n position: absolute;\n top: 16px;\n width: 28px;\n height: 28px;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n background: transparent;\n border: 1px solid var(--ft-line-strong);\n border-radius: 2px;\n color: var(--ft-fg);\n cursor: pointer;\n padding: 0;\n transition: color 120ms, border-color 120ms, background 120ms;\n}\n.ft-detail-overlay__close { right: 16px; }\n.ft-detail-overlay__collapse { right: 52px; }\n.ft-detail-overlay__close:hover,\n.ft-detail-overlay__collapse:hover {\n color: var(--ft-tier-orange);\n border-color: var(--ft-tier-orange);\n background: oklch(0.22 0.008 80);\n}\n\n@media (max-width: 760px) {\n .ft-detail-overlay__panel {\n margin: 12px;\n padding: 18px 18px 22px;\n }\n .ft-detail-overlay__panel .ft-detail__lead { font-size: 16px; }\n}\n";
|
|
5296
|
+
declare const FLOW_TREE_CSS = "\n@import url(\"https://fonts.googleapis.com/css2?family=Instrument+Serif:ital@0;1&family=Inter:wght@400;500;600&family=JetBrains+Mono:wght@400;500&display=swap\");\n\n.ft-shell {\n --ft-bg: oklch(0.165 0.008 80);\n --ft-panel: oklch(0.21 0.008 80);\n --ft-panel-2: oklch(0.25 0.01 80);\n --ft-fg: oklch(0.96 0.005 85);\n --ft-muted-fg: oklch(0.68 0.008 80);\n --ft-dim-fg: oklch(0.5 0.008 80);\n --ft-line: oklch(0.28 0.008 80);\n --ft-line-strong: oklch(0.4 0.008 80);\n --ft-grid-strong: oklch(0.24 0.008 80);\n --ft-tier-orange: #f16c25;\n --ft-tier-teal: #5fb7b8;\n --ft-tier-blue: oklch(0.72 0.12 240);\n --ft-tier-amber: oklch(0.8 0.14 75);\n --ft-tier-green: oklch(0.74 0.14 155);\n --ft-accent: var(--ft-tier-orange);\n --ft-serif: \"Instrument Serif\", Georgia, serif;\n --ft-sans: \"Inter\", system-ui, sans-serif;\n --ft-mono: \"JetBrains Mono\", ui-monospace, Menlo, monospace;\n\n /* Defensive shell sizing \u2014 fills flex parents (flex: 1) and block\n parents with definite dimensions (width/height: 100%). */\n flex: 1 1 auto;\n width: 100%;\n height: 100%;\n min-height: 420px;\n display: flex;\n flex-direction: column;\n background: var(--ft-bg);\n border: 1px solid var(--ft-line);\n border-radius: 2px;\n overflow: hidden;\n color: var(--ft-fg);\n font-family: var(--ft-sans);\n font-size: 14px;\n line-height: 1.5;\n -webkit-font-smoothing: antialiased;\n box-shadow: 0 30px 60px -30px oklch(0 0 0 / 0.5);\n}\n.ft-shell * { box-sizing: border-box; }\n.ft-shell .ft-mono {\n font-family: var(--ft-mono);\n font-size: 11px;\n letter-spacing: 0.02em;\n}\n\n.ft-header {\n padding: 22px 28px 20px;\n border-bottom: 1px solid var(--ft-line);\n background: linear-gradient(180deg, oklch(0.21 0.01 60) 0%, oklch(0.19 0.008 70) 100%);\n display: flex;\n flex-direction: column;\n gap: 6px;\n}\n.ft-header__eyebrow {\n font-family: var(--ft-mono);\n font-size: 10.5px;\n letter-spacing: 0.22em;\n text-transform: uppercase;\n color: var(--ft-tier-orange);\n}\n.ft-header__title {\n margin: 0;\n font-family: var(--ft-serif);\n font-weight: 400;\n font-size: 44px;\n line-height: 1;\n letter-spacing: -0.015em;\n color: var(--ft-fg);\n}\n.ft-header__tagline {\n margin: 6px 0 0;\n max-width: 76ch;\n color: var(--ft-muted-fg);\n font-size: 13px;\n}\n\n.ft-stage {\n position: relative;\n flex: 1;\n min-height: 0;\n overflow: hidden;\n background:\n radial-gradient(1200px 700px at 15% -10%, oklch(0.22 0.012 60), transparent 60%),\n radial-gradient(900px 600px at 110% 110%, oklch(0.2 0.02 200 / 0.5), transparent 65%);\n}\n\n.ft-svg {\n display: block;\n width: 100%;\n height: 100%;\n background: transparent;\n cursor: grab;\n touch-action: none;\n user-select: none;\n}\n.ft-svg.is-dragging { cursor: grabbing; }\n\n.ft-controls {\n position: absolute;\n top: 14px;\n right: 14px;\n z-index: 5;\n display: flex;\n align-items: center;\n gap: 6px;\n background: oklch(0.2 0.008 80 / 0.94);\n border: 1px solid var(--ft-line-strong);\n padding: 5px 8px;\n backdrop-filter: blur(8px);\n border-radius: 2px;\n}\n.ft-controls button {\n font-family: var(--ft-mono);\n font-size: 12px;\n width: 26px;\n height: 26px;\n background: transparent;\n border: 1px solid var(--ft-line);\n color: var(--ft-fg);\n cursor: pointer;\n padding: 0;\n}\n.ft-controls button:hover { border-color: var(--ft-tier-orange); }\n.ft-controls__reset {\n width: auto !important;\n padding: 0 10px !important;\n font-size: 9.5px !important;\n letter-spacing: 0.1em;\n text-transform: uppercase;\n}\n.ft-controls__hint {\n font-family: var(--ft-mono);\n font-size: 9.5px;\n color: var(--ft-muted-fg);\n letter-spacing: 0.04em;\n padding-left: 8px;\n margin-left: 2px;\n border-left: 1px solid var(--ft-line);\n}\n\n.ft-legend {\n position: absolute;\n left: 18px;\n bottom: 14px;\n z-index: 5;\n display: flex;\n flex-wrap: wrap;\n align-items: center;\n gap: 6px;\n font-family: var(--ft-mono);\n font-size: 10px;\n color: var(--ft-muted-fg);\n background: oklch(0.2 0.008 80 / 0.88);\n border: 1px solid var(--ft-line);\n padding: 6px 10px;\n backdrop-filter: blur(6px);\n max-width: calc(100% - 220px);\n}\n.ft-legend__chip {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n padding: 2px 6px;\n margin: -2px 0;\n background: transparent;\n border: none;\n color: inherit;\n font: inherit;\n letter-spacing: inherit;\n cursor: pointer;\n border-radius: 2px;\n transition: background 120ms, color 120ms;\n}\n.ft-legend__chip:hover {\n background: oklch(0.24 0.01 80);\n color: var(--ft-fg);\n}\n.ft-legend__chip:disabled {\n cursor: default;\n color: var(--ft-fg);\n}\n.ft-legend__chip:disabled:hover { background: transparent; }\n.ft-legend__dot {\n width: 5px;\n height: 5px;\n border-radius: 50%;\n background: var(--ft-tier-orange);\n flex-shrink: 0;\n}\n.ft-legend__sep {\n color: var(--ft-line-strong);\n margin: 0 2px;\n pointer-events: none;\n user-select: none;\n}\n\n/* edges */\n.ft-edge {\n fill: none;\n /* Keep stroke widths crisp under the SVG <g scale(z)> pan/zoom transform.\n Without this, fit-to-viewport (z \u2248 0.6-0.9) renders 1.6px strokes as\n sub-pixel and they visually disappear. */\n vector-effect: non-scaling-stroke;\n transition: stroke 260ms, opacity 260ms;\n}\n.ft-edge--off { stroke: var(--ft-line); stroke-width: 1; opacity: 0.55; }\n.ft-edge--on {\n stroke: var(--ft-tier-orange);\n /* Verbatim restore of the reference design (local-docs/styles.css\n line 133-140). The 4px dash + 5px gap reads as continuous\n marching-ant flow \u2014 every frame, dash edges visibly sweep across\n the path because the gap (5px) is shorter than the dash itself.\n This is what gives the focused branches their \"alive\" feel; the\n wider gap variants (1/12 in 1.30.1, 0.1/9 in 1.30.0) read as\n isolated dots and look static at typical fit-zoom levels. */\n stroke-width: 1.6;\n stroke-dasharray: 4 5;\n opacity: 1;\n animation: ftDashFlow 1.4s linear infinite;\n /* Visibility-under-zoom fix from 1.29.1 \u2014 without this, fit-zoom\n transforms (z \u2248 0.4-0.7) render the 1.6px stroke as sub-pixel\n and the line becomes invisible. Keeps stroke-width and\n dasharray in screen pixels regardless of the SVG transform.\n Not in the reference because the reference demo runs at z=1. */\n vector-effect: non-scaling-stroke;\n}\n@keyframes ftDashFlow {\n /* -36 == 4 \u00D7 (4+5) so the pattern advances exactly four cycles\n per period at 1.4s \u2014 perceptibly fast flow without strobing. */\n to { stroke-dashoffset: -36; }\n}\n@media (prefers-reduced-motion: reduce) {\n /* a11y improvement not in the reference \u2014 users who suppress\n motion get a clean solid line instead of a static frozen dash. */\n .ft-edge--on {\n animation: none;\n stroke-dasharray: none;\n }\n}\n\n/* card */\n.ft-card {\n --tier-local: var(--tier, var(--ft-line-strong));\n width: 100%;\n height: 100%;\n display: grid;\n grid-template-columns: 1fr auto;\n gap: 0;\n align-items: stretch;\n background: oklch(0.21 0.008 80);\n border: 1px solid var(--ft-line);\n border-left: 3px solid var(--tier-local);\n border-radius: 2px;\n transition:\n background 260ms cubic-bezier(.2,.8,.2,1),\n border-color 260ms, box-shadow 260ms,\n transform 260ms cubic-bezier(.2,.8,.2,1),\n filter 260ms, opacity 260ms, color 260ms;\n overflow: visible;\n animation: ftCardIn 320ms cubic-bezier(.2,.8,.2,1) backwards;\n}\n@keyframes ftCardIn {\n from { opacity: 0; transform: translateX(-6px); }\n to { opacity: 1; transform: translateX(0); }\n}\n.ft-card__main {\n display: grid;\n grid-template-columns: auto 1fr auto;\n gap: 10px;\n align-items: center;\n padding: 0 10px 0 12px;\n background: transparent;\n border: none;\n color: inherit;\n font-family: var(--ft-sans);\n font-size: 13px;\n text-align: left;\n cursor: pointer;\n min-width: 0;\n}\n.ft-card__main:hover { background: oklch(0.23 0.01 80 / 0.6); }\n.ft-card__icon {\n width: 24px;\n height: 24px;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n color: var(--tier-local);\n border: 1px solid var(--ft-line-strong);\n background: oklch(0.17 0.008 80);\n flex-shrink: 0;\n}\n.ft-card__body { display: flex; flex-direction: column; min-width: 0; gap: 1px; }\n.ft-card__label {\n font-family: var(--ft-serif);\n font-size: 15px;\n line-height: 1.15;\n color: var(--ft-fg);\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n display: flex;\n align-items: center;\n gap: 5px;\n}\n.ft-card__sub {\n font-family: var(--ft-mono);\n font-size: 9.5px;\n letter-spacing: 0.02em;\n color: var(--ft-muted-fg);\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n.ft-card__lock { color: var(--ft-muted-fg); display: inline-flex; }\n.ft-card__caret {\n width: 18px;\n height: 18px;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n font-family: var(--ft-mono);\n font-size: 12px;\n color: var(--ft-muted-fg);\n border: 1px solid var(--ft-line);\n}\n.ft-card--active .ft-card__caret {\n color: var(--tier-local);\n border-color: var(--tier-local);\n}\n\n.ft-card__rail {\n display: flex;\n flex-direction: column;\n border-left: 1px solid var(--ft-line);\n background: oklch(0.19 0.008 80);\n}\n.ft-card__mini {\n flex: 1;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 28px;\n min-height: 20px;\n background: transparent;\n border: none;\n color: var(--ft-muted-fg);\n cursor: pointer;\n transition: background 150ms, color 150ms;\n border-bottom: 1px solid var(--ft-line);\n padding: 0;\n text-decoration: none;\n}\n.ft-card__mini:last-child { border-bottom: none; }\n.ft-card__mini:hover { background: oklch(0.23 0.01 80); color: var(--tier-local); }\n.ft-card__mini.is-on { color: var(--tier-local); background: oklch(0.23 0.01 80); }\n\n/* states */\n.ft-card--active {\n background: oklch(0.25 0.015 60);\n box-shadow: 0 0 0 1px var(--tier-local), 0 14px 34px -16px oklch(0.5 0.18 50 / 0.55);\n transform: scale(1.02);\n}\n.ft-card--dim {\n filter: grayscale(0.85) brightness(0.82);\n opacity: 0.7;\n transform: scale(0.88);\n transform-origin: center left;\n}\n.ft-card--dim .ft-card__label { color: var(--ft-dim-fg); }\n.ft-card--dim:hover {\n filter: grayscale(0.3) brightness(0.96);\n opacity: 1;\n transform: scale(0.94);\n}\n.ft-card--cta {\n border-left-color: var(--ft-tier-orange);\n background: linear-gradient(180deg, oklch(0.23 0.02 55) 0%, oklch(0.2 0.015 60) 100%);\n}\n.ft-card--root {\n border-left-color: var(--ft-tier-orange);\n background: oklch(0.26 0.015 55);\n}\n.ft-card--root .ft-card__icon {\n color: var(--ft-tier-orange);\n border-color: var(--ft-tier-orange);\n}\n\n/* detail pop */\n.ft-detail {\n position: relative;\n margin-top: 0;\n padding: 16px 18px 14px;\n background: oklch(0.16 0.008 80);\n border: 1px solid var(--ft-line-strong);\n border-left: 2px solid var(--ft-tier-orange);\n border-radius: 3px;\n animation: ftDetailIn 220ms cubic-bezier(.2,.8,.2,1) backwards;\n color: var(--ft-fg);\n width: 320px;\n box-shadow: 0 18px 40px -8px rgba(0,0,0,0.6), 0 2px 8px rgba(0,0,0,0.4);\n}\n.ft-detail__head {\n display: flex;\n align-items: center;\n /* Clear room for the two stacked rail buttons in the top-right\n (expand + close). Bumped from 28px \u2192 58px to fit both. */\n margin: -2px 58px 10px 0;\n}\n.ft-detail__title {\n font-family: var(--ft-mono);\n font-size: 10px;\n letter-spacing: 0.14em;\n text-transform: uppercase;\n color: var(--ft-muted-fg);\n}\n.ft-detail__close,\n.ft-detail__expand {\n position: absolute;\n top: 8px;\n width: 22px;\n height: 22px;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n background: transparent;\n border: 1px solid var(--ft-line);\n border-radius: 2px;\n color: var(--ft-muted-fg);\n cursor: pointer;\n padding: 0;\n transition: color 120ms, border-color 120ms, background 120ms;\n}\n.ft-detail__close { right: 8px; }\n/* Expand button sits immediately to the left of close. */\n.ft-detail__expand { right: 36px; }\n.ft-detail__close:hover,\n.ft-detail__expand:hover {\n color: var(--ft-fg);\n border-color: var(--ft-tier-orange);\n background: oklch(0.22 0.008 80);\n}\n@keyframes ftDetailIn {\n from { opacity: 0; transform: translateY(-4px); }\n to { opacity: 1; transform: translateY(0); }\n}\n.ft-detail__lead {\n /* Inter (sans) at slightly larger size + medium weight reads\n dramatically better than serif italic on dark stages, while still\n looking distinct from the body paragraph. The orange accent\n border on the left preserves the \"pull-quote\" rhythm. */\n font-family: var(--ft-sans);\n font-size: 14.5px;\n line-height: 1.45;\n font-style: normal;\n font-weight: 500;\n color: var(--ft-fg);\n padding-left: 10px;\n border-left: 2px solid var(--ft-tier-orange);\n margin-bottom: 12px;\n}\n.ft-detail__body {\n margin: 0 0 10px;\n font-size: 12px;\n color: var(--ft-muted-fg);\n line-height: 1.5;\n}\n.ft-detail__bullets {\n margin: 0 0 10px;\n padding-left: 16px;\n font-size: 12px;\n color: var(--ft-fg);\n}\n.ft-detail__bullets li { margin-bottom: 3px; }\n.ft-detail__meta {\n margin: 0 0 10px;\n padding: 0;\n display: flex;\n flex-direction: column;\n gap: 4px;\n}\n.ft-detail__meta-row {\n display: grid;\n grid-template-columns: 96px 1fr;\n gap: 8px;\n font-size: 11px;\n}\n.ft-detail__meta-row dt {\n font-family: var(--ft-mono);\n font-size: 9.5px;\n letter-spacing: 0.1em;\n text-transform: uppercase;\n color: var(--ft-muted-fg);\n padding-top: 1px;\n}\n.ft-detail__meta-row dd { margin: 0; color: var(--ft-fg); }\n.ft-detail__actions {\n display: flex;\n gap: 6px;\n flex-wrap: wrap;\n margin-top: 8px;\n}\n\n.ft-btn {\n font-family: var(--ft-mono);\n font-size: 10px;\n letter-spacing: 0.1em;\n text-transform: uppercase;\n padding: 7px 10px;\n background: transparent;\n color: var(--ft-fg);\n border: 1px solid var(--ft-line-strong);\n text-decoration: none;\n cursor: pointer;\n display: inline-flex;\n gap: 5px;\n align-items: center;\n transition: border-color 150ms, background 150ms;\n}\n.ft-btn:hover { border-color: var(--ft-tier-orange); }\n.ft-btn--primary {\n background: var(--ft-tier-orange);\n color: oklch(0.18 0.01 50);\n border-color: var(--ft-tier-orange);\n}\n\n@media (max-width: 760px) {\n .ft-header { padding: 16px 18px 14px; }\n .ft-header__title { font-size: 32px; }\n .ft-controls__hint { display: none; }\n .ft-legend { max-width: calc(100% - 24px); left: 10px; bottom: 10px; }\n /* Larger touch targets on phones \u2014 bumps zoom controls from 26px\n to 36px to comfortably clear the 44px Apple HIG / Material 48dp\n minimum once you account for visual padding. */\n .ft-controls { padding: 6px 8px; }\n .ft-controls button { width: 36px; height: 36px; font-size: 16px; }\n .ft-controls__reset { padding: 0 14px !important; height: 36px; }\n /* Inline detail popup buttons are intentionally compact in the\n inline footprint \u2014 but on touch the user can promote to the\n fullscreen overlay which has 28px buttons by default. */\n .ft-detail__close, .ft-detail__expand { width: 28px; height: 28px; }\n .ft-detail__expand { right: 42px; }\n .ft-detail__head { margin-right: 70px; }\n}\n@media (max-width: 480px) {\n /* Phone-sized: shrink card width so 5+ depth levels still fit\n reasonably without forcing the user to scroll horizontally to\n read the labels. Cards still ellipsis-truncate when needed. */\n .ft-card { font-size: 12px; }\n .ft-card__label { font-size: 14px; }\n .ft-card__sub { font-size: 9px; }\n .ft-controls__hint { display: none; }\n}\n\n/* \u2500\u2500\u2500 Fullscreen detail overlay \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n Triggered by the expand button in any inline DetailPop. Renders\n inside .ft-stage as an absolutely-positioned scrim + scrollable\n panel. The inline pop stays mounted (cheaper React tree) but the\n user's focus and the pointer-events both transfer to the overlay\n while it's visible.\n*/\n.ft-detail-overlay {\n position: absolute;\n inset: 0;\n z-index: 20;\n display: flex;\n align-items: stretch;\n justify-content: center;\n /* Translucent backdrop blurs the flow tree behind so the focused\n content reads cleanly without losing the user's \"where am I\"\n spatial anchor. */\n background: oklch(0.12 0.008 80 / 0.78);\n backdrop-filter: blur(6px);\n animation: ftOverlayIn 200ms cubic-bezier(.2,.8,.2,1);\n}\n@keyframes ftOverlayIn {\n from { opacity: 0; }\n to { opacity: 1; }\n}\n.ft-detail-overlay__panel {\n position: relative;\n margin: 36px;\n flex: 1 1 auto;\n max-width: 760px;\n background: oklch(0.18 0.008 80);\n border: 1px solid var(--ft-line-strong);\n border-left: 3px solid var(--ft-tier-orange);\n border-radius: 4px;\n overflow: auto;\n padding: 26px 32px 28px;\n box-shadow: 0 30px 80px -10px oklch(0 0 0 / 0.7);\n animation: ftOverlayPanelIn 240ms cubic-bezier(.2,.8,.2,1);\n}\n@keyframes ftOverlayPanelIn {\n from { opacity: 0; transform: translateY(8px); }\n to { opacity: 1; transform: translateY(0); }\n}\n.ft-detail-overlay__panel .ft-detail__title {\n font-size: 11px;\n}\n.ft-detail-overlay__panel .ft-detail__lead {\n font-size: 18px;\n line-height: 1.5;\n padding-left: 14px;\n}\n.ft-detail-overlay__panel .ft-detail__body {\n font-size: 14px;\n color: var(--ft-fg);\n line-height: 1.65;\n}\n.ft-detail-overlay__panel .ft-detail__bullets {\n font-size: 14px;\n line-height: 1.55;\n padding-left: 20px;\n}\n.ft-detail-overlay__panel .ft-detail__bullets li { margin-bottom: 6px; }\n.ft-detail-overlay__panel .ft-detail__meta-row {\n font-size: 13px;\n grid-template-columns: 140px 1fr;\n}\n.ft-detail-overlay__panel .ft-detail__meta-row dt { font-size: 10.5px; }\n.ft-detail-overlay__panel .ft-btn { font-size: 11px; padding: 9px 14px; }\n.ft-detail-overlay__head {\n display: flex;\n align-items: center;\n margin: 0 0 14px;\n padding-right: 70px;\n}\n.ft-detail-overlay__title {\n font-family: var(--ft-mono);\n font-size: 11px;\n letter-spacing: 0.18em;\n text-transform: uppercase;\n color: var(--ft-tier-orange);\n}\n.ft-detail-overlay__close,\n.ft-detail-overlay__collapse {\n position: absolute;\n top: 16px;\n width: 28px;\n height: 28px;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n background: transparent;\n border: 1px solid var(--ft-line-strong);\n border-radius: 2px;\n color: var(--ft-fg);\n cursor: pointer;\n padding: 0;\n transition: color 120ms, border-color 120ms, background 120ms;\n}\n.ft-detail-overlay__close { right: 16px; }\n.ft-detail-overlay__collapse { right: 52px; }\n.ft-detail-overlay__close:hover,\n.ft-detail-overlay__collapse:hover {\n color: var(--ft-tier-orange);\n border-color: var(--ft-tier-orange);\n background: oklch(0.22 0.008 80);\n}\n\n@media (max-width: 760px) {\n .ft-detail-overlay__panel {\n margin: 12px;\n padding: 18px 18px 22px;\n }\n .ft-detail-overlay__panel .ft-detail__lead { font-size: 16px; }\n}\n";
|
|
5297
5297
|
|
|
5298
5298
|
type GameTimerMode = "countdown" | "countup";
|
|
5299
5299
|
type GameTimerThemePreset = "green" | "red" | "blue" | "amber" | "purple" | "pink" | "teal";
|
package/dist/index.d.ts
CHANGED
|
@@ -5293,7 +5293,7 @@ declare function FlowTree({ data, title, eyebrow, tagline, renderIcon: renderIco
|
|
|
5293
5293
|
* delta: it keeps connector strokes crisp under the pan/zoom transform's
|
|
5294
5294
|
* `scale()` (otherwise sub-1 fit-zoom renders them sub-pixel and invisible).
|
|
5295
5295
|
*/
|
|
5296
|
-
declare const FLOW_TREE_CSS = "\n@import url(\"https://fonts.googleapis.com/css2?family=Instrument+Serif:ital@0;1&family=Inter:wght@400;500;600&family=JetBrains+Mono:wght@400;500&display=swap\");\n\n.ft-shell {\n --ft-bg: oklch(0.165 0.008 80);\n --ft-panel: oklch(0.21 0.008 80);\n --ft-panel-2: oklch(0.25 0.01 80);\n --ft-fg: oklch(0.96 0.005 85);\n --ft-muted-fg: oklch(0.68 0.008 80);\n --ft-dim-fg: oklch(0.5 0.008 80);\n --ft-line: oklch(0.28 0.008 80);\n --ft-line-strong: oklch(0.4 0.008 80);\n --ft-grid-strong: oklch(0.24 0.008 80);\n --ft-tier-orange: #f16c25;\n --ft-tier-teal: #5fb7b8;\n --ft-tier-blue: oklch(0.72 0.12 240);\n --ft-tier-amber: oklch(0.8 0.14 75);\n --ft-tier-green: oklch(0.74 0.14 155);\n --ft-accent: var(--ft-tier-orange);\n --ft-serif: \"Instrument Serif\", Georgia, serif;\n --ft-sans: \"Inter\", system-ui, sans-serif;\n --ft-mono: \"JetBrains Mono\", ui-monospace, Menlo, monospace;\n\n /* Defensive shell sizing \u2014 fills flex parents (flex: 1) and block\n parents with definite dimensions (width/height: 100%). */\n flex: 1 1 auto;\n width: 100%;\n height: 100%;\n min-height: 420px;\n display: flex;\n flex-direction: column;\n background: var(--ft-bg);\n border: 1px solid var(--ft-line);\n border-radius: 2px;\n overflow: hidden;\n color: var(--ft-fg);\n font-family: var(--ft-sans);\n font-size: 14px;\n line-height: 1.5;\n -webkit-font-smoothing: antialiased;\n box-shadow: 0 30px 60px -30px oklch(0 0 0 / 0.5);\n}\n.ft-shell * { box-sizing: border-box; }\n.ft-shell .ft-mono {\n font-family: var(--ft-mono);\n font-size: 11px;\n letter-spacing: 0.02em;\n}\n\n.ft-header {\n padding: 22px 28px 20px;\n border-bottom: 1px solid var(--ft-line);\n background: linear-gradient(180deg, oklch(0.21 0.01 60) 0%, oklch(0.19 0.008 70) 100%);\n display: flex;\n flex-direction: column;\n gap: 6px;\n}\n.ft-header__eyebrow {\n font-family: var(--ft-mono);\n font-size: 10.5px;\n letter-spacing: 0.22em;\n text-transform: uppercase;\n color: var(--ft-tier-orange);\n}\n.ft-header__title {\n margin: 0;\n font-family: var(--ft-serif);\n font-weight: 400;\n font-size: 44px;\n line-height: 1;\n letter-spacing: -0.015em;\n color: var(--ft-fg);\n}\n.ft-header__tagline {\n margin: 6px 0 0;\n max-width: 76ch;\n color: var(--ft-muted-fg);\n font-size: 13px;\n}\n\n.ft-stage {\n position: relative;\n flex: 1;\n min-height: 0;\n overflow: hidden;\n background:\n radial-gradient(1200px 700px at 15% -10%, oklch(0.22 0.012 60), transparent 60%),\n radial-gradient(900px 600px at 110% 110%, oklch(0.2 0.02 200 / 0.5), transparent 65%);\n}\n\n.ft-svg {\n display: block;\n width: 100%;\n height: 100%;\n background: transparent;\n cursor: grab;\n touch-action: none;\n user-select: none;\n}\n.ft-svg.is-dragging { cursor: grabbing; }\n\n.ft-controls {\n position: absolute;\n top: 14px;\n right: 14px;\n z-index: 5;\n display: flex;\n align-items: center;\n gap: 6px;\n background: oklch(0.2 0.008 80 / 0.94);\n border: 1px solid var(--ft-line-strong);\n padding: 5px 8px;\n backdrop-filter: blur(8px);\n border-radius: 2px;\n}\n.ft-controls button {\n font-family: var(--ft-mono);\n font-size: 12px;\n width: 26px;\n height: 26px;\n background: transparent;\n border: 1px solid var(--ft-line);\n color: var(--ft-fg);\n cursor: pointer;\n padding: 0;\n}\n.ft-controls button:hover { border-color: var(--ft-tier-orange); }\n.ft-controls__reset {\n width: auto !important;\n padding: 0 10px !important;\n font-size: 9.5px !important;\n letter-spacing: 0.1em;\n text-transform: uppercase;\n}\n.ft-controls__hint {\n font-family: var(--ft-mono);\n font-size: 9.5px;\n color: var(--ft-muted-fg);\n letter-spacing: 0.04em;\n padding-left: 8px;\n margin-left: 2px;\n border-left: 1px solid var(--ft-line);\n}\n\n.ft-legend {\n position: absolute;\n left: 18px;\n bottom: 14px;\n z-index: 5;\n display: flex;\n flex-wrap: wrap;\n align-items: center;\n gap: 6px;\n font-family: var(--ft-mono);\n font-size: 10px;\n color: var(--ft-muted-fg);\n background: oklch(0.2 0.008 80 / 0.88);\n border: 1px solid var(--ft-line);\n padding: 6px 10px;\n backdrop-filter: blur(6px);\n max-width: calc(100% - 220px);\n}\n.ft-legend__chip {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n padding: 2px 6px;\n margin: -2px 0;\n background: transparent;\n border: none;\n color: inherit;\n font: inherit;\n letter-spacing: inherit;\n cursor: pointer;\n border-radius: 2px;\n transition: background 120ms, color 120ms;\n}\n.ft-legend__chip:hover {\n background: oklch(0.24 0.01 80);\n color: var(--ft-fg);\n}\n.ft-legend__chip:disabled {\n cursor: default;\n color: var(--ft-fg);\n}\n.ft-legend__chip:disabled:hover { background: transparent; }\n.ft-legend__dot {\n width: 5px;\n height: 5px;\n border-radius: 50%;\n background: var(--ft-tier-orange);\n flex-shrink: 0;\n}\n.ft-legend__sep {\n color: var(--ft-line-strong);\n margin: 0 2px;\n pointer-events: none;\n user-select: none;\n}\n\n/* edges */\n.ft-edge {\n fill: none;\n /* Keep stroke widths crisp under the SVG <g scale(z)> pan/zoom transform.\n Without this, fit-to-viewport (z \u2248 0.6-0.9) renders 1.6px strokes as\n sub-pixel and they visually disappear. */\n vector-effect: non-scaling-stroke;\n transition: stroke 260ms, opacity 260ms;\n}\n.ft-edge--off { stroke: var(--ft-line); stroke-width: 1; opacity: 0.55; }\n.ft-edge--on {\n stroke: var(--ft-tier-orange);\n /* Wider stroke than off-path so the dot pattern reads clearly on\n dense paths and on high-DPI displays where 1.6px antialiased to\n \"barely visible\". Cross-browser tested floor; renders a solid 3px\n dot (1px hard center + 1px round cap each side) every 13px. */\n stroke-width: 3;\n stroke-linecap: round;\n /* 1px hard dash + 12px gap. With stroke-linecap:round the cap\n extends each dash by half-stroke-width on each end, producing\n visible 4px round beads spaced 13px apart. The \"0.1 9\" pattern in\n 1.30.0 was below subpixel-antialiasing threshold in some\n renderers (particularly Chromium under fit-to-viewport zoom) and\n the dashes disappeared entirely \u2014 leaving the line visually\n \"plain\". 1px is the minimum value every browser renders. */\n stroke-dasharray: 1 12;\n opacity: 1;\n /* Drop-shadow drops a tier-tinted glow under the line. Cheap on\n desktop, slightly more expensive on mobile GPUs but well within\n budget for the handful of paths we render at once. */\n filter: drop-shadow(0 0 5px oklch(0.7 0.18 50 / 0.55));\n /* Animate stroke-dashoffset so beads visibly travel along the\n path. Speed tuned to ~30px/s on a typical card connector \u2014 fast\n enough to read as motion without becoming distracting. */\n animation: ftDashFlow 1.4s linear infinite;\n /* Keep the bead pattern crisp under fit-to-viewport scale()\n transforms \u2014 without this, sub-1 zoom turns 3px strokes into\n fractional pixels and the beads merge into a hairline. */\n vector-effect: non-scaling-stroke;\n}\n.ft-edge--on.ft-edge--solid {\n /* Fallback for any consumer that explicitly opts out of the bead\n pattern \u2014 keeps the legacy solid orange line. */\n stroke-dasharray: none;\n animation: none;\n}\n@keyframes ftDashFlow {\n /* -26 == 2 \u00D7 (1 + 12) so each cycle advances the bead exactly two\n full units, which reads as smooth perpetual flow at 1.4s. */\n to { stroke-dashoffset: -26; }\n}\n@media (prefers-reduced-motion: reduce) {\n .ft-edge--on {\n animation: none;\n /* When motion is suppressed, drop the dot pattern too so users\n see a clean solid line instead of a static frozen dash. */\n stroke-dasharray: none;\n }\n}\n\n/* card */\n.ft-card {\n --tier-local: var(--tier, var(--ft-line-strong));\n width: 100%;\n height: 100%;\n display: grid;\n grid-template-columns: 1fr auto;\n gap: 0;\n align-items: stretch;\n background: oklch(0.21 0.008 80);\n border: 1px solid var(--ft-line);\n border-left: 3px solid var(--tier-local);\n border-radius: 2px;\n transition:\n background 260ms cubic-bezier(.2,.8,.2,1),\n border-color 260ms, box-shadow 260ms,\n transform 260ms cubic-bezier(.2,.8,.2,1),\n filter 260ms, opacity 260ms, color 260ms;\n overflow: visible;\n animation: ftCardIn 320ms cubic-bezier(.2,.8,.2,1) backwards;\n}\n@keyframes ftCardIn {\n from { opacity: 0; transform: translateX(-6px); }\n to { opacity: 1; transform: translateX(0); }\n}\n.ft-card__main {\n display: grid;\n grid-template-columns: auto 1fr auto;\n gap: 10px;\n align-items: center;\n padding: 0 10px 0 12px;\n background: transparent;\n border: none;\n color: inherit;\n font-family: var(--ft-sans);\n font-size: 13px;\n text-align: left;\n cursor: pointer;\n min-width: 0;\n}\n.ft-card__main:hover { background: oklch(0.23 0.01 80 / 0.6); }\n.ft-card__icon {\n width: 24px;\n height: 24px;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n color: var(--tier-local);\n border: 1px solid var(--ft-line-strong);\n background: oklch(0.17 0.008 80);\n flex-shrink: 0;\n}\n.ft-card__body { display: flex; flex-direction: column; min-width: 0; gap: 1px; }\n.ft-card__label {\n font-family: var(--ft-serif);\n font-size: 15px;\n line-height: 1.15;\n color: var(--ft-fg);\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n display: flex;\n align-items: center;\n gap: 5px;\n}\n.ft-card__sub {\n font-family: var(--ft-mono);\n font-size: 9.5px;\n letter-spacing: 0.02em;\n color: var(--ft-muted-fg);\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n.ft-card__lock { color: var(--ft-muted-fg); display: inline-flex; }\n.ft-card__caret {\n width: 18px;\n height: 18px;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n font-family: var(--ft-mono);\n font-size: 12px;\n color: var(--ft-muted-fg);\n border: 1px solid var(--ft-line);\n}\n.ft-card--active .ft-card__caret {\n color: var(--tier-local);\n border-color: var(--tier-local);\n}\n\n.ft-card__rail {\n display: flex;\n flex-direction: column;\n border-left: 1px solid var(--ft-line);\n background: oklch(0.19 0.008 80);\n}\n.ft-card__mini {\n flex: 1;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 28px;\n min-height: 20px;\n background: transparent;\n border: none;\n color: var(--ft-muted-fg);\n cursor: pointer;\n transition: background 150ms, color 150ms;\n border-bottom: 1px solid var(--ft-line);\n padding: 0;\n text-decoration: none;\n}\n.ft-card__mini:last-child { border-bottom: none; }\n.ft-card__mini:hover { background: oklch(0.23 0.01 80); color: var(--tier-local); }\n.ft-card__mini.is-on { color: var(--tier-local); background: oklch(0.23 0.01 80); }\n\n/* states */\n.ft-card--active {\n background: oklch(0.25 0.015 60);\n box-shadow: 0 0 0 1px var(--tier-local), 0 14px 34px -16px oklch(0.5 0.18 50 / 0.55);\n transform: scale(1.02);\n}\n.ft-card--dim {\n filter: grayscale(0.85) brightness(0.82);\n opacity: 0.7;\n transform: scale(0.88);\n transform-origin: center left;\n}\n.ft-card--dim .ft-card__label { color: var(--ft-dim-fg); }\n.ft-card--dim:hover {\n filter: grayscale(0.3) brightness(0.96);\n opacity: 1;\n transform: scale(0.94);\n}\n.ft-card--cta {\n border-left-color: var(--ft-tier-orange);\n background: linear-gradient(180deg, oklch(0.23 0.02 55) 0%, oklch(0.2 0.015 60) 100%);\n}\n.ft-card--root {\n border-left-color: var(--ft-tier-orange);\n background: oklch(0.26 0.015 55);\n}\n.ft-card--root .ft-card__icon {\n color: var(--ft-tier-orange);\n border-color: var(--ft-tier-orange);\n}\n\n/* detail pop */\n.ft-detail {\n position: relative;\n margin-top: 0;\n padding: 16px 18px 14px;\n background: oklch(0.16 0.008 80);\n border: 1px solid var(--ft-line-strong);\n border-left: 2px solid var(--ft-tier-orange);\n border-radius: 3px;\n animation: ftDetailIn 220ms cubic-bezier(.2,.8,.2,1) backwards;\n color: var(--ft-fg);\n width: 320px;\n box-shadow: 0 18px 40px -8px rgba(0,0,0,0.6), 0 2px 8px rgba(0,0,0,0.4);\n}\n.ft-detail__head {\n display: flex;\n align-items: center;\n /* Clear room for the two stacked rail buttons in the top-right\n (expand + close). Bumped from 28px \u2192 58px to fit both. */\n margin: -2px 58px 10px 0;\n}\n.ft-detail__title {\n font-family: var(--ft-mono);\n font-size: 10px;\n letter-spacing: 0.14em;\n text-transform: uppercase;\n color: var(--ft-muted-fg);\n}\n.ft-detail__close,\n.ft-detail__expand {\n position: absolute;\n top: 8px;\n width: 22px;\n height: 22px;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n background: transparent;\n border: 1px solid var(--ft-line);\n border-radius: 2px;\n color: var(--ft-muted-fg);\n cursor: pointer;\n padding: 0;\n transition: color 120ms, border-color 120ms, background 120ms;\n}\n.ft-detail__close { right: 8px; }\n/* Expand button sits immediately to the left of close. */\n.ft-detail__expand { right: 36px; }\n.ft-detail__close:hover,\n.ft-detail__expand:hover {\n color: var(--ft-fg);\n border-color: var(--ft-tier-orange);\n background: oklch(0.22 0.008 80);\n}\n@keyframes ftDetailIn {\n from { opacity: 0; transform: translateY(-4px); }\n to { opacity: 1; transform: translateY(0); }\n}\n.ft-detail__lead {\n /* Inter (sans) at slightly larger size + medium weight reads\n dramatically better than serif italic on dark stages, while still\n looking distinct from the body paragraph. The orange accent\n border on the left preserves the \"pull-quote\" rhythm. */\n font-family: var(--ft-sans);\n font-size: 14.5px;\n line-height: 1.45;\n font-style: normal;\n font-weight: 500;\n color: var(--ft-fg);\n padding-left: 10px;\n border-left: 2px solid var(--ft-tier-orange);\n margin-bottom: 12px;\n}\n.ft-detail__body {\n margin: 0 0 10px;\n font-size: 12px;\n color: var(--ft-muted-fg);\n line-height: 1.5;\n}\n.ft-detail__bullets {\n margin: 0 0 10px;\n padding-left: 16px;\n font-size: 12px;\n color: var(--ft-fg);\n}\n.ft-detail__bullets li { margin-bottom: 3px; }\n.ft-detail__meta {\n margin: 0 0 10px;\n padding: 0;\n display: flex;\n flex-direction: column;\n gap: 4px;\n}\n.ft-detail__meta-row {\n display: grid;\n grid-template-columns: 96px 1fr;\n gap: 8px;\n font-size: 11px;\n}\n.ft-detail__meta-row dt {\n font-family: var(--ft-mono);\n font-size: 9.5px;\n letter-spacing: 0.1em;\n text-transform: uppercase;\n color: var(--ft-muted-fg);\n padding-top: 1px;\n}\n.ft-detail__meta-row dd { margin: 0; color: var(--ft-fg); }\n.ft-detail__actions {\n display: flex;\n gap: 6px;\n flex-wrap: wrap;\n margin-top: 8px;\n}\n\n.ft-btn {\n font-family: var(--ft-mono);\n font-size: 10px;\n letter-spacing: 0.1em;\n text-transform: uppercase;\n padding: 7px 10px;\n background: transparent;\n color: var(--ft-fg);\n border: 1px solid var(--ft-line-strong);\n text-decoration: none;\n cursor: pointer;\n display: inline-flex;\n gap: 5px;\n align-items: center;\n transition: border-color 150ms, background 150ms;\n}\n.ft-btn:hover { border-color: var(--ft-tier-orange); }\n.ft-btn--primary {\n background: var(--ft-tier-orange);\n color: oklch(0.18 0.01 50);\n border-color: var(--ft-tier-orange);\n}\n\n@media (max-width: 760px) {\n .ft-header { padding: 16px 18px 14px; }\n .ft-header__title { font-size: 32px; }\n .ft-controls__hint { display: none; }\n .ft-legend { max-width: calc(100% - 24px); left: 10px; bottom: 10px; }\n /* Larger touch targets on phones \u2014 bumps zoom controls from 26px\n to 36px to comfortably clear the 44px Apple HIG / Material 48dp\n minimum once you account for visual padding. */\n .ft-controls { padding: 6px 8px; }\n .ft-controls button { width: 36px; height: 36px; font-size: 16px; }\n .ft-controls__reset { padding: 0 14px !important; height: 36px; }\n /* Inline detail popup buttons are intentionally compact in the\n inline footprint \u2014 but on touch the user can promote to the\n fullscreen overlay which has 28px buttons by default. */\n .ft-detail__close, .ft-detail__expand { width: 28px; height: 28px; }\n .ft-detail__expand { right: 42px; }\n .ft-detail__head { margin-right: 70px; }\n}\n@media (max-width: 480px) {\n /* Phone-sized: shrink card width so 5+ depth levels still fit\n reasonably without forcing the user to scroll horizontally to\n read the labels. Cards still ellipsis-truncate when needed. */\n .ft-card { font-size: 12px; }\n .ft-card__label { font-size: 14px; }\n .ft-card__sub { font-size: 9px; }\n .ft-controls__hint { display: none; }\n}\n\n/* \u2500\u2500\u2500 Fullscreen detail overlay \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n Triggered by the expand button in any inline DetailPop. Renders\n inside .ft-stage as an absolutely-positioned scrim + scrollable\n panel. The inline pop stays mounted (cheaper React tree) but the\n user's focus and the pointer-events both transfer to the overlay\n while it's visible.\n*/\n.ft-detail-overlay {\n position: absolute;\n inset: 0;\n z-index: 20;\n display: flex;\n align-items: stretch;\n justify-content: center;\n /* Translucent backdrop blurs the flow tree behind so the focused\n content reads cleanly without losing the user's \"where am I\"\n spatial anchor. */\n background: oklch(0.12 0.008 80 / 0.78);\n backdrop-filter: blur(6px);\n animation: ftOverlayIn 200ms cubic-bezier(.2,.8,.2,1);\n}\n@keyframes ftOverlayIn {\n from { opacity: 0; }\n to { opacity: 1; }\n}\n.ft-detail-overlay__panel {\n position: relative;\n margin: 36px;\n flex: 1 1 auto;\n max-width: 760px;\n background: oklch(0.18 0.008 80);\n border: 1px solid var(--ft-line-strong);\n border-left: 3px solid var(--ft-tier-orange);\n border-radius: 4px;\n overflow: auto;\n padding: 26px 32px 28px;\n box-shadow: 0 30px 80px -10px oklch(0 0 0 / 0.7);\n animation: ftOverlayPanelIn 240ms cubic-bezier(.2,.8,.2,1);\n}\n@keyframes ftOverlayPanelIn {\n from { opacity: 0; transform: translateY(8px); }\n to { opacity: 1; transform: translateY(0); }\n}\n.ft-detail-overlay__panel .ft-detail__title {\n font-size: 11px;\n}\n.ft-detail-overlay__panel .ft-detail__lead {\n font-size: 18px;\n line-height: 1.5;\n padding-left: 14px;\n}\n.ft-detail-overlay__panel .ft-detail__body {\n font-size: 14px;\n color: var(--ft-fg);\n line-height: 1.65;\n}\n.ft-detail-overlay__panel .ft-detail__bullets {\n font-size: 14px;\n line-height: 1.55;\n padding-left: 20px;\n}\n.ft-detail-overlay__panel .ft-detail__bullets li { margin-bottom: 6px; }\n.ft-detail-overlay__panel .ft-detail__meta-row {\n font-size: 13px;\n grid-template-columns: 140px 1fr;\n}\n.ft-detail-overlay__panel .ft-detail__meta-row dt { font-size: 10.5px; }\n.ft-detail-overlay__panel .ft-btn { font-size: 11px; padding: 9px 14px; }\n.ft-detail-overlay__head {\n display: flex;\n align-items: center;\n margin: 0 0 14px;\n padding-right: 70px;\n}\n.ft-detail-overlay__title {\n font-family: var(--ft-mono);\n font-size: 11px;\n letter-spacing: 0.18em;\n text-transform: uppercase;\n color: var(--ft-tier-orange);\n}\n.ft-detail-overlay__close,\n.ft-detail-overlay__collapse {\n position: absolute;\n top: 16px;\n width: 28px;\n height: 28px;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n background: transparent;\n border: 1px solid var(--ft-line-strong);\n border-radius: 2px;\n color: var(--ft-fg);\n cursor: pointer;\n padding: 0;\n transition: color 120ms, border-color 120ms, background 120ms;\n}\n.ft-detail-overlay__close { right: 16px; }\n.ft-detail-overlay__collapse { right: 52px; }\n.ft-detail-overlay__close:hover,\n.ft-detail-overlay__collapse:hover {\n color: var(--ft-tier-orange);\n border-color: var(--ft-tier-orange);\n background: oklch(0.22 0.008 80);\n}\n\n@media (max-width: 760px) {\n .ft-detail-overlay__panel {\n margin: 12px;\n padding: 18px 18px 22px;\n }\n .ft-detail-overlay__panel .ft-detail__lead { font-size: 16px; }\n}\n";
|
|
5296
|
+
declare const FLOW_TREE_CSS = "\n@import url(\"https://fonts.googleapis.com/css2?family=Instrument+Serif:ital@0;1&family=Inter:wght@400;500;600&family=JetBrains+Mono:wght@400;500&display=swap\");\n\n.ft-shell {\n --ft-bg: oklch(0.165 0.008 80);\n --ft-panel: oklch(0.21 0.008 80);\n --ft-panel-2: oklch(0.25 0.01 80);\n --ft-fg: oklch(0.96 0.005 85);\n --ft-muted-fg: oklch(0.68 0.008 80);\n --ft-dim-fg: oklch(0.5 0.008 80);\n --ft-line: oklch(0.28 0.008 80);\n --ft-line-strong: oklch(0.4 0.008 80);\n --ft-grid-strong: oklch(0.24 0.008 80);\n --ft-tier-orange: #f16c25;\n --ft-tier-teal: #5fb7b8;\n --ft-tier-blue: oklch(0.72 0.12 240);\n --ft-tier-amber: oklch(0.8 0.14 75);\n --ft-tier-green: oklch(0.74 0.14 155);\n --ft-accent: var(--ft-tier-orange);\n --ft-serif: \"Instrument Serif\", Georgia, serif;\n --ft-sans: \"Inter\", system-ui, sans-serif;\n --ft-mono: \"JetBrains Mono\", ui-monospace, Menlo, monospace;\n\n /* Defensive shell sizing \u2014 fills flex parents (flex: 1) and block\n parents with definite dimensions (width/height: 100%). */\n flex: 1 1 auto;\n width: 100%;\n height: 100%;\n min-height: 420px;\n display: flex;\n flex-direction: column;\n background: var(--ft-bg);\n border: 1px solid var(--ft-line);\n border-radius: 2px;\n overflow: hidden;\n color: var(--ft-fg);\n font-family: var(--ft-sans);\n font-size: 14px;\n line-height: 1.5;\n -webkit-font-smoothing: antialiased;\n box-shadow: 0 30px 60px -30px oklch(0 0 0 / 0.5);\n}\n.ft-shell * { box-sizing: border-box; }\n.ft-shell .ft-mono {\n font-family: var(--ft-mono);\n font-size: 11px;\n letter-spacing: 0.02em;\n}\n\n.ft-header {\n padding: 22px 28px 20px;\n border-bottom: 1px solid var(--ft-line);\n background: linear-gradient(180deg, oklch(0.21 0.01 60) 0%, oklch(0.19 0.008 70) 100%);\n display: flex;\n flex-direction: column;\n gap: 6px;\n}\n.ft-header__eyebrow {\n font-family: var(--ft-mono);\n font-size: 10.5px;\n letter-spacing: 0.22em;\n text-transform: uppercase;\n color: var(--ft-tier-orange);\n}\n.ft-header__title {\n margin: 0;\n font-family: var(--ft-serif);\n font-weight: 400;\n font-size: 44px;\n line-height: 1;\n letter-spacing: -0.015em;\n color: var(--ft-fg);\n}\n.ft-header__tagline {\n margin: 6px 0 0;\n max-width: 76ch;\n color: var(--ft-muted-fg);\n font-size: 13px;\n}\n\n.ft-stage {\n position: relative;\n flex: 1;\n min-height: 0;\n overflow: hidden;\n background:\n radial-gradient(1200px 700px at 15% -10%, oklch(0.22 0.012 60), transparent 60%),\n radial-gradient(900px 600px at 110% 110%, oklch(0.2 0.02 200 / 0.5), transparent 65%);\n}\n\n.ft-svg {\n display: block;\n width: 100%;\n height: 100%;\n background: transparent;\n cursor: grab;\n touch-action: none;\n user-select: none;\n}\n.ft-svg.is-dragging { cursor: grabbing; }\n\n.ft-controls {\n position: absolute;\n top: 14px;\n right: 14px;\n z-index: 5;\n display: flex;\n align-items: center;\n gap: 6px;\n background: oklch(0.2 0.008 80 / 0.94);\n border: 1px solid var(--ft-line-strong);\n padding: 5px 8px;\n backdrop-filter: blur(8px);\n border-radius: 2px;\n}\n.ft-controls button {\n font-family: var(--ft-mono);\n font-size: 12px;\n width: 26px;\n height: 26px;\n background: transparent;\n border: 1px solid var(--ft-line);\n color: var(--ft-fg);\n cursor: pointer;\n padding: 0;\n}\n.ft-controls button:hover { border-color: var(--ft-tier-orange); }\n.ft-controls__reset {\n width: auto !important;\n padding: 0 10px !important;\n font-size: 9.5px !important;\n letter-spacing: 0.1em;\n text-transform: uppercase;\n}\n.ft-controls__hint {\n font-family: var(--ft-mono);\n font-size: 9.5px;\n color: var(--ft-muted-fg);\n letter-spacing: 0.04em;\n padding-left: 8px;\n margin-left: 2px;\n border-left: 1px solid var(--ft-line);\n}\n\n.ft-legend {\n position: absolute;\n left: 18px;\n bottom: 14px;\n z-index: 5;\n display: flex;\n flex-wrap: wrap;\n align-items: center;\n gap: 6px;\n font-family: var(--ft-mono);\n font-size: 10px;\n color: var(--ft-muted-fg);\n background: oklch(0.2 0.008 80 / 0.88);\n border: 1px solid var(--ft-line);\n padding: 6px 10px;\n backdrop-filter: blur(6px);\n max-width: calc(100% - 220px);\n}\n.ft-legend__chip {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n padding: 2px 6px;\n margin: -2px 0;\n background: transparent;\n border: none;\n color: inherit;\n font: inherit;\n letter-spacing: inherit;\n cursor: pointer;\n border-radius: 2px;\n transition: background 120ms, color 120ms;\n}\n.ft-legend__chip:hover {\n background: oklch(0.24 0.01 80);\n color: var(--ft-fg);\n}\n.ft-legend__chip:disabled {\n cursor: default;\n color: var(--ft-fg);\n}\n.ft-legend__chip:disabled:hover { background: transparent; }\n.ft-legend__dot {\n width: 5px;\n height: 5px;\n border-radius: 50%;\n background: var(--ft-tier-orange);\n flex-shrink: 0;\n}\n.ft-legend__sep {\n color: var(--ft-line-strong);\n margin: 0 2px;\n pointer-events: none;\n user-select: none;\n}\n\n/* edges */\n.ft-edge {\n fill: none;\n /* Keep stroke widths crisp under the SVG <g scale(z)> pan/zoom transform.\n Without this, fit-to-viewport (z \u2248 0.6-0.9) renders 1.6px strokes as\n sub-pixel and they visually disappear. */\n vector-effect: non-scaling-stroke;\n transition: stroke 260ms, opacity 260ms;\n}\n.ft-edge--off { stroke: var(--ft-line); stroke-width: 1; opacity: 0.55; }\n.ft-edge--on {\n stroke: var(--ft-tier-orange);\n /* Verbatim restore of the reference design (local-docs/styles.css\n line 133-140). The 4px dash + 5px gap reads as continuous\n marching-ant flow \u2014 every frame, dash edges visibly sweep across\n the path because the gap (5px) is shorter than the dash itself.\n This is what gives the focused branches their \"alive\" feel; the\n wider gap variants (1/12 in 1.30.1, 0.1/9 in 1.30.0) read as\n isolated dots and look static at typical fit-zoom levels. */\n stroke-width: 1.6;\n stroke-dasharray: 4 5;\n opacity: 1;\n animation: ftDashFlow 1.4s linear infinite;\n /* Visibility-under-zoom fix from 1.29.1 \u2014 without this, fit-zoom\n transforms (z \u2248 0.4-0.7) render the 1.6px stroke as sub-pixel\n and the line becomes invisible. Keeps stroke-width and\n dasharray in screen pixels regardless of the SVG transform.\n Not in the reference because the reference demo runs at z=1. */\n vector-effect: non-scaling-stroke;\n}\n@keyframes ftDashFlow {\n /* -36 == 4 \u00D7 (4+5) so the pattern advances exactly four cycles\n per period at 1.4s \u2014 perceptibly fast flow without strobing. */\n to { stroke-dashoffset: -36; }\n}\n@media (prefers-reduced-motion: reduce) {\n /* a11y improvement not in the reference \u2014 users who suppress\n motion get a clean solid line instead of a static frozen dash. */\n .ft-edge--on {\n animation: none;\n stroke-dasharray: none;\n }\n}\n\n/* card */\n.ft-card {\n --tier-local: var(--tier, var(--ft-line-strong));\n width: 100%;\n height: 100%;\n display: grid;\n grid-template-columns: 1fr auto;\n gap: 0;\n align-items: stretch;\n background: oklch(0.21 0.008 80);\n border: 1px solid var(--ft-line);\n border-left: 3px solid var(--tier-local);\n border-radius: 2px;\n transition:\n background 260ms cubic-bezier(.2,.8,.2,1),\n border-color 260ms, box-shadow 260ms,\n transform 260ms cubic-bezier(.2,.8,.2,1),\n filter 260ms, opacity 260ms, color 260ms;\n overflow: visible;\n animation: ftCardIn 320ms cubic-bezier(.2,.8,.2,1) backwards;\n}\n@keyframes ftCardIn {\n from { opacity: 0; transform: translateX(-6px); }\n to { opacity: 1; transform: translateX(0); }\n}\n.ft-card__main {\n display: grid;\n grid-template-columns: auto 1fr auto;\n gap: 10px;\n align-items: center;\n padding: 0 10px 0 12px;\n background: transparent;\n border: none;\n color: inherit;\n font-family: var(--ft-sans);\n font-size: 13px;\n text-align: left;\n cursor: pointer;\n min-width: 0;\n}\n.ft-card__main:hover { background: oklch(0.23 0.01 80 / 0.6); }\n.ft-card__icon {\n width: 24px;\n height: 24px;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n color: var(--tier-local);\n border: 1px solid var(--ft-line-strong);\n background: oklch(0.17 0.008 80);\n flex-shrink: 0;\n}\n.ft-card__body { display: flex; flex-direction: column; min-width: 0; gap: 1px; }\n.ft-card__label {\n font-family: var(--ft-serif);\n font-size: 15px;\n line-height: 1.15;\n color: var(--ft-fg);\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n display: flex;\n align-items: center;\n gap: 5px;\n}\n.ft-card__sub {\n font-family: var(--ft-mono);\n font-size: 9.5px;\n letter-spacing: 0.02em;\n color: var(--ft-muted-fg);\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n.ft-card__lock { color: var(--ft-muted-fg); display: inline-flex; }\n.ft-card__caret {\n width: 18px;\n height: 18px;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n font-family: var(--ft-mono);\n font-size: 12px;\n color: var(--ft-muted-fg);\n border: 1px solid var(--ft-line);\n}\n.ft-card--active .ft-card__caret {\n color: var(--tier-local);\n border-color: var(--tier-local);\n}\n\n.ft-card__rail {\n display: flex;\n flex-direction: column;\n border-left: 1px solid var(--ft-line);\n background: oklch(0.19 0.008 80);\n}\n.ft-card__mini {\n flex: 1;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 28px;\n min-height: 20px;\n background: transparent;\n border: none;\n color: var(--ft-muted-fg);\n cursor: pointer;\n transition: background 150ms, color 150ms;\n border-bottom: 1px solid var(--ft-line);\n padding: 0;\n text-decoration: none;\n}\n.ft-card__mini:last-child { border-bottom: none; }\n.ft-card__mini:hover { background: oklch(0.23 0.01 80); color: var(--tier-local); }\n.ft-card__mini.is-on { color: var(--tier-local); background: oklch(0.23 0.01 80); }\n\n/* states */\n.ft-card--active {\n background: oklch(0.25 0.015 60);\n box-shadow: 0 0 0 1px var(--tier-local), 0 14px 34px -16px oklch(0.5 0.18 50 / 0.55);\n transform: scale(1.02);\n}\n.ft-card--dim {\n filter: grayscale(0.85) brightness(0.82);\n opacity: 0.7;\n transform: scale(0.88);\n transform-origin: center left;\n}\n.ft-card--dim .ft-card__label { color: var(--ft-dim-fg); }\n.ft-card--dim:hover {\n filter: grayscale(0.3) brightness(0.96);\n opacity: 1;\n transform: scale(0.94);\n}\n.ft-card--cta {\n border-left-color: var(--ft-tier-orange);\n background: linear-gradient(180deg, oklch(0.23 0.02 55) 0%, oklch(0.2 0.015 60) 100%);\n}\n.ft-card--root {\n border-left-color: var(--ft-tier-orange);\n background: oklch(0.26 0.015 55);\n}\n.ft-card--root .ft-card__icon {\n color: var(--ft-tier-orange);\n border-color: var(--ft-tier-orange);\n}\n\n/* detail pop */\n.ft-detail {\n position: relative;\n margin-top: 0;\n padding: 16px 18px 14px;\n background: oklch(0.16 0.008 80);\n border: 1px solid var(--ft-line-strong);\n border-left: 2px solid var(--ft-tier-orange);\n border-radius: 3px;\n animation: ftDetailIn 220ms cubic-bezier(.2,.8,.2,1) backwards;\n color: var(--ft-fg);\n width: 320px;\n box-shadow: 0 18px 40px -8px rgba(0,0,0,0.6), 0 2px 8px rgba(0,0,0,0.4);\n}\n.ft-detail__head {\n display: flex;\n align-items: center;\n /* Clear room for the two stacked rail buttons in the top-right\n (expand + close). Bumped from 28px \u2192 58px to fit both. */\n margin: -2px 58px 10px 0;\n}\n.ft-detail__title {\n font-family: var(--ft-mono);\n font-size: 10px;\n letter-spacing: 0.14em;\n text-transform: uppercase;\n color: var(--ft-muted-fg);\n}\n.ft-detail__close,\n.ft-detail__expand {\n position: absolute;\n top: 8px;\n width: 22px;\n height: 22px;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n background: transparent;\n border: 1px solid var(--ft-line);\n border-radius: 2px;\n color: var(--ft-muted-fg);\n cursor: pointer;\n padding: 0;\n transition: color 120ms, border-color 120ms, background 120ms;\n}\n.ft-detail__close { right: 8px; }\n/* Expand button sits immediately to the left of close. */\n.ft-detail__expand { right: 36px; }\n.ft-detail__close:hover,\n.ft-detail__expand:hover {\n color: var(--ft-fg);\n border-color: var(--ft-tier-orange);\n background: oklch(0.22 0.008 80);\n}\n@keyframes ftDetailIn {\n from { opacity: 0; transform: translateY(-4px); }\n to { opacity: 1; transform: translateY(0); }\n}\n.ft-detail__lead {\n /* Inter (sans) at slightly larger size + medium weight reads\n dramatically better than serif italic on dark stages, while still\n looking distinct from the body paragraph. The orange accent\n border on the left preserves the \"pull-quote\" rhythm. */\n font-family: var(--ft-sans);\n font-size: 14.5px;\n line-height: 1.45;\n font-style: normal;\n font-weight: 500;\n color: var(--ft-fg);\n padding-left: 10px;\n border-left: 2px solid var(--ft-tier-orange);\n margin-bottom: 12px;\n}\n.ft-detail__body {\n margin: 0 0 10px;\n font-size: 12px;\n color: var(--ft-muted-fg);\n line-height: 1.5;\n}\n.ft-detail__bullets {\n margin: 0 0 10px;\n padding-left: 16px;\n font-size: 12px;\n color: var(--ft-fg);\n}\n.ft-detail__bullets li { margin-bottom: 3px; }\n.ft-detail__meta {\n margin: 0 0 10px;\n padding: 0;\n display: flex;\n flex-direction: column;\n gap: 4px;\n}\n.ft-detail__meta-row {\n display: grid;\n grid-template-columns: 96px 1fr;\n gap: 8px;\n font-size: 11px;\n}\n.ft-detail__meta-row dt {\n font-family: var(--ft-mono);\n font-size: 9.5px;\n letter-spacing: 0.1em;\n text-transform: uppercase;\n color: var(--ft-muted-fg);\n padding-top: 1px;\n}\n.ft-detail__meta-row dd { margin: 0; color: var(--ft-fg); }\n.ft-detail__actions {\n display: flex;\n gap: 6px;\n flex-wrap: wrap;\n margin-top: 8px;\n}\n\n.ft-btn {\n font-family: var(--ft-mono);\n font-size: 10px;\n letter-spacing: 0.1em;\n text-transform: uppercase;\n padding: 7px 10px;\n background: transparent;\n color: var(--ft-fg);\n border: 1px solid var(--ft-line-strong);\n text-decoration: none;\n cursor: pointer;\n display: inline-flex;\n gap: 5px;\n align-items: center;\n transition: border-color 150ms, background 150ms;\n}\n.ft-btn:hover { border-color: var(--ft-tier-orange); }\n.ft-btn--primary {\n background: var(--ft-tier-orange);\n color: oklch(0.18 0.01 50);\n border-color: var(--ft-tier-orange);\n}\n\n@media (max-width: 760px) {\n .ft-header { padding: 16px 18px 14px; }\n .ft-header__title { font-size: 32px; }\n .ft-controls__hint { display: none; }\n .ft-legend { max-width: calc(100% - 24px); left: 10px; bottom: 10px; }\n /* Larger touch targets on phones \u2014 bumps zoom controls from 26px\n to 36px to comfortably clear the 44px Apple HIG / Material 48dp\n minimum once you account for visual padding. */\n .ft-controls { padding: 6px 8px; }\n .ft-controls button { width: 36px; height: 36px; font-size: 16px; }\n .ft-controls__reset { padding: 0 14px !important; height: 36px; }\n /* Inline detail popup buttons are intentionally compact in the\n inline footprint \u2014 but on touch the user can promote to the\n fullscreen overlay which has 28px buttons by default. */\n .ft-detail__close, .ft-detail__expand { width: 28px; height: 28px; }\n .ft-detail__expand { right: 42px; }\n .ft-detail__head { margin-right: 70px; }\n}\n@media (max-width: 480px) {\n /* Phone-sized: shrink card width so 5+ depth levels still fit\n reasonably without forcing the user to scroll horizontally to\n read the labels. Cards still ellipsis-truncate when needed. */\n .ft-card { font-size: 12px; }\n .ft-card__label { font-size: 14px; }\n .ft-card__sub { font-size: 9px; }\n .ft-controls__hint { display: none; }\n}\n\n/* \u2500\u2500\u2500 Fullscreen detail overlay \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n Triggered by the expand button in any inline DetailPop. Renders\n inside .ft-stage as an absolutely-positioned scrim + scrollable\n panel. The inline pop stays mounted (cheaper React tree) but the\n user's focus and the pointer-events both transfer to the overlay\n while it's visible.\n*/\n.ft-detail-overlay {\n position: absolute;\n inset: 0;\n z-index: 20;\n display: flex;\n align-items: stretch;\n justify-content: center;\n /* Translucent backdrop blurs the flow tree behind so the focused\n content reads cleanly without losing the user's \"where am I\"\n spatial anchor. */\n background: oklch(0.12 0.008 80 / 0.78);\n backdrop-filter: blur(6px);\n animation: ftOverlayIn 200ms cubic-bezier(.2,.8,.2,1);\n}\n@keyframes ftOverlayIn {\n from { opacity: 0; }\n to { opacity: 1; }\n}\n.ft-detail-overlay__panel {\n position: relative;\n margin: 36px;\n flex: 1 1 auto;\n max-width: 760px;\n background: oklch(0.18 0.008 80);\n border: 1px solid var(--ft-line-strong);\n border-left: 3px solid var(--ft-tier-orange);\n border-radius: 4px;\n overflow: auto;\n padding: 26px 32px 28px;\n box-shadow: 0 30px 80px -10px oklch(0 0 0 / 0.7);\n animation: ftOverlayPanelIn 240ms cubic-bezier(.2,.8,.2,1);\n}\n@keyframes ftOverlayPanelIn {\n from { opacity: 0; transform: translateY(8px); }\n to { opacity: 1; transform: translateY(0); }\n}\n.ft-detail-overlay__panel .ft-detail__title {\n font-size: 11px;\n}\n.ft-detail-overlay__panel .ft-detail__lead {\n font-size: 18px;\n line-height: 1.5;\n padding-left: 14px;\n}\n.ft-detail-overlay__panel .ft-detail__body {\n font-size: 14px;\n color: var(--ft-fg);\n line-height: 1.65;\n}\n.ft-detail-overlay__panel .ft-detail__bullets {\n font-size: 14px;\n line-height: 1.55;\n padding-left: 20px;\n}\n.ft-detail-overlay__panel .ft-detail__bullets li { margin-bottom: 6px; }\n.ft-detail-overlay__panel .ft-detail__meta-row {\n font-size: 13px;\n grid-template-columns: 140px 1fr;\n}\n.ft-detail-overlay__panel .ft-detail__meta-row dt { font-size: 10.5px; }\n.ft-detail-overlay__panel .ft-btn { font-size: 11px; padding: 9px 14px; }\n.ft-detail-overlay__head {\n display: flex;\n align-items: center;\n margin: 0 0 14px;\n padding-right: 70px;\n}\n.ft-detail-overlay__title {\n font-family: var(--ft-mono);\n font-size: 11px;\n letter-spacing: 0.18em;\n text-transform: uppercase;\n color: var(--ft-tier-orange);\n}\n.ft-detail-overlay__close,\n.ft-detail-overlay__collapse {\n position: absolute;\n top: 16px;\n width: 28px;\n height: 28px;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n background: transparent;\n border: 1px solid var(--ft-line-strong);\n border-radius: 2px;\n color: var(--ft-fg);\n cursor: pointer;\n padding: 0;\n transition: color 120ms, border-color 120ms, background 120ms;\n}\n.ft-detail-overlay__close { right: 16px; }\n.ft-detail-overlay__collapse { right: 52px; }\n.ft-detail-overlay__close:hover,\n.ft-detail-overlay__collapse:hover {\n color: var(--ft-tier-orange);\n border-color: var(--ft-tier-orange);\n background: oklch(0.22 0.008 80);\n}\n\n@media (max-width: 760px) {\n .ft-detail-overlay__panel {\n margin: 12px;\n padding: 18px 18px 22px;\n }\n .ft-detail-overlay__panel .ft-detail__lead { font-size: 16px; }\n}\n";
|
|
5297
5297
|
|
|
5298
5298
|
type GameTimerMode = "countdown" | "countup";
|
|
5299
5299
|
type GameTimerThemePreset = "green" | "red" | "blue" | "amber" | "purple" | "pink" | "teal";
|
package/dist/index.js
CHANGED
|
@@ -35500,15 +35500,7 @@ var PATHS = {
|
|
|
35500
35500
|
)
|
|
35501
35501
|
] }),
|
|
35502
35502
|
seedling: /* @__PURE__ */ (0, import_jsx_runtime119.jsxs)(import_jsx_runtime119.Fragment, { children: [
|
|
35503
|
-
/* @__PURE__ */ (0, import_jsx_runtime119.jsx)(
|
|
35504
|
-
"path",
|
|
35505
|
-
{
|
|
35506
|
-
d: "M8 14 v-5",
|
|
35507
|
-
fill: "none",
|
|
35508
|
-
stroke: "currentColor",
|
|
35509
|
-
strokeWidth: "1.2"
|
|
35510
|
-
}
|
|
35511
|
-
),
|
|
35503
|
+
/* @__PURE__ */ (0, import_jsx_runtime119.jsx)("path", { d: "M8 14 v-5", fill: "none", stroke: "currentColor", strokeWidth: "1.2" }),
|
|
35512
35504
|
/* @__PURE__ */ (0, import_jsx_runtime119.jsx)(
|
|
35513
35505
|
"path",
|
|
35514
35506
|
{
|
|
@@ -35662,24 +35654,8 @@ var PATHS = {
|
|
|
35662
35654
|
strokeWidth: "1.2"
|
|
35663
35655
|
}
|
|
35664
35656
|
),
|
|
35665
|
-
/* @__PURE__ */ (0, import_jsx_runtime119.jsx)(
|
|
35666
|
-
|
|
35667
|
-
{
|
|
35668
|
-
d: "M9 5 v6",
|
|
35669
|
-
fill: "none",
|
|
35670
|
-
stroke: "currentColor",
|
|
35671
|
-
strokeWidth: "1.2"
|
|
35672
|
-
}
|
|
35673
|
-
),
|
|
35674
|
-
/* @__PURE__ */ (0, import_jsx_runtime119.jsx)(
|
|
35675
|
-
"path",
|
|
35676
|
-
{
|
|
35677
|
-
d: "M9 8 h4",
|
|
35678
|
-
fill: "none",
|
|
35679
|
-
stroke: "currentColor",
|
|
35680
|
-
strokeWidth: "1.2"
|
|
35681
|
-
}
|
|
35682
|
-
)
|
|
35657
|
+
/* @__PURE__ */ (0, import_jsx_runtime119.jsx)("path", { d: "M9 5 v6", fill: "none", stroke: "currentColor", strokeWidth: "1.2" }),
|
|
35658
|
+
/* @__PURE__ */ (0, import_jsx_runtime119.jsx)("path", { d: "M9 8 h4", fill: "none", stroke: "currentColor", strokeWidth: "1.2" })
|
|
35683
35659
|
] }),
|
|
35684
35660
|
score: /* @__PURE__ */ (0, import_jsx_runtime119.jsxs)(import_jsx_runtime119.Fragment, { children: [
|
|
35685
35661
|
/* @__PURE__ */ (0, import_jsx_runtime119.jsx)(
|
|
@@ -36124,50 +36100,34 @@ var FLOW_TREE_CSS = `
|
|
|
36124
36100
|
.ft-edge--off { stroke: var(--ft-line); stroke-width: 1; opacity: 0.55; }
|
|
36125
36101
|
.ft-edge--on {
|
|
36126
36102
|
stroke: var(--ft-tier-orange);
|
|
36127
|
-
/*
|
|
36128
|
-
|
|
36129
|
-
|
|
36130
|
-
|
|
36131
|
-
|
|
36132
|
-
|
|
36133
|
-
|
|
36134
|
-
|
|
36135
|
-
|
|
36136
|
-
1.30.0 was below subpixel-antialiasing threshold in some
|
|
36137
|
-
renderers (particularly Chromium under fit-to-viewport zoom) and
|
|
36138
|
-
the dashes disappeared entirely \u2014 leaving the line visually
|
|
36139
|
-
"plain". 1px is the minimum value every browser renders. */
|
|
36140
|
-
stroke-dasharray: 1 12;
|
|
36103
|
+
/* Verbatim restore of the reference design (local-docs/styles.css
|
|
36104
|
+
line 133-140). The 4px dash + 5px gap reads as continuous
|
|
36105
|
+
marching-ant flow \u2014 every frame, dash edges visibly sweep across
|
|
36106
|
+
the path because the gap (5px) is shorter than the dash itself.
|
|
36107
|
+
This is what gives the focused branches their "alive" feel; the
|
|
36108
|
+
wider gap variants (1/12 in 1.30.1, 0.1/9 in 1.30.0) read as
|
|
36109
|
+
isolated dots and look static at typical fit-zoom levels. */
|
|
36110
|
+
stroke-width: 1.6;
|
|
36111
|
+
stroke-dasharray: 4 5;
|
|
36141
36112
|
opacity: 1;
|
|
36142
|
-
/* Drop-shadow drops a tier-tinted glow under the line. Cheap on
|
|
36143
|
-
desktop, slightly more expensive on mobile GPUs but well within
|
|
36144
|
-
budget for the handful of paths we render at once. */
|
|
36145
|
-
filter: drop-shadow(0 0 5px oklch(0.7 0.18 50 / 0.55));
|
|
36146
|
-
/* Animate stroke-dashoffset so beads visibly travel along the
|
|
36147
|
-
path. Speed tuned to ~30px/s on a typical card connector \u2014 fast
|
|
36148
|
-
enough to read as motion without becoming distracting. */
|
|
36149
36113
|
animation: ftDashFlow 1.4s linear infinite;
|
|
36150
|
-
/*
|
|
36151
|
-
transforms \
|
|
36152
|
-
|
|
36114
|
+
/* Visibility-under-zoom fix from 1.29.1 \u2014 without this, fit-zoom
|
|
36115
|
+
transforms (z \u2248 0.4-0.7) render the 1.6px stroke as sub-pixel
|
|
36116
|
+
and the line becomes invisible. Keeps stroke-width and
|
|
36117
|
+
dasharray in screen pixels regardless of the SVG transform.
|
|
36118
|
+
Not in the reference because the reference demo runs at z=1. */
|
|
36153
36119
|
vector-effect: non-scaling-stroke;
|
|
36154
36120
|
}
|
|
36155
|
-
.ft-edge--on.ft-edge--solid {
|
|
36156
|
-
/* Fallback for any consumer that explicitly opts out of the bead
|
|
36157
|
-
pattern \u2014 keeps the legacy solid orange line. */
|
|
36158
|
-
stroke-dasharray: none;
|
|
36159
|
-
animation: none;
|
|
36160
|
-
}
|
|
36161
36121
|
@keyframes ftDashFlow {
|
|
36162
|
-
/* -
|
|
36163
|
-
|
|
36164
|
-
to { stroke-dashoffset: -
|
|
36122
|
+
/* -36 == 4 \xD7 (4+5) so the pattern advances exactly four cycles
|
|
36123
|
+
per period at 1.4s \u2014 perceptibly fast flow without strobing. */
|
|
36124
|
+
to { stroke-dashoffset: -36; }
|
|
36165
36125
|
}
|
|
36166
36126
|
@media (prefers-reduced-motion: reduce) {
|
|
36127
|
+
/* a11y improvement not in the reference \u2014 users who suppress
|
|
36128
|
+
motion get a clean solid line instead of a static frozen dash. */
|
|
36167
36129
|
.ft-edge--on {
|
|
36168
36130
|
animation: none;
|
|
36169
|
-
/* When motion is suppressed, drop the dot pattern too so users
|
|
36170
|
-
see a clean solid line instead of a static frozen dash. */
|
|
36171
36131
|
stroke-dasharray: none;
|
|
36172
36132
|
}
|
|
36173
36133
|
}
|