@loworbitstudio/visor 1.18.1 → 1.19.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/CHANGELOG.json +1 -1
- package/dist/index.js +145 -31
- package/dist/registry.json +29 -29
- package/dist/visor-manifest.json +2 -1
- package/package.json +2 -2
package/dist/registry.json
CHANGED
|
@@ -96,7 +96,7 @@
|
|
|
96
96
|
{
|
|
97
97
|
"path": "components/ui/text/text.module.css",
|
|
98
98
|
"type": "registry:ui",
|
|
99
|
-
"content": "/* Text base styles */\n.base {\n font-family: var(--font-body,
|
|
99
|
+
"content": "/* Text base styles */\n.base {\n font-family: var(--font-body, inherit);\n margin: 0;\n}\n\n/* Sizes */\n.sizeXs {\n font-size: var(--font-size-xs, 0.75rem);\n}\n\n.sizeSm {\n font-size: var(--font-size-sm, 0.875rem);\n}\n\n.sizeMd {\n font-size: var(--font-size-base, 1rem);\n}\n\n.sizeLg {\n font-size: var(--font-size-lg, 1.125rem);\n}\n\n.sizeXl {\n font-size: var(--font-size-xl, 1.25rem);\n}\n\n/* Weights */\n.weightNormal {\n font-weight: var(--font-weight-normal, 400);\n}\n\n.weightMedium {\n font-weight: var(--font-weight-medium, 500);\n}\n\n.weightSemibold {\n font-weight: var(--font-weight-semibold, 600);\n}\n\n.weightBold {\n font-weight: var(--font-weight-bold, 700);\n}\n\n/* Colors */\n.colorPrimary {\n color: var(--text-primary, #111827);\n}\n\n.colorSecondary {\n color: var(--text-secondary, #6b7280);\n}\n\n.colorTertiary {\n color: var(--text-tertiary, #9ca3af);\n}\n\n.colorInherit {\n color: inherit;\n}\n\n/* Line height */\n.leadingTight {\n line-height: var(--line-height-tight, 1.25);\n}\n\n.leadingSnug {\n line-height: var(--line-height-snug, 1.375);\n}\n\n.leadingNormal {\n line-height: var(--line-height-normal, 1.5);\n}\n\n.leadingRelaxed {\n line-height: var(--line-height-relaxed, 1.625);\n}\n\n.leadingLoose {\n line-height: var(--line-height-loose, 2);\n}\n"
|
|
100
100
|
}
|
|
101
101
|
]
|
|
102
102
|
},
|
|
@@ -146,7 +146,7 @@
|
|
|
146
146
|
{
|
|
147
147
|
"path": "components/ui/button/button.module.css",
|
|
148
148
|
"type": "registry:ui",
|
|
149
|
-
"content": "/* Button base styles */\n.base {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n gap: var(--spacing-2, 0.5rem);\n white-space: nowrap;\n border-radius: var(--radius-md, 0.375rem);\n font-size: var(--font-size-sm, 0.875rem);\n font-weight: var(--font-weight-medium, 500);\n line-height: 1;\n cursor: pointer;\n border: 1px solid transparent;\n transition: background-color var(--motion-duration-150, 150ms) var(--motion-easing-default, ease-in-out), color var(--motion-duration-150, 150ms) var(--motion-easing-default, ease-in-out), border-color var(--motion-duration-150, 150ms) var(--motion-easing-default, ease-in-out), opacity var(--motion-duration-150, 150ms) var(--motion-easing-default, ease-in-out), transform var(--motion-duration-150, 150ms) var(--motion-easing-default, ease-in-out);\n text-decoration: none;\n outline: none;\n}\n\n.base:focus-visible {\n outline: var(--focus-ring-width, 2px) solid var(--border-focus, currentColor);\n outline-offset: var(--focus-ring-offset, 2px);\n}\n\n.base:active:not(:disabled) {\n transform: translateY(1px);\n transition: none;\n}\n\n.base:disabled {\n pointer-events: none;\n opacity: 0.5;\n}\n\n/* Variants */\n.variantDefault {\n background-color: var(--interactive-primary-bg, var(--primary, #111827));\n color: var(--interactive-primary-text, #f9fafb);\n}\n\n.variantSecondary {\n background-color: var(--interactive-secondary-bg, #f3f4f6);\n color: var(--interactive-secondary-text, #111827);\n}\n\n/* Editorial density: secondary on the card tier, ghost truly transparent.\n * Direct values — the editorial design language owns control surfaces, so the\n * theme's --interactive-secondary-bg / --interactive-ghost-bg are deliberately\n * bypassed (matches the blessed overlay, which out-cascaded the palette). */\n:global([data-density=\"editorial\"]) .variantSecondary {\n background-color: var(--surface-card, #ffffff);\n}\n\n:global([data-density=\"editorial\"]) .variantGhost {\n background-color: transparent;\n}\n\n.variantOutline {\n background-color: transparent;\n color: var(--text-primary, #111827);\n border-color: var(--border-strong, #e5e7eb);\n}\n\n.variantGhost {\n background-color: var(--interactive-ghost-bg, transparent);\n color: var(--text-primary, #111827);\n}\n\n.variantDestructive {\n background-color: var(--interactive-destructive-bg, #ef4444);\n color: var(--interactive-destructive-text, #fef2f2);\n}\n\n@media (hover: hover) {\n .variantDefault:hover {\n background-color: var(--interactive-primary-bg-hover, #1f2937);\n }\n\n .variantSecondary:hover {\n background-color: var(--interactive-secondary-bg-hover, #e5e7eb);\n }\n\n .variantOutline:hover {\n background-color: var(--surface-muted, #f3f4f6);\n }\n\n .variantGhost:hover {\n background-color: var(--interactive-ghost-bg-hover, var(--surface-muted, #f3f4f6));\n }\n\n .variantDestructive:hover {\n background-color: var(--interactive-destructive-bg-hover, #dc2626);\n }\n}\n\n/* Open / active state — ghost variant only. OPT-IN, strictly additive.\n A ghost Button reads as \"held\" while its popover/menu is open so the\n trigger no longer needs an inline style. Three opt-in triggers, all\n resolving to the same held look:\n - data-state=\"open\" — forwarded automatically by Radix when the\n Button is the trigger via <Trigger asChild> (Popover/DropdownMenu).\n - data-active=\"true\" — manual non-Radix triggers (mirrors the\n sidebar `data-active` convention).\n - .isActive — className opt-in (mirrors sidebar/section-nav).\n Default ghost rendering is untouched: none of these match unless a\n consumer explicitly sets them. Matches the prototype-overlay held look:\n background var(--surface-subtle), color var(--text-primary). */\n.variantGhost[data-state=\"open\"],\n.variantGhost[data-active=\"true\"],\n.variantGhost.isActive {\n background-color: var(--surface-subtle, var(--surface-muted, #f3f4f6));\n color: var(--text-primary, #111827);\n}\n\n/* Gated state — orthogonal to variant, works with all variants */\n.base[data-gated=\"true\"] {\n opacity: var(--opacity-40, 0.4);\n cursor: not-allowed;\n border-color: var(--border-default, #e5e7eb);\n}\n\n/* Editorial density: gated reads like plain disabled (the blessed admin\n builds render gated actions at the 0.5 disabled opacity). */\n:global([data-density=\"editorial\"]) .base[data-gated=\"true\"] {\n opacity: 0.5;\n}\n\n/* Suppress active transform when gated */\n.base[data-gated=\"true\"]:active {\n transform: none;\n transition: opacity var(--motion-duration-150, 150ms) var(--motion-easing-default, ease-in-out);\n}\n\n/* Sizes\n Default (no data-density attr) rendering is byte-identical to the prior\n canonical values. Under data-density=\"editorial\" (set on any ancestor,\n typically the app root), the editorial density axis re-drives specific\n metrics to the blessed admin values. */\n.sizeSm {\n height: 2rem;\n padding: 0 var(--spacing-3, 0.75rem);\n font-size: var(--font-size-xs, 0.75rem);\n}\n\n.sizeMd {\n height: 2.5rem;\n padding: 0 var(--spacing-4, 1rem);\n line-height: 1;\n}\n\n:global([data-density=\"editorial\"]) .sizeSm {\n font-size: 0.8125rem;\n}\n\n:global([data-density=\"editorial\"]) .sizeMd {\n height: 2.125rem;\n line-height: normal;\n}\n\n.sizeLg {\n height: 3rem;\n padding: 0 var(--spacing-6, 1.5rem);\n font-size: var(--font-size-base, 1rem);\n}\n
|
|
149
|
+
"content": "/* Button base styles */\n.base {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n gap: var(--spacing-2, 0.5rem);\n white-space: nowrap;\n border-radius: var(--radius-md, 0.375rem);\n font-size: var(--font-size-sm, 0.875rem);\n font-weight: var(--font-weight-medium, 500);\n line-height: 1;\n cursor: pointer;\n border: 1px solid transparent;\n transition: background-color var(--motion-duration-150, 150ms) var(--motion-easing-default, ease-in-out), color var(--motion-duration-150, 150ms) var(--motion-easing-default, ease-in-out), border-color var(--motion-duration-150, 150ms) var(--motion-easing-default, ease-in-out), opacity var(--motion-duration-150, 150ms) var(--motion-easing-default, ease-in-out), transform var(--motion-duration-150, 150ms) var(--motion-easing-default, ease-in-out);\n text-decoration: none;\n outline: none;\n}\n\n.base:focus-visible {\n outline: var(--focus-ring-width, 2px) solid var(--border-focus, currentColor);\n outline-offset: var(--focus-ring-offset, 2px);\n}\n\n.base:active:not(:disabled) {\n transform: translateY(1px);\n transition: none;\n}\n\n.base:disabled {\n pointer-events: none;\n opacity: 0.5;\n}\n\n/* Variants */\n.variantDefault {\n background-color: var(--interactive-primary-bg, var(--primary, #111827));\n color: var(--interactive-primary-text, #f9fafb);\n}\n\n.variantSecondary {\n background-color: var(--interactive-secondary-bg, #f3f4f6);\n color: var(--interactive-secondary-text, #111827);\n}\n\n/* Editorial density: secondary on the card tier, ghost truly transparent.\n * Direct values — the editorial design language owns control surfaces, so the\n * theme's --interactive-secondary-bg / --interactive-ghost-bg are deliberately\n * bypassed (matches the blessed overlay, which out-cascaded the palette). */\n:global([data-density=\"editorial\"]) .variantSecondary {\n background-color: var(--surface-card, #ffffff);\n}\n\n:global([data-density=\"editorial\"]) .variantGhost {\n background-color: transparent;\n}\n\n.variantOutline {\n background-color: transparent;\n color: var(--text-primary, #111827);\n border-color: var(--border-strong, #e5e7eb);\n}\n\n.variantGhost {\n background-color: var(--interactive-ghost-bg, transparent);\n color: var(--text-primary, #111827);\n}\n\n.variantDestructive {\n background-color: var(--interactive-destructive-bg, #ef4444);\n color: var(--interactive-destructive-text, #fef2f2);\n}\n\n@media (hover: hover) {\n .variantDefault:hover {\n background-color: var(--interactive-primary-bg-hover, #1f2937);\n }\n\n .variantSecondary:hover {\n background-color: var(--interactive-secondary-bg-hover, #e5e7eb);\n }\n\n .variantOutline:hover {\n background-color: var(--surface-muted, #f3f4f6);\n }\n\n .variantGhost:hover {\n background-color: var(--interactive-ghost-bg-hover, var(--surface-muted, #f3f4f6));\n }\n\n .variantDestructive:hover {\n background-color: var(--interactive-destructive-bg-hover, #dc2626);\n }\n}\n\n/* Open / active state — ghost variant only. OPT-IN, strictly additive.\n A ghost Button reads as \"held\" while its popover/menu is open so the\n trigger no longer needs an inline style. Three opt-in triggers, all\n resolving to the same held look:\n - data-state=\"open\" — forwarded automatically by Radix when the\n Button is the trigger via <Trigger asChild> (Popover/DropdownMenu).\n - data-active=\"true\" — manual non-Radix triggers (mirrors the\n sidebar `data-active` convention).\n - .isActive — className opt-in (mirrors sidebar/section-nav).\n Default ghost rendering is untouched: none of these match unless a\n consumer explicitly sets them. Matches the prototype-overlay held look:\n background var(--surface-subtle), color var(--text-primary). */\n.variantGhost[data-state=\"open\"],\n.variantGhost[data-active=\"true\"],\n.variantGhost.isActive {\n background-color: var(--surface-subtle, var(--surface-muted, #f3f4f6));\n color: var(--text-primary, #111827);\n}\n\n/* Gated state — orthogonal to variant, works with all variants */\n.base[data-gated=\"true\"] {\n opacity: var(--opacity-40, 0.4);\n cursor: not-allowed;\n border-color: var(--border-default, #e5e7eb);\n}\n\n/* Editorial density: gated reads like plain disabled (the blessed admin\n builds render gated actions at the 0.5 disabled opacity). */\n:global([data-density=\"editorial\"]) .base[data-gated=\"true\"] {\n opacity: 0.5;\n}\n\n/* Suppress active transform when gated */\n.base[data-gated=\"true\"]:active {\n transform: none;\n transition: opacity var(--motion-duration-150, 150ms) var(--motion-easing-default, ease-in-out);\n}\n\n/* Sizes\n Default (no data-density attr) rendering is byte-identical to the prior\n canonical values. Under data-density=\"editorial\" (set on any ancestor,\n typically the app root), the editorial density axis re-drives specific\n metrics to the blessed admin values. */\n.sizeSm {\n height: 2rem;\n padding: 0 var(--spacing-3, 0.75rem);\n font-size: var(--font-size-xs, 0.75rem);\n}\n\n.sizeMd {\n height: 2.5rem;\n padding: 0 var(--spacing-4, 1rem);\n line-height: 1;\n}\n\n:global([data-density=\"editorial\"]) .sizeSm {\n font-size: 0.8125rem;\n}\n\n:global([data-density=\"editorial\"]) .sizeMd {\n height: 2.125rem;\n line-height: normal;\n}\n\n.sizeLg {\n height: 3rem;\n padding: 0 var(--spacing-6, 1.5rem);\n font-size: var(--font-size-base, 1rem);\n}\n"
|
|
150
150
|
}
|
|
151
151
|
]
|
|
152
152
|
},
|
|
@@ -172,7 +172,7 @@
|
|
|
172
172
|
{
|
|
173
173
|
"path": "components/ui/input/input.module.css",
|
|
174
174
|
"type": "registry:ui",
|
|
175
|
-
"content": "/* Input base styles */\n.base {\n width: 100%;\n min-width: 0;\n border: 1px solid var(--input-border, var(--border-default, #e5e7eb));\n /* --field-control-bg is the shared \"what surface does a form control sit on\"\n role. It defaults to var(--input-bg), so default inputs are unchanged. A\n form context (for example an in-dialog wrapper) can set --field-control-bg:\n var(--surface-subtle) to lift controls onto a different surface without a\n per-component prop. Under data-density=\"editorial\", the fallback chain\n defaults to var(--surface-card) while still honoring any scoped\n --field-control-bg override from a form context. */\n background-color: var(--field-control-bg, var(--input-bg, var(--surface-interactive-default, #f9fafb)));\n line-height: 1.5;\n color: var(--text-primary, #111827);\n transition: border-color var(--motion-duration-150, 150ms) var(--motion-easing-default, ease-in-out), box-shadow var(--motion-duration-150, 150ms) var(--motion-easing-default, ease-in-out);\n outline: none;\n}\n\n:global([data-density=\"editorial\"]) .base {\n background-color: var(--field-control-bg, var(--surface-card));\n}\n\n.base::placeholder {\n color: var(--input-placeholder-color, var(--text-secondary, #9ca3af));\n}\n\n@media (hover: hover) {\n .base:hover:not(:focus-visible):not(:disabled):not([aria-invalid=\"true\"]) {\n border-color: var(--border-strong, #d1d5db);\n }\n}\n\n.base:focus-visible {\n border-color: var(--border-focus, #111827);\n box-shadow: 0 0 0 var(--focus-ring-width, 2px) color-mix(in srgb, var(--border-focus, #111827) 15%, transparent);\n}\n\n.base:disabled {\n pointer-events: none;\n cursor: not-allowed;\n opacity: 0.5;\n}\n\n.base[aria-invalid=\"true\"] {\n border-color: transparent;\n background-color: var(--input-bg-invalid, var(--surface-error-subtle, color-mix(in srgb, var(--border-error, #ef4444) 6%, var(--field-control-bg, var(--input-bg, #f9fafb)))));\n box-shadow: inset 0 0 0 1.5px var(--border-error, #ef4444);\n}\n\n:global([data-density=\"editorial\"]) .base[aria-invalid=\"true\"] {\n background-color: var(--input-bg-invalid, var(--surface-error-subtle, color-mix(in srgb, var(--border-error, #ef4444) 6%, var(--field-control-bg, var(--surface-card)))));\n}\n\n.base[aria-invalid=\"true\"]:focus-visible {\n border-color: transparent;\n outline-offset: var(--focus-ring-offset, 2px);\n box-shadow: inset 0 0 0 1.5px var(--border-error, #ef4444),\n 0 0 0 var(--focus-ring-width, 2px) color-mix(in srgb, var(--border-error, #ef4444) 30%, transparent);\n}\n\n/* File input styles */\n.base[type=\"file\"] {\n font-size: var(--font-size-sm, 0.875rem);\n}\n\n/* Leading-icon wrapper\n *\n * When the consumer passes a leadingIcon node, Input wraps its <input> in a\n * <span> and positions the icon absolutely inside it. The <input> itself\n * picks up .hasLeadingIcon, which adds enough left padding to clear the\n * icon (sized in em so it scales with the field's font-size). */\n.leadingIconWrapper {\n position: relative;\n display: flex;\n align-items: center;\n width: 100%;\n min-width: 0;\n}\n\n.leadingIcon {\n position: absolute;\n left: var(--spacing-3, 0.75rem);\n top: 50%;\n transform: translateY(-50%);\n display: inline-flex;\n align-items: center;\n justify-content: center;\n color: var(--text-secondary, #9ca3af);\n pointer-events: none;\n font-size: 1.125em;\n line-height: 1;\n}\n\n/* Size variants\n *\n * Default rendering uses canonical values directly. Under data-density=\"editorial\"\n * (set on any ancestor), the editorial density axis bakes in the blessed admin\n * values — sm inputs at 33.5px height with --radius-md corners. Padding and the\n * md/lg sizes are not driven by the editorial treatment and remain canonical. */\n.sizeSm {\n height: 2.25rem;\n padding: var(--input-padding-sm, var(--spacing-1, 0.25rem) var(--spacing-3, 0.75rem));\n font-size: var(--font-size-sm, 0.875rem);\n border-radius: var(--radius-sm, 0.25rem);\n}\n\n:global([data-density=\"editorial\"]) .sizeSm {\n height: 33.5px;\n border-radius: var(--radius-md);\n}\n\n.sizeMd {\n height: var(--input-height-md, auto);\n padding: var(--input-padding-md, var(--spacing-3_5, 0.875rem) var(--spacing-4, 1rem));\n font-size: var(--font-size-sm, 0.875rem);\n border-radius: var(--input-radius-md, var(--radius-sm, 0.5rem));\n}\n\n.sizeLg {\n height: var(--input-height-lg, auto);\n padding: var(--input-padding-lg, var(--spacing-4_5, 1.125rem) var(--spacing-5, 1.25rem));\n font-size: var(--font-size-base, 1rem);\n border-radius: var(--input-radius-lg, var(--radius-sm, 0.5rem));\n}\n\n/* Leading-icon left-padding override.\n *\n * Declared AFTER the size variants so the padding-left value wins the\n * cascade against the shorthand `padding` each size sets. Double-class\n * selector bumps specificity above the size classes for good measure. */\n.sizeSm.hasLeadingIcon {\n padding-left: calc(var(--spacing-3, 0.75rem) * 2 + 1.125em);\n}\n\n.sizeMd.hasLeadingIcon {\n padding-left: calc(var(--spacing-4, 1rem) + var(--spacing-3, 0.75rem) + 1.125em);\n}\n\n.sizeLg.hasLeadingIcon {\n padding-left: calc(var(--spacing-5, 1.25rem) + var(--spacing-3, 0.75rem) + 1.125em);\n}\n
|
|
175
|
+
"content": "/* Input base styles */\n.base {\n width: 100%;\n min-width: 0;\n border: 1px solid var(--input-border, var(--border-default, #e5e7eb));\n /* --field-control-bg is the shared \"what surface does a form control sit on\"\n role. It defaults to var(--input-bg), so default inputs are unchanged. A\n form context (for example an in-dialog wrapper) can set --field-control-bg:\n var(--surface-subtle) to lift controls onto a different surface without a\n per-component prop. Under data-density=\"editorial\", the fallback chain\n defaults to var(--surface-card) while still honoring any scoped\n --field-control-bg override from a form context. */\n background-color: var(--field-control-bg, var(--input-bg, var(--surface-interactive-default, #f9fafb)));\n line-height: 1.5;\n color: var(--text-primary, #111827);\n transition: border-color var(--motion-duration-150, 150ms) var(--motion-easing-default, ease-in-out), box-shadow var(--motion-duration-150, 150ms) var(--motion-easing-default, ease-in-out);\n outline: none;\n}\n\n:global([data-density=\"editorial\"]) .base {\n background-color: var(--field-control-bg, var(--surface-card));\n}\n\n.base::placeholder {\n color: var(--input-placeholder-color, var(--text-secondary, #9ca3af));\n}\n\n@media (hover: hover) {\n .base:hover:not(:focus-visible):not(:disabled):not([aria-invalid=\"true\"]) {\n border-color: var(--border-strong, #d1d5db);\n }\n}\n\n.base:focus-visible {\n border-color: var(--border-focus, #111827);\n box-shadow: 0 0 0 var(--focus-ring-width, 2px) color-mix(in srgb, var(--border-focus, #111827) 15%, transparent);\n}\n\n.base:disabled {\n pointer-events: none;\n cursor: not-allowed;\n opacity: 0.5;\n}\n\n.base[aria-invalid=\"true\"] {\n border-color: transparent;\n background-color: var(--input-bg-invalid, var(--surface-error-subtle, color-mix(in srgb, var(--border-error, #ef4444) 6%, var(--field-control-bg, var(--input-bg, #f9fafb)))));\n box-shadow: inset 0 0 0 1.5px var(--border-error, #ef4444);\n}\n\n:global([data-density=\"editorial\"]) .base[aria-invalid=\"true\"] {\n background-color: var(--input-bg-invalid, var(--surface-error-subtle, color-mix(in srgb, var(--border-error, #ef4444) 6%, var(--field-control-bg, var(--surface-card)))));\n}\n\n.base[aria-invalid=\"true\"]:focus-visible {\n border-color: transparent;\n outline-offset: var(--focus-ring-offset, 2px);\n box-shadow: inset 0 0 0 1.5px var(--border-error, #ef4444),\n 0 0 0 var(--focus-ring-width, 2px) color-mix(in srgb, var(--border-error, #ef4444) 30%, transparent);\n}\n\n/* File input styles */\n.base[type=\"file\"] {\n font-size: var(--font-size-sm, 0.875rem);\n}\n\n/* Leading-icon wrapper\n *\n * When the consumer passes a leadingIcon node, Input wraps its <input> in a\n * <span> and positions the icon absolutely inside it. The <input> itself\n * picks up .hasLeadingIcon, which adds enough left padding to clear the\n * icon (sized in em so it scales with the field's font-size). */\n.leadingIconWrapper {\n position: relative;\n display: flex;\n align-items: center;\n width: 100%;\n min-width: 0;\n}\n\n.leadingIcon {\n position: absolute;\n left: var(--spacing-3, 0.75rem);\n top: 50%;\n transform: translateY(-50%);\n display: inline-flex;\n align-items: center;\n justify-content: center;\n color: var(--text-secondary, #9ca3af);\n pointer-events: none;\n font-size: 1.125em;\n line-height: 1;\n}\n\n/* Size variants\n *\n * Default rendering uses canonical values directly. Under data-density=\"editorial\"\n * (set on any ancestor), the editorial density axis bakes in the blessed admin\n * values — sm inputs at 33.5px height with --radius-md corners. Padding and the\n * md/lg sizes are not driven by the editorial treatment and remain canonical. */\n.sizeSm {\n height: 2.25rem;\n padding: var(--input-padding-sm, var(--spacing-1, 0.25rem) var(--spacing-3, 0.75rem));\n font-size: var(--font-size-sm, 0.875rem);\n border-radius: var(--radius-sm, 0.25rem);\n}\n\n:global([data-density=\"editorial\"]) .sizeSm {\n height: 33.5px;\n border-radius: var(--radius-md);\n}\n\n.sizeMd {\n height: var(--input-height-md, auto);\n padding: var(--input-padding-md, var(--spacing-3_5, 0.875rem) var(--spacing-4, 1rem));\n font-size: var(--font-size-sm, 0.875rem);\n border-radius: var(--input-radius-md, var(--radius-sm, 0.5rem));\n}\n\n.sizeLg {\n height: var(--input-height-lg, auto);\n padding: var(--input-padding-lg, var(--spacing-4_5, 1.125rem) var(--spacing-5, 1.25rem));\n font-size: var(--font-size-base, 1rem);\n border-radius: var(--input-radius-lg, var(--radius-sm, 0.5rem));\n}\n\n/* Leading-icon left-padding override.\n *\n * Declared AFTER the size variants so the padding-left value wins the\n * cascade against the shorthand `padding` each size sets. Double-class\n * selector bumps specificity above the size classes for good measure. */\n.sizeSm.hasLeadingIcon {\n padding-left: calc(var(--spacing-3, 0.75rem) * 2 + 1.125em);\n}\n\n.sizeMd.hasLeadingIcon {\n padding-left: calc(var(--spacing-4, 1rem) + var(--spacing-3, 0.75rem) + 1.125em);\n}\n\n.sizeLg.hasLeadingIcon {\n padding-left: calc(var(--spacing-5, 1.25rem) + var(--spacing-3, 0.75rem) + 1.125em);\n}\n"
|
|
176
176
|
}
|
|
177
177
|
]
|
|
178
178
|
},
|
|
@@ -223,7 +223,7 @@
|
|
|
223
223
|
{
|
|
224
224
|
"path": "components/ui/textarea/textarea.module.css",
|
|
225
225
|
"type": "registry:ui",
|
|
226
|
-
"content": "/* Textarea base styles */\n.base {\n display: flex;\n width: 100%;\n resize: none;\n border: 1px solid var(--textarea-border, var(--border-default, #e5e7eb));\n background-color: var(--textarea-bg, var(--surface-interactive-default, #f9fafb));\n line-height: 1.5;\n color: var(--text-primary, #111827);\n transition: border-color var(--motion-duration-150, 150ms) var(--motion-easing-default, ease-in-out), box-shadow var(--motion-duration-150, 150ms) var(--motion-easing-default, ease-in-out);\n outline: none;\n
|
|
226
|
+
"content": "/* Textarea base styles */\n.base {\n display: flex;\n width: 100%;\n resize: none;\n border: 1px solid var(--textarea-border, var(--border-default, #e5e7eb));\n background-color: var(--textarea-bg, var(--surface-interactive-default, #f9fafb));\n line-height: 1.5;\n color: var(--text-primary, #111827);\n transition: border-color var(--motion-duration-150, 150ms) var(--motion-easing-default, ease-in-out), box-shadow var(--motion-duration-150, 150ms) var(--motion-easing-default, ease-in-out);\n outline: none;\n}\n\n.base::placeholder {\n color: var(--text-secondary, #9ca3af);\n}\n\n@media (hover: hover) {\n .base:hover:not(:focus-visible):not(:disabled):not([aria-invalid=\"true\"]) {\n border-color: var(--border-strong, #d1d5db);\n }\n}\n\n.base:focus-visible {\n border-color: var(--border-focus, #111827);\n box-shadow: 0 0 0 var(--focus-ring-width, 2px) color-mix(in srgb, var(--border-focus, #111827) 15%, transparent);\n}\n\n.base:disabled {\n cursor: not-allowed;\n opacity: 0.5;\n}\n\n.base[aria-invalid=\"true\"] {\n border-color: var(--border-error, #ef4444);\n box-shadow: 0 0 0 var(--focus-ring-width, 2px) color-mix(in srgb, var(--border-error, #ef4444) 15%, transparent);\n}\n\n/* Size variants */\n.sizeSm {\n min-height: 4rem;\n padding: var(--spacing-3, 0.75rem);\n font-size: var(--font-size-sm, 0.875rem);\n border-radius: var(--radius-sm, 0.25rem);\n}\n\n.sizeMd {\n min-height: 6.25rem;\n padding: var(--spacing-3_5, 0.875rem) var(--spacing-4, 1rem);\n font-size: var(--font-size-sm, 0.875rem);\n border-radius: var(--radius-sm, 0.5rem);\n}\n\n.sizeLg {\n min-height: 8rem;\n padding: var(--spacing-4_5, 1.125rem) var(--spacing-5, 1.25rem);\n font-size: var(--font-size-base, 1rem);\n border-radius: var(--radius-sm, 0.5rem);\n}\n"
|
|
227
227
|
}
|
|
228
228
|
]
|
|
229
229
|
},
|
|
@@ -275,7 +275,7 @@
|
|
|
275
275
|
{
|
|
276
276
|
"path": "components/ui/select/select.module.css",
|
|
277
277
|
"type": "registry:ui",
|
|
278
|
-
"content": "/* Select Trigger */\n.trigger {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: calc(var(--spacing-1, 0.25rem) * 1.5);\n width: fit-content;\n border-radius: var(--radius-md, 0.375rem);\n border: 1px solid var(--select-border, var(--border-default, #e5e7eb));\n background-color: var(--field-control-bg, var(--select-bg, var(--surface-interactive-default, #f9fafb)));\n padding: var(--spacing-2, 0.5rem) var(--spacing-3, 0.75rem);\n font-size: var(--font-size-sm, 0.875rem);\n /* Match Input's line-height so the trigger's height tracks the text field at\n the same size. Without this the trigger inherited line-height 2.0, rendering\n ~7px taller than a same-size Input. */\n line-height: 1.5;\n white-space: nowrap;\n color: var(--text-primary, #111827);\n transition: border-color var(--motion-duration-150, 150ms) var(--motion-easing-default, ease-in-out), box-shadow var(--motion-duration-150, 150ms) var(--motion-easing-default, ease-in-out);\n outline: none;\n cursor: pointer;\n}\n\n@media (hover: hover) {\n .trigger:hover:not(:focus-visible):not(:disabled):not([aria-invalid=\"true\"]) {\n border-color: var(--border-strong, #d1d5db);\n }\n}\n\n.trigger:focus-visible {\n border-color: var(--border-focus, #111827);\n box-shadow: 0 0 0 var(--focus-ring-width, 2px) color-mix(in srgb, var(--border-focus, #111827) 15%, transparent);\n}\n\n.trigger:disabled {\n cursor: not-allowed;\n opacity: 0.5;\n}\n\n.trigger[aria-invalid=\"true\"] {\n border-color: var(--border-error, #ef4444);\n box-shadow: 0 0 0 var(--focus-ring-width, 2px) color-mix(in srgb, var(--border-error, #ef4444) 15%, transparent);\n}\n\n.trigger[data-placeholder] {\n color: var(--text-secondary, #9ca3af);\n}\n\n/* Borderless trigger variant (opt-in via <SelectTrigger variant=\"borderless\">).\n *\n * Closed trigger has no 1px border and sits on --field-control-bg — the same\n * shared form-control surface role Input uses — so a borderless Select matches a\n * borderless Input inside an in-dialog form context that sets\n * --field-control-bg: var(--surface-subtle). Default Select is unchanged. The\n * border is kept transparent (rather than removed) so the trigger's box size\n * stays identical to the default trigger and the focus ring keeps its geometry.\n * Declared after the base .trigger so these overrides win the cascade. */\n.triggerBorderless {\n border-color: transparent;\n background-color: var(--field-control-bg, var(--select-bg, var(--surface-interactive-default, #f9fafb)));\n /* In-form borderless selects match the Input they sit beside: full width and\n the same md height/padding (the prototype paired select and input controls inside its field rows). */\n width: 100%;\n padding: var(--spacing-3_5, 0.875rem) var(--spacing-4, 1rem);\n}\n\n@media (hover: hover) {\n .triggerBorderless:hover:not(:focus-visible):not(:disabled):not([aria-invalid=\"true\"]) {\n border-color: transparent;\n }\n}\n\n.triggerBorderless:focus-visible {\n border-color: transparent;\n box-shadow: 0 0 0 var(--focus-ring-width, 2px) color-mix(in srgb, var(--border-focus, #111827) 15%, transparent);\n}\n\n:global([data-density=\"editorial\"]) .trigger {\n background-color: var(--field-control-bg, var(--surface-card));\n}\n\n:global([data-density=\"editorial\"]) .triggerBorderless {\n background-color: var(--field-control-bg, var(--surface-card));\n}\n\n.triggerSizeSm {\n height: 2.25rem;\n border-radius: var(--radius-sm, 0.25rem);\n}\n\n.triggerSizeMd {\n height: auto;\n padding: var(--spacing-3_5, 0.875rem) var(--spacing-4, 1rem);\n font-size: var(--font-size-sm, 0.875rem);\n border-radius: var(--radius-sm, 0.5rem);\n}\n\n.triggerSizeLg {\n height: auto;\n padding: var(--spacing-4_5, 1.125rem) var(--spacing-5, 1.25rem);\n font-size: var(--font-size-base, 1rem);\n border-radius: var(--radius-sm, 0.5rem);\n}\n\n.triggerIcon {\n pointer-events: none;\n width: 1rem;\n height: 1rem;\n flex-shrink: 0;\n color: var(--text-secondary, #9ca3af);\n}\n\n/* Select Content */\n.content {\n position: relative;\n z-index: 50;\n max-height: var(--radix-select-content-available-height, 300px);\n min-width: 9rem;\n overflow: hidden;\n border-radius: var(--radius-lg, 0.5rem);\n background-color: var(--field-menu-bg, var(--surface-popover, var(--surface-card, #ffffff)));\n color: var(--text-primary, #111827);\n box-shadow: var(--shadow-lg);\n}\n\n/* Select Viewport */\n.viewport {\n padding: var(--spacing-1, 0.25rem);\n}\n\n.viewportPopper {\n height: var(--radix-select-trigger-height);\n width: 100%;\n min-width: var(--radix-select-trigger-width);\n}\n\n/* Select Label */\n.label {\n padding: var(--spacing-2, 0.5rem) var(--spacing-3, 0.75rem);\n font-size: var(--font-size-xs, 0.75rem);\n color: var(--text-secondary, #9ca3af);\n}\n\n/* Select Item */\n.item {\n position: relative;\n display: flex;\n width: 100%;\n cursor: default;\n align-items: center;\n gap: calc(var(--spacing-2, 0.5rem) + var(--spacing-1, 0.25rem) / 2);\n border-radius: var(--radius-sm, 0.25rem);\n padding: var(--spacing-2, 0.5rem) var(--spacing-8, 2rem) var(--spacing-2, 0.5rem) var(--spacing-3, 0.75rem);\n font-size: var(--font-size-sm, 0.875rem);\n outline: none;\n user-select: none;\n}\n\n.item:focus,\n.item[data-highlighted] {\n background-color: var(--surface-interactive-hover, #f3f4f6);\n color: var(--text-primary, #111827);\n}\n\n.item[data-disabled] {\n pointer-events: none;\n opacity: 0.5;\n}\n\n.itemIndicatorWrapper {\n position: absolute;\n right: 0.5rem;\n display: flex;\n width: 1rem;\n height: 1rem;\n align-items: center;\n justify-content: center;\n}\n\n.itemIndicatorIcon {\n width: 0.875rem;\n height: 0.875rem;\n pointer-events: none;\n}\n\n/* Select Separator */\n.separator {\n pointer-events: none;\n margin: var(--spacing-1, 0.25rem) calc(-1 * var(--spacing-1, 0.25rem));\n height: 1px;\n background-color: var(--border-default, #e5e7eb);\n}\n\n/* Scroll Buttons */\n.scrollButton {\n display: flex;\n cursor: default;\n align-items: center;\n justify-content: center;\n padding: var(--spacing-1, 0.25rem);\n background-color: var(--field-menu-bg, var(--surface-popover, var(--surface-card, #ffffff)));\n}\n\n.scrollButtonIcon {\n width: 1rem;\n height: 1rem;\n}\n
|
|
278
|
+
"content": "/* Select Trigger */\n.trigger {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: calc(var(--spacing-1, 0.25rem) * 1.5);\n width: fit-content;\n border-radius: var(--radius-md, 0.375rem);\n border: 1px solid var(--select-border, var(--border-default, #e5e7eb));\n background-color: var(--field-control-bg, var(--select-bg, var(--surface-interactive-default, #f9fafb)));\n padding: var(--spacing-2, 0.5rem) var(--spacing-3, 0.75rem);\n font-size: var(--font-size-sm, 0.875rem);\n /* Match Input's line-height so the trigger's height tracks the text field at\n the same size. Without this the trigger inherited line-height 2.0, rendering\n ~7px taller than a same-size Input. */\n line-height: 1.5;\n white-space: nowrap;\n color: var(--text-primary, #111827);\n transition: border-color var(--motion-duration-150, 150ms) var(--motion-easing-default, ease-in-out), box-shadow var(--motion-duration-150, 150ms) var(--motion-easing-default, ease-in-out);\n outline: none;\n cursor: pointer;\n}\n\n@media (hover: hover) {\n .trigger:hover:not(:focus-visible):not(:disabled):not([aria-invalid=\"true\"]) {\n border-color: var(--border-strong, #d1d5db);\n }\n}\n\n.trigger:focus-visible {\n border-color: var(--border-focus, #111827);\n box-shadow: 0 0 0 var(--focus-ring-width, 2px) color-mix(in srgb, var(--border-focus, #111827) 15%, transparent);\n}\n\n.trigger:disabled {\n cursor: not-allowed;\n opacity: 0.5;\n}\n\n.trigger[aria-invalid=\"true\"] {\n border-color: var(--border-error, #ef4444);\n box-shadow: 0 0 0 var(--focus-ring-width, 2px) color-mix(in srgb, var(--border-error, #ef4444) 15%, transparent);\n}\n\n.trigger[data-placeholder] {\n color: var(--text-secondary, #9ca3af);\n}\n\n/* Borderless trigger variant (opt-in via <SelectTrigger variant=\"borderless\">).\n *\n * Closed trigger has no 1px border and sits on --field-control-bg — the same\n * shared form-control surface role Input uses — so a borderless Select matches a\n * borderless Input inside an in-dialog form context that sets\n * --field-control-bg: var(--surface-subtle). Default Select is unchanged. The\n * border is kept transparent (rather than removed) so the trigger's box size\n * stays identical to the default trigger and the focus ring keeps its geometry.\n * Declared after the base .trigger so these overrides win the cascade. */\n.triggerBorderless {\n border-color: transparent;\n background-color: var(--field-control-bg, var(--select-bg, var(--surface-interactive-default, #f9fafb)));\n /* In-form borderless selects match the Input they sit beside: full width and\n the same md height/padding (the prototype paired select and input controls inside its field rows). */\n width: 100%;\n padding: var(--spacing-3_5, 0.875rem) var(--spacing-4, 1rem);\n}\n\n@media (hover: hover) {\n .triggerBorderless:hover:not(:focus-visible):not(:disabled):not([aria-invalid=\"true\"]) {\n border-color: transparent;\n }\n}\n\n.triggerBorderless:focus-visible {\n border-color: transparent;\n box-shadow: 0 0 0 var(--focus-ring-width, 2px) color-mix(in srgb, var(--border-focus, #111827) 15%, transparent);\n}\n\n:global([data-density=\"editorial\"]) .trigger {\n background-color: var(--field-control-bg, var(--surface-card));\n}\n\n:global([data-density=\"editorial\"]) .triggerBorderless {\n background-color: var(--field-control-bg, var(--surface-card));\n}\n\n.triggerSizeSm {\n height: 2.25rem;\n border-radius: var(--radius-sm, 0.25rem);\n}\n\n.triggerSizeMd {\n height: auto;\n padding: var(--spacing-3_5, 0.875rem) var(--spacing-4, 1rem);\n font-size: var(--font-size-sm, 0.875rem);\n border-radius: var(--radius-sm, 0.5rem);\n}\n\n.triggerSizeLg {\n height: auto;\n padding: var(--spacing-4_5, 1.125rem) var(--spacing-5, 1.25rem);\n font-size: var(--font-size-base, 1rem);\n border-radius: var(--radius-sm, 0.5rem);\n}\n\n.triggerIcon {\n pointer-events: none;\n width: 1rem;\n height: 1rem;\n flex-shrink: 0;\n color: var(--text-secondary, #9ca3af);\n}\n\n/* Select Content */\n.content {\n position: relative;\n z-index: 50;\n max-height: var(--radix-select-content-available-height, 300px);\n min-width: 9rem;\n overflow: hidden;\n border-radius: var(--radius-lg, 0.5rem);\n background-color: var(--field-menu-bg, var(--surface-popover, var(--surface-card, #ffffff)));\n color: var(--text-primary, #111827);\n box-shadow: var(--shadow-lg);\n}\n\n/* Select Viewport */\n.viewport {\n padding: var(--spacing-1, 0.25rem);\n}\n\n.viewportPopper {\n height: var(--radix-select-trigger-height);\n width: 100%;\n min-width: var(--radix-select-trigger-width);\n}\n\n/* Select Label */\n.label {\n padding: var(--spacing-2, 0.5rem) var(--spacing-3, 0.75rem);\n font-size: var(--font-size-xs, 0.75rem);\n color: var(--text-secondary, #9ca3af);\n}\n\n/* Select Item */\n.item {\n position: relative;\n display: flex;\n width: 100%;\n cursor: default;\n align-items: center;\n gap: calc(var(--spacing-2, 0.5rem) + var(--spacing-1, 0.25rem) / 2);\n border-radius: var(--radius-sm, 0.25rem);\n padding: var(--spacing-2, 0.5rem) var(--spacing-8, 2rem) var(--spacing-2, 0.5rem) var(--spacing-3, 0.75rem);\n font-size: var(--font-size-sm, 0.875rem);\n outline: none;\n user-select: none;\n}\n\n.item:focus,\n.item[data-highlighted] {\n background-color: var(--surface-interactive-hover, #f3f4f6);\n color: var(--text-primary, #111827);\n}\n\n.item[data-disabled] {\n pointer-events: none;\n opacity: 0.5;\n}\n\n.itemIndicatorWrapper {\n position: absolute;\n right: 0.5rem;\n display: flex;\n width: 1rem;\n height: 1rem;\n align-items: center;\n justify-content: center;\n}\n\n.itemIndicatorIcon {\n width: 0.875rem;\n height: 0.875rem;\n pointer-events: none;\n}\n\n/* Select Separator */\n.separator {\n pointer-events: none;\n margin: var(--spacing-1, 0.25rem) calc(-1 * var(--spacing-1, 0.25rem));\n height: 1px;\n background-color: var(--border-default, #e5e7eb);\n}\n\n/* Scroll Buttons */\n.scrollButton {\n display: flex;\n cursor: default;\n align-items: center;\n justify-content: center;\n padding: var(--spacing-1, 0.25rem);\n background-color: var(--field-menu-bg, var(--surface-popover, var(--surface-card, #ffffff)));\n}\n\n.scrollButtonIcon {\n width: 1rem;\n height: 1rem;\n}\n"
|
|
279
279
|
}
|
|
280
280
|
]
|
|
281
281
|
},
|
|
@@ -651,7 +651,7 @@
|
|
|
651
651
|
{
|
|
652
652
|
"path": "components/ui/challenge-card/challenge-card.module.css",
|
|
653
653
|
"type": "registry:ui",
|
|
654
|
-
"content": "/* ChallengeCard\n *\n * First-class adversarial challenge message — an AI pushes back on the user's\n * input and the HUMAN holds the gate. Distinct from Alert (passive notice):\n * ChallengeCard carries its own action semantics and gate affordance.\n *\n * Visual spec: docs/design/brand-workbench/elicit-core (the adversarial\n * challenge card section, around line 261-273)\n */\n\n/* Root card */\n.root {\n /* Component-scoped hooks — consumers can override any of these on the wrapper. */\n --challenge-card-action-primary-text: var(--color-warning-900, var(--text-warning, #78350f));\n\n width: 100%;\n border-radius: var(--radius-xl, 1rem);\n background-color: var(--surface-warning-subtle, #fffbeb);\n border: var(--stroke-width-thin, 1px) solid var(--border-warning, #d97706);\n overflow: hidden;\n}\n\n/* Header — flag icon + uppercase warning-colored title */\n.header {\n display: flex;\n align-items: center;\n gap: var(--spacing-2, 0.5rem);\n padding: var(--spacing-2-5, 0.625rem) var(--spacing-4, 1rem);\n font-size: 11.5px;\n font-weight: 800;\n letter-spacing: 0.05em;\n text-transform: uppercase;\n color: var(--text-warning, #b45309);\n}\n\n.headerIcon {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 14px;\n height: 14px;\n flex-shrink: 0;\n color: var(--text-warning, #b45309);\n}\n\n/* Body — prose */\n.body {\n padding: 0 var(--spacing-4, 1rem) var(--spacing-3, 0.75rem);\n font-size: 14.5px;\n line-height: 1.55;\n color: var(--text-primary, #111827);\n}\n\n/* Actions row */\n.actions {\n display: flex;\n align-items: center;\n gap: var(--spacing-2, 0.5rem);\n padding: 0 var(--spacing-4, 1rem) var(--spacing-3-5, 0.875rem);\n}\n\n/* Action button base */\n.action {\n height: 32px;\n padding: 0 var(--spacing-3-5, 0.875rem);\n border-radius: var(--radius-lg, 0.5rem);\n font-
|
|
654
|
+
"content": "/* ChallengeCard\n *\n * First-class adversarial challenge message — an AI pushes back on the user's\n * input and the HUMAN holds the gate. Distinct from Alert (passive notice):\n * ChallengeCard carries its own action semantics and gate affordance.\n *\n * Visual spec: docs/design/brand-workbench/elicit-core (the adversarial\n * challenge card section, around line 261-273)\n */\n\n/* Root card */\n.root {\n /* Component-scoped hooks — consumers can override any of these on the wrapper. */\n --challenge-card-action-primary-text: var(--color-warning-900, var(--text-warning, #78350f));\n\n width: 100%;\n border-radius: var(--radius-xl, 1rem);\n background-color: var(--surface-warning-subtle, #fffbeb);\n border: var(--stroke-width-thin, 1px) solid var(--border-warning, #d97706);\n overflow: hidden;\n}\n\n/* Header — flag icon + uppercase warning-colored title */\n.header {\n display: flex;\n align-items: center;\n gap: var(--spacing-2, 0.5rem);\n padding: var(--spacing-2-5, 0.625rem) var(--spacing-4, 1rem);\n font-size: 11.5px;\n font-weight: 800;\n letter-spacing: 0.05em;\n text-transform: uppercase;\n color: var(--text-warning, #b45309);\n}\n\n.headerIcon {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 14px;\n height: 14px;\n flex-shrink: 0;\n color: var(--text-warning, #b45309);\n}\n\n/* Body — prose */\n.body {\n padding: 0 var(--spacing-4, 1rem) var(--spacing-3, 0.75rem);\n font-size: 14.5px;\n line-height: 1.55;\n color: var(--text-primary, #111827);\n}\n\n/* Actions row */\n.actions {\n display: flex;\n align-items: center;\n gap: var(--spacing-2, 0.5rem);\n padding: 0 var(--spacing-4, 1rem) var(--spacing-3-5, 0.875rem);\n}\n\n/* Action button base */\n.action {\n height: 32px;\n padding: 0 var(--spacing-3-5, 0.875rem);\n border-radius: var(--radius-lg, 0.5rem);\n font-size: 12.5px;\n font-weight: 700;\n cursor: pointer;\n display: inline-flex;\n align-items: center;\n gap: var(--spacing-1-5, 0.375rem);\n transition:\n opacity var(--motion-duration-150, 150ms) var(--motion-easing-default, ease-in-out),\n box-shadow var(--motion-duration-150, 150ms) var(--motion-easing-default, ease-in-out);\n outline: none;\n}\n\n.action:focus-visible {\n outline: var(--focus-ring-width, 2px) solid var(--text-warning, #b45309);\n outline-offset: var(--focus-ring-offset, 2px);\n}\n\n.action:disabled {\n opacity: var(--opacity-40, 0.4);\n cursor: not-allowed;\n}\n\n/* Primary — filled warning-toned */\n.actionPrimary {\n background-color: var(--warning, #f59e0b);\n /* Warning amber is a light/warm amber — dark warm-900 text has the highest contrast */\n color: var(--challenge-card-action-primary-text);\n border: none;\n}\n\n.actionPrimary:hover:not(:disabled) {\n opacity: var(--opacity-80, 0.8);\n}\n\n/* Ghost — transparent with border */\n.actionGhost {\n background-color: transparent;\n color: var(--text-secondary, #6b7280);\n border: var(--stroke-width-thin, 1px) solid var(--border-default, #e5e7eb);\n}\n\n.actionGhost:hover:not(:disabled) {\n background-color: color-mix(in srgb, var(--surface-card, #ffffff) 80%, transparent);\n}\n\n/* Action icon */\n.actionIcon {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 13px;\n height: 13px;\n flex-shrink: 0;\n}\n\n/* Gate indicator — pushed right via margin-left: auto */\n.gate {\n margin-left: auto;\n font-size: 11px;\n color: var(--text-tertiary, #9ca3af);\n display: inline-flex;\n align-items: center;\n gap: var(--spacing-1, 0.25rem);\n white-space: nowrap;\n flex-shrink: 0;\n}\n\n.gateIcon {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 12px;\n height: 12px;\n flex-shrink: 0;\n}\n\n/* Respect reduced motion */\n@media (prefers-reduced-motion: reduce) {\n .action {\n transition: none;\n }\n}\n"
|
|
655
655
|
}
|
|
656
656
|
]
|
|
657
657
|
},
|
|
@@ -677,7 +677,7 @@
|
|
|
677
677
|
{
|
|
678
678
|
"path": "components/ui/coherence-check/coherence-check.module.css",
|
|
679
679
|
"type": "registry:ui",
|
|
680
|
-
"content": "/* ─── CheckGroup ─────────────────────────────────────────────────────────── */\n\n.group {\n margin-bottom: var(--spacing-5, 1.25rem);\n}\n\n/* Uppercase group header */\n.groupHeading {\n margin: 0 0 var(--spacing-2, 0.5rem);\n padding: 0 calc(var(--spacing-1, 0.25rem) / 2);\n font-size: var(--font-size-xs, 0.75rem);\n font-weight: var(--font-weight-extrabold, 800);\n letter-spacing: 0.06em;\n text-transform: uppercase;\n color: var(--text-tertiary, #9ca3af);\n line-height: 1.4;\n}\n\n/* ─── CheckRow ───────────────────────────────────────────────────────────── */\n\n.row {\n display: flex;\n align-items: flex-start;\n gap: var(--spacing-3, 0.75rem);\n background: var(--surface-card, #ffffff);\n border: var(--stroke-width-thin, 1px) solid var(--hairline, #e5e7eb);\n border-radius: var(--radius-lg, 0.5rem);\n padding: var(--spacing-3, 0.75rem) var(--spacing-4, 1rem);\n margin-bottom: var(--spacing-2, 0.5rem);\n box-shadow: var(--shadow-sm);\n}\n\n/* Last row in a group has no bottom margin */\n.row:last-child {\n margin-bottom: 0;\n}\n\n/* ─── State icon circle ─────────────────────────────────────────────────── */\n\n.icon {\n flex: none;\n width: var(--spacing-6, 1.5rem);\n height: var(--spacing-6, 1.5rem);\n border-radius: var(--radius-full, 9999px);\n display: grid;\n place-items: center;\n margin-top: calc(var(--spacing-1, 0.25rem) / 4);\n color: var(--text-inverse, #ffffff);\n}\n\n.icon svg {\n width: var(--spacing-4, 1rem);\n height: var(--spacing-4, 1rem);\n}\n\n/* State — icon background tints */\n.statePass .icon {\n background: var(--success, #22c55e);\n}\n\n.stateWarn .icon {\n background: var(--warning, #f59e0b);\n}\n\n.stateFail .icon {\n background: var(--destructive, #ef4444);\n}\n\n/* ─── Body (title + description) ─────────────────────────────────────────── */\n\n.body {\n flex: 1;\n min-width: 0;\n}\n\n.rowTitle {\n display: block;\n font-size: var(--font-size-sm, 0.875rem);\n font-weight: var(--font-weight-bold, 700);\n color: var(--text-primary, #111827);\n line-height: 1.4;\n}\n\n.rowDescription {\n margin: calc(var(--spacing-1, 0.25rem) * 0.75) 0 0;\n font-size: var(--font-size-xs, 0.75rem);\n color: var(--text-secondary, #6b7280);\n line-height: 1.5;\n}\n\n/* Inline code token support within description */\n.rowDescription code {\n font-family: var(--font-mono, ui-monospace, monospace);\n font-size: var(--font-size-xs, 0.75rem);\n background: var(--surface-muted, #f3f4f6);\n padding: var(--stroke-width-thin, 1px) var(--spacing-1, 0.25rem);\n border-radius: var(--radius-sm, 0.125rem);\n}\n\n/* ─── Fix action button (ghost) ──────────────────────────────────────────── */\n\n.fixButton {\n flex: none;\n align-self: center;\n height: var(--spacing-8, 2rem);\n padding: 0 var(--spacing-3, 0.75rem);\n border-radius: var(--radius-md, 0.25rem);\n font-
|
|
680
|
+
"content": "/* ─── CheckGroup ─────────────────────────────────────────────────────────── */\n\n.group {\n margin-bottom: var(--spacing-5, 1.25rem);\n}\n\n/* Uppercase group header */\n.groupHeading {\n margin: 0 0 var(--spacing-2, 0.5rem);\n padding: 0 calc(var(--spacing-1, 0.25rem) / 2);\n font-size: var(--font-size-xs, 0.75rem);\n font-weight: var(--font-weight-extrabold, 800);\n letter-spacing: 0.06em;\n text-transform: uppercase;\n color: var(--text-tertiary, #9ca3af);\n line-height: 1.4;\n}\n\n/* ─── CheckRow ───────────────────────────────────────────────────────────── */\n\n.row {\n display: flex;\n align-items: flex-start;\n gap: var(--spacing-3, 0.75rem);\n background: var(--surface-card, #ffffff);\n border: var(--stroke-width-thin, 1px) solid var(--hairline, #e5e7eb);\n border-radius: var(--radius-lg, 0.5rem);\n padding: var(--spacing-3, 0.75rem) var(--spacing-4, 1rem);\n margin-bottom: var(--spacing-2, 0.5rem);\n box-shadow: var(--shadow-sm);\n}\n\n/* Last row in a group has no bottom margin */\n.row:last-child {\n margin-bottom: 0;\n}\n\n/* ─── State icon circle ─────────────────────────────────────────────────── */\n\n.icon {\n flex: none;\n width: var(--spacing-6, 1.5rem);\n height: var(--spacing-6, 1.5rem);\n border-radius: var(--radius-full, 9999px);\n display: grid;\n place-items: center;\n margin-top: calc(var(--spacing-1, 0.25rem) / 4);\n color: var(--text-inverse, #ffffff);\n}\n\n.icon svg {\n width: var(--spacing-4, 1rem);\n height: var(--spacing-4, 1rem);\n}\n\n/* State — icon background tints */\n.statePass .icon {\n background: var(--success, #22c55e);\n}\n\n.stateWarn .icon {\n background: var(--warning, #f59e0b);\n}\n\n.stateFail .icon {\n background: var(--destructive, #ef4444);\n}\n\n/* ─── Body (title + description) ─────────────────────────────────────────── */\n\n.body {\n flex: 1;\n min-width: 0;\n}\n\n.rowTitle {\n display: block;\n font-size: var(--font-size-sm, 0.875rem);\n font-weight: var(--font-weight-bold, 700);\n color: var(--text-primary, #111827);\n line-height: 1.4;\n}\n\n.rowDescription {\n margin: calc(var(--spacing-1, 0.25rem) * 0.75) 0 0;\n font-size: var(--font-size-xs, 0.75rem);\n color: var(--text-secondary, #6b7280);\n line-height: 1.5;\n}\n\n/* Inline code token support within description */\n.rowDescription code {\n font-family: var(--font-mono, ui-monospace, monospace);\n font-size: var(--font-size-xs, 0.75rem);\n background: var(--surface-muted, #f3f4f6);\n padding: var(--stroke-width-thin, 1px) var(--spacing-1, 0.25rem);\n border-radius: var(--radius-sm, 0.125rem);\n}\n\n/* ─── Fix action button (ghost) ──────────────────────────────────────────── */\n\n.fixButton {\n flex: none;\n align-self: center;\n height: var(--spacing-8, 2rem);\n padding: 0 var(--spacing-3, 0.75rem);\n border-radius: var(--radius-md, 0.25rem);\n font-size: var(--font-size-xs, 0.75rem);\n font-weight: var(--font-weight-bold, 700);\n border: var(--stroke-width-thin, 1px) solid var(--border-default, #e5e7eb);\n background: transparent;\n color: var(--text-primary, #111827);\n cursor: pointer;\n transition:\n background-color var(--motion-duration-150, 150ms) var(--motion-easing-default, ease-in-out),\n border-color var(--motion-duration-150, 150ms) var(--motion-easing-default, ease-in-out),\n color var(--motion-duration-150, 150ms) var(--motion-easing-default, ease-in-out);\n white-space: nowrap;\n}\n\n.fixButton:hover {\n background: var(--surface-muted, #f3f4f6);\n border-color: var(--border-strong, #d1d5db);\n}\n\n.fixButton:focus-visible {\n outline: var(--focus-ring-width, 2px) solid var(--border-focus, currentColor);\n outline-offset: var(--focus-ring-offset, 2px);\n}\n"
|
|
681
681
|
}
|
|
682
682
|
]
|
|
683
683
|
},
|
|
@@ -832,7 +832,7 @@
|
|
|
832
832
|
{
|
|
833
833
|
"path": "components/ui/tabs/tabs.module.css",
|
|
834
834
|
"type": "registry:ui",
|
|
835
|
-
"content": "/* Tabs root */\n.root {\n display: flex;\n flex-direction: column;\n gap: var(--spacing-2, 0.5rem);\n}\n\n/* Tabs list */\n.list {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n border-radius: var(--radius-full, 9999px);\n padding: calc(var(--spacing-1, 0.25rem) * 0.75);\n color: var(--text-secondary, #6b7280);\n height: 2.25rem;\n width: fit-content;\n}\n\n.listVariantDefault {\n background-color: var(--surface-muted, #f3f4f6);\n}\n\n.listVariantLine {\n position: relative;\n gap: var(--spacing-2, 0.5rem);\n background-color: transparent;\n border-radius: 0;\n border-bottom: 1px solid var(--hairline, var(--border-default, #e5e7eb));\n height: auto;\n padding-bottom: 0;\n width: 100%;\n justify-content: flex-start;\n}\n\n/* Line variant: content-width triggers with comfortable padding — the strip\n reads as an underlined rail, not a segmented control. */\n.listVariantLine .trigger {\n flex: 0 0 auto;\n padding: var(--spacing-2, 0.5rem) var(--spacing-3, 0.75rem);\n}\n\n/* Tabs trigger */\n.trigger {\n position: relative;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n gap: calc(var(--spacing-1, 0.25rem) * 1.5);\n border-radius: var(--radius-md, 0.375rem);\n border: 1px solid transparent;\n padding: var(--spacing-1, 0.25rem) var(--spacing-2, 0.5rem);\n font-size: var(--font-size-sm, 0.875rem);\n font-weight: var(--font-weight-medium, 500);\n
|
|
835
|
+
"content": "/* Tabs root */\n.root {\n display: flex;\n flex-direction: column;\n gap: var(--spacing-2, 0.5rem);\n}\n\n/* Tabs list */\n.list {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n border-radius: var(--radius-full, 9999px);\n padding: calc(var(--spacing-1, 0.25rem) * 0.75);\n color: var(--text-secondary, #6b7280);\n height: 2.25rem;\n width: fit-content;\n}\n\n.listVariantDefault {\n background-color: var(--surface-muted, #f3f4f6);\n}\n\n.listVariantLine {\n position: relative;\n gap: var(--spacing-2, 0.5rem);\n background-color: transparent;\n border-radius: 0;\n border-bottom: 1px solid var(--hairline, var(--border-default, #e5e7eb));\n height: auto;\n padding-bottom: 0;\n width: 100%;\n justify-content: flex-start;\n}\n\n/* Line variant: content-width triggers with comfortable padding — the strip\n reads as an underlined rail, not a segmented control. */\n.listVariantLine .trigger {\n flex: 0 0 auto;\n padding: var(--spacing-2, 0.5rem) var(--spacing-3, 0.75rem);\n}\n\n/* Tabs trigger */\n.trigger {\n position: relative;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n gap: calc(var(--spacing-1, 0.25rem) * 1.5);\n border-radius: var(--radius-md, 0.375rem);\n border: 1px solid transparent;\n padding: var(--spacing-1, 0.25rem) var(--spacing-2, 0.5rem);\n font-size: var(--font-size-sm, 0.875rem);\n font-weight: var(--font-weight-medium, 500);\n white-space: nowrap;\n color: var(--text-secondary, #6b7280);\n background: transparent;\n cursor: pointer;\n transition: color var(--motion-duration-150, 150ms) var(--motion-easing-default, ease-in-out), background-color var(--motion-duration-150, 150ms) var(--motion-easing-default, ease-in-out), border-color var(--motion-duration-150, 150ms) var(--motion-easing-default, ease-in-out), transform var(--motion-duration-150, 150ms) var(--motion-easing-default, ease-in-out);\n outline: none;\n flex: 1;\n height: calc(100% - 2px);\n}\n\n.trigger:active:not(:disabled) {\n transform: translateY(1px);\n transition: none;\n}\n\n@media (hover: hover) {\n .trigger:hover {\n color: var(--text-primary, #111827);\n }\n}\n\n.trigger:focus-visible {\n outline: var(--focus-ring-width, 2px) solid var(--border-focus, currentColor);\n outline-offset: var(--focus-ring-offset, 2px);\n}\n\n.trigger:disabled {\n pointer-events: none;\n opacity: 0.5;\n}\n\n.trigger[data-state=\"active\"] {\n background-color: var(--surface-page, #ffffff);\n color: var(--text-primary, #111827);\n box-shadow: var(--shadow-sm);\n}\n\n/* Trigger label — wraps children to allow count pill alongside */\n.label {\n flex: 1 1 auto;\n min-width: 0;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n/* Count pill */\n.count {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n flex-shrink: 0;\n border-radius: var(--radius-full, 9999px);\n padding: 0 var(--spacing-2, 0.5rem);\n font-size: var(--font-size-xs, 0.75rem);\n font-weight: var(--font-weight-medium, 500);\n font-variant-numeric: tabular-nums;\n line-height: 1.5;\n vertical-align: baseline;\n}\n\n.countNeutral {\n background-color: var(--surface-muted, #f3f4f6);\n color: var(--text-secondary, #6b7280);\n}\n\n.countPrimary {\n background-color: var(--surface-accent-subtle, #eff6ff);\n color: var(--text-link, #2563eb);\n}\n\n/* Active-state re-tone: regardless of countTone, re-tone to primary on active */\n.trigger[data-state=\"active\"] .count {\n background-color: var(--surface-accent-subtle, #eff6ff);\n color: var(--text-link, #2563eb);\n}\n\n/* Tabs content */\n.content {\n flex: 1;\n font-size: var(--font-size-sm, 0.875rem);\n outline: none;\n}\n\n.content:focus-visible {\n outline: var(--focus-ring-width, 2px) solid var(--border-focus, currentColor);\n outline-offset: var(--focus-ring-offset, 2px);\n}\n\n/* Line variant: active trigger loses shadow/bg, just text color */\n.listVariantLine .trigger[data-state=\"active\"] {\n background-color: transparent;\n box-shadow: none;\n}\n\n/* Animated sliding indicator for line variant */\n.indicator {\n position: absolute;\n bottom: -1px;\n height: 2px;\n /* Default: text-primary */\n background-color: var(--text-primary, #111827);\n border-radius: var(--radius-full, 9999px);\n transition: left var(--motion-duration-normal, 200ms) var(--motion-easing-default, ease-in-out),\n width var(--motion-duration-normal, 200ms) var(--motion-easing-default, ease-in-out);\n}\n\n/* Density axis — editorial: brand primary underline for dark admin surfaces */\n:global([data-density=\"editorial\"]) .indicator {\n background-color: var(--primary);\n}\n"
|
|
836
836
|
}
|
|
837
837
|
]
|
|
838
838
|
},
|
|
@@ -1070,7 +1070,7 @@
|
|
|
1070
1070
|
{
|
|
1071
1071
|
"path": "components/ui/toast/toast.module.css",
|
|
1072
1072
|
"type": "registry:ui",
|
|
1073
|
-
"content": "/* Toaster container */\n.toaster {\n /* Container styling if needed */\n}\n\n/* Individual toast — :global() selectors nested under .toaster for CSS Modules purity.\n Sonner renders toasts as children of its container element. */\n.toaster :global([data-sonner-toast]) {\n font-family: var(--font-family-sans,
|
|
1073
|
+
"content": "/* Toaster container */\n.toaster {\n /* Container styling if needed */\n}\n\n/* Individual toast — :global() selectors nested under .toaster for CSS Modules purity.\n Sonner renders toasts as children of its container element. */\n.toaster :global([data-sonner-toast]) {\n font-family: var(--font-family-sans, inherit);\n background-color: var(--surface-popover, var(--surface-card, #ffffff));\n color: var(--text-primary, #111827);\n border-radius: var(--radius-lg, 0.5rem);\n box-shadow: var(--shadow-lg);\n padding: var(--spacing-3, 0.75rem) var(--spacing-4, 1rem);\n gap: var(--spacing-2, 0.5rem);\n /* Override Sonner's default 400ms transitions with Visor motion tokens */\n transition:\n transform var(--motion-duration-normal, 200ms) var(--motion-easing-enter, ease-out),\n opacity var(--motion-duration-normal, 200ms) var(--motion-easing-enter, ease-out),\n height var(--motion-duration-normal, 200ms) !important;\n}\n\n/* Faster exit animation for dismissed toasts */\n.toaster :global([data-sonner-toast][data-removed=\"true\"]) {\n transition:\n transform var(--motion-duration-150, 150ms) var(--motion-easing-exit, ease-in),\n opacity var(--motion-duration-150, 150ms) var(--motion-easing-exit, ease-in) !important;\n}\n\n/* Toast title */\n.toaster :global([data-sonner-toast] [data-title]) {\n font-weight: var(--font-weight-semibold, 600);\n font-size: var(--font-size-sm, 0.875rem);\n color: var(--text-primary, #111827);\n}\n\n/* Toast description */\n.toaster :global([data-sonner-toast] [data-description]) {\n font-size: var(--font-size-sm, 0.875rem);\n color: var(--text-secondary, #6b7280);\n}\n\n/* Type-specific colors — subtle bg fill + left accent border */\n\n/* Success: Borealis-spec dark inverse surface (VI-589).\n Dark bg + light text signals a completed, affirmative action.\n Falls back to a high-contrast dark surface on themes that lack\n the --surface-inverse token (for example, custom minimal themes). */\n.toaster :global([data-sonner-toast][data-type=\"success\"]) {\n background-color: var(--surface-inverse, var(--text-primary, #111827));\n color: var(--text-inverse, #f9fafb);\n border-left: none;\n}\n\n/* Success title — use inverse text so it reads on the dark bg */\n.toaster :global([data-sonner-toast][data-type=\"success\"] [data-title]) {\n color: var(--text-inverse, #f9fafb);\n font-weight: var(--font-weight-semibold, 700);\n}\n\n/* Success description — slightly muted inverse text */\n.toaster :global([data-sonner-toast][data-type=\"success\"] [data-description]) {\n color: var(--text-inverse-secondary, #d1d5db);\n}\n\n/* Success action button — accent colour reads on dark surface */\n.toaster :global([data-sonner-toast][data-type=\"success\"] [data-button]) {\n background-color: var(--primary, #111827);\n color: var(--primary-text, #ffffff);\n border: var(--stroke-width-thin, 1px) solid color-mix(in srgb, var(--primary, #111827) 60%, transparent);\n}\n\n/* Success close button — muted inverse */\n.toaster :global([data-sonner-toast][data-type=\"success\"] [data-close-button]) {\n background-color: transparent;\n border-color: color-mix(in srgb, var(--text-inverse, #f9fafb) 20%, transparent);\n color: var(--text-inverse-secondary, #d1d5db);\n}\n\n.toaster :global([data-sonner-toast][data-type=\"error\"]) {\n background-color: var(--surface-error-subtle, #fef2f2);\n border-left: 3px solid var(--border-error, #ef4444);\n}\n\n.toaster :global([data-sonner-toast][data-type=\"warning\"]) {\n background-color: var(--surface-warning-subtle, #fffbeb);\n border-left: 3px solid var(--border-warning, #f59e0b);\n}\n\n.toaster :global([data-sonner-toast][data-type=\"info\"]) {\n background-color: var(--surface-info-subtle, #f0f9ff);\n border-left: 3px solid var(--border-info, #0ea5e9);\n}\n\n/* Action button */\n.toaster :global([data-sonner-toast] [data-button]) {\n background-color: var(--interactive-primary-bg, var(--primary, #111827));\n color: var(--interactive-primary-text, #ffffff);\n border-radius: var(--radius-md, 0.375rem);\n font-size: var(--font-size-xs, 0.75rem);\n font-weight: var(--font-weight-medium, 500);\n padding: var(--spacing-1, 0.25rem) var(--spacing-2, 0.5rem);\n}\n\n/* Cancel button */\n.toaster :global([data-sonner-toast] [data-cancel]) {\n background-color: transparent;\n color: var(--text-secondary, #6b7280);\n font-size: var(--font-size-xs, 0.75rem);\n}\n\n/* Close button */\n.toaster :global([data-sonner-toast] [data-close-button]) {\n background-color: var(--surface-card, #ffffff);\n border: 1px solid var(--border-default, #e5e7eb);\n color: var(--text-secondary, #6b7280);\n}\n\n/* Dark mode support — :where() keeps specificity low so type-specific selectors above win */\n:global(:where(.dark)) .toaster :global([data-sonner-toast]),\n:global(:where([data-theme=\"dark\"])) .toaster :global([data-sonner-toast]) {\n background-color: var(--surface-card, #1f2937);\n color: var(--text-primary, #f9fafb);\n}\n\n/* Class-based styles applied via Sonner's classNames option */\n.toast {\n /* Specificity boost layer — matches :global styles above */\n}\n\n.title {\n font-weight: var(--font-weight-semibold, 600);\n}\n\n.description {\n color: var(--text-secondary, #6b7280);\n}\n\n.actionButton {\n background-color: var(--interactive-primary-bg, var(--primary, #111827));\n color: var(--interactive-primary-text, #ffffff);\n border-radius: var(--radius-md, 0.375rem);\n font-size: var(--font-size-xs, 0.75rem);\n font-weight: var(--font-weight-medium, 500);\n padding: var(--spacing-1, 0.25rem) var(--spacing-2, 0.5rem);\n}\n\n.cancelButton {\n background-color: transparent;\n color: var(--text-secondary, #6b7280);\n font-size: var(--font-size-xs, 0.75rem);\n}\n\n.closeButton {\n background-color: var(--surface-card, #ffffff);\n border: 1px solid var(--border-default, #e5e7eb);\n color: var(--text-secondary, #6b7280);\n}\n"
|
|
1074
1074
|
}
|
|
1075
1075
|
]
|
|
1076
1076
|
},
|
|
@@ -1299,7 +1299,7 @@
|
|
|
1299
1299
|
{
|
|
1300
1300
|
"path": "components/ui/combobox/combobox.module.css",
|
|
1301
1301
|
"type": "registry:ui",
|
|
1302
|
-
"content": "/* Combobox root */\n.root {\n position: relative;\n display: inline-flex;\n flex-direction: column;\n width: fit-content;\n}\n\n/* Input wrapper */\n.inputWrapper {\n position: relative;\n display: flex;\n align-items: center;\n}\n\n/* Input */\n.input {\n width: 100%;\n height: 2.25rem;\n padding: var(--spacing-2, 0.5rem) calc(var(--spacing-8, 2rem) + var(--spacing-1, 0.25rem)) var(--spacing-2, 0.5rem) var(--spacing-3, 0.75rem);\n border-radius: var(--radius-md, 0.375rem);\n border: 1px solid var(--combobox-border, var(--border-default, #e5e7eb));\n background-color: var(--combobox-bg, var(--surface-interactive-default, #f9fafb));\n font-size: var(--font-size-sm, 0.875rem);\n color: var(--text-primary, #111827);\n transition: border-color var(--motion-duration-150, 150ms) var(--motion-easing-default, ease-in-out),\n box-shadow var(--motion-duration-150, 150ms) var(--motion-easing-default, ease-in-out);\n outline: none;\n}\n\n.input::placeholder {\n color: var(--text-secondary, #9ca3af);\n}\n\n@media (hover: hover) {\n .input:hover:not(:focus-visible):not(:disabled) {\n border-color: var(--border-strong, #d1d5db);\n }\n}\n\n.input:focus-visible {\n border-color: var(--border-focus, #111827);\n box-shadow: 0 0 0 var(--focus-ring-width, 2px) color-mix(in srgb, var(--border-focus, #111827) 15%, transparent);\n}\n\n.input:disabled {\n cursor: not-allowed;\n opacity: 0.5;\n}\n\n/* Caret icon */\n.icon {\n position: absolute;\n right: var(--spacing-3, 0.75rem);\n top: 50%;\n transform: translateY(-50%);\n width: 1rem;\n height: 1rem;\n pointer-events: none;\n color: var(--text-secondary, #9ca3af);\n transition: transform var(--motion-duration-150, 150ms) var(--motion-easing-default, ease-in-out);\n}\n\n.iconOpen {\n transform: translateY(-50%) rotate(180deg);\n}\n\n/* Content popover */\n.content {\n z-index: 50;\n min-width: var(--radix-popover-trigger-width, 12rem);\n max-height: 18rem;\n overflow: hidden auto;\n border-radius: var(--radius-lg, 0.5rem);\n background-color: var(--field-menu-bg, var(--surface-popover, var(--surface-card, #ffffff)));\n color: var(--text-primary, #111827);\n box-shadow: var(--shadow-lg);\n padding: var(--spacing-1, 0.25rem);\n}\n\n/* Listbox */\n.listbox {\n list-style: none;\n margin: 0;\n padding: 0;\n}\n\n/* Item */\n.item {\n position: relative;\n display: flex;\n align-items: center;\n gap: var(--spacing-2, 0.5rem);\n padding: var(--spacing-2, 0.5rem) var(--spacing-3, 0.75rem);\n border-radius: var(--radius-sm, 0.25rem);\n font-size: var(--font-size-sm, 0.875rem);\n cursor: default;\n outline: none;\n user-select: none;\n}\n\n.item:focus:not([data-disabled]) {\n background-color: var(--surface-interactive-hover, #f3f4f6);\n cursor: pointer;\n}\n\n@media (hover: hover) {\n .item:hover:not([data-disabled]) {\n background-color: var(--surface-interactive-hover, #f3f4f6);\n cursor: pointer;\n }\n}\n\n.item[data-disabled] {\n opacity: 0.5;\n cursor: not-allowed;\n}\n\n.item[data-selected] {\n background-color: var(--surface-interactive-hover, #f3f4f6);\n font-weight: var(--font-weight-medium, 500);\n}\n\n.itemCheck {\n display: inline-flex;\n width: 1rem;\n height: 1rem;\n align-items: center;\n justify-content: center;\n flex-shrink: 0;\n}\n\n.itemCheckIcon {\n width: 0.875rem;\n height: 0.875rem;\n color: var(--interactive-primary-bg, var(--primary, #111827));\n}\n\n/* Empty */\n.empty {\n list-style: none;\n padding: var(--spacing-4, 1rem) var(--spacing-3, 0.75rem);\n text-align: center;\n font-size: var(--font-size-sm, 0.875rem);\n color: var(--text-secondary, #9ca3af);\n}\n\n/* Group */\n.group {\n list-style: none;\n}\n\n.group ul {\n list-style: none;\n margin: 0;\n padding: 0;\n}\n\n.groupHeading {\n padding: var(--spacing-1, 0.25rem) var(--spacing-3, 0.75rem) var(--spacing-1, 0.25rem);\n font-size: var(--font-size-xs, 0.75rem);\n font-weight: var(--font-weight-medium, 500);\n color: var(--text-secondary, #9ca3af);\n text-transform: uppercase;\n letter-spacing: 0.05em;\n}\n\n/* Separator */\n.separator {\n list-style: none;\n height: 1px;\n margin: var(--spacing-1, 0.25rem) calc(-1 * var(--spacing-1, 0.25rem));\n background-color: var(--border-default, #e5e7eb);\n}\n
|
|
1302
|
+
"content": "/* Combobox root */\n.root {\n position: relative;\n display: inline-flex;\n flex-direction: column;\n width: fit-content;\n}\n\n/* Input wrapper */\n.inputWrapper {\n position: relative;\n display: flex;\n align-items: center;\n}\n\n/* Input */\n.input {\n width: 100%;\n height: 2.25rem;\n padding: var(--spacing-2, 0.5rem) calc(var(--spacing-8, 2rem) + var(--spacing-1, 0.25rem)) var(--spacing-2, 0.5rem) var(--spacing-3, 0.75rem);\n border-radius: var(--radius-md, 0.375rem);\n border: 1px solid var(--combobox-border, var(--border-default, #e5e7eb));\n background-color: var(--combobox-bg, var(--surface-interactive-default, #f9fafb));\n font-size: var(--font-size-sm, 0.875rem);\n color: var(--text-primary, #111827);\n transition: border-color var(--motion-duration-150, 150ms) var(--motion-easing-default, ease-in-out),\n box-shadow var(--motion-duration-150, 150ms) var(--motion-easing-default, ease-in-out);\n outline: none;\n}\n\n.input::placeholder {\n color: var(--text-secondary, #9ca3af);\n}\n\n@media (hover: hover) {\n .input:hover:not(:focus-visible):not(:disabled) {\n border-color: var(--border-strong, #d1d5db);\n }\n}\n\n.input:focus-visible {\n border-color: var(--border-focus, #111827);\n box-shadow: 0 0 0 var(--focus-ring-width, 2px) color-mix(in srgb, var(--border-focus, #111827) 15%, transparent);\n}\n\n.input:disabled {\n cursor: not-allowed;\n opacity: 0.5;\n}\n\n/* Caret icon */\n.icon {\n position: absolute;\n right: var(--spacing-3, 0.75rem);\n top: 50%;\n transform: translateY(-50%);\n width: 1rem;\n height: 1rem;\n pointer-events: none;\n color: var(--text-secondary, #9ca3af);\n transition: transform var(--motion-duration-150, 150ms) var(--motion-easing-default, ease-in-out);\n}\n\n.iconOpen {\n transform: translateY(-50%) rotate(180deg);\n}\n\n/* Content popover */\n.content {\n z-index: 50;\n min-width: var(--radix-popover-trigger-width, 12rem);\n max-height: 18rem;\n overflow: hidden auto;\n border-radius: var(--radius-lg, 0.5rem);\n background-color: var(--field-menu-bg, var(--surface-popover, var(--surface-card, #ffffff)));\n color: var(--text-primary, #111827);\n box-shadow: var(--shadow-lg);\n padding: var(--spacing-1, 0.25rem);\n}\n\n/* Listbox */\n.listbox {\n list-style: none;\n margin: 0;\n padding: 0;\n}\n\n/* Item */\n.item {\n position: relative;\n display: flex;\n align-items: center;\n gap: var(--spacing-2, 0.5rem);\n padding: var(--spacing-2, 0.5rem) var(--spacing-3, 0.75rem);\n border-radius: var(--radius-sm, 0.25rem);\n font-size: var(--font-size-sm, 0.875rem);\n cursor: default;\n outline: none;\n user-select: none;\n}\n\n.item:focus:not([data-disabled]) {\n background-color: var(--surface-interactive-hover, #f3f4f6);\n cursor: pointer;\n}\n\n@media (hover: hover) {\n .item:hover:not([data-disabled]) {\n background-color: var(--surface-interactive-hover, #f3f4f6);\n cursor: pointer;\n }\n}\n\n.item[data-disabled] {\n opacity: 0.5;\n cursor: not-allowed;\n}\n\n.item[data-selected] {\n background-color: var(--surface-interactive-hover, #f3f4f6);\n font-weight: var(--font-weight-medium, 500);\n}\n\n.itemCheck {\n display: inline-flex;\n width: 1rem;\n height: 1rem;\n align-items: center;\n justify-content: center;\n flex-shrink: 0;\n}\n\n.itemCheckIcon {\n width: 0.875rem;\n height: 0.875rem;\n color: var(--interactive-primary-bg, var(--primary, #111827));\n}\n\n/* Empty */\n.empty {\n list-style: none;\n padding: var(--spacing-4, 1rem) var(--spacing-3, 0.75rem);\n text-align: center;\n font-size: var(--font-size-sm, 0.875rem);\n color: var(--text-secondary, #9ca3af);\n}\n\n/* Group */\n.group {\n list-style: none;\n}\n\n.group ul {\n list-style: none;\n margin: 0;\n padding: 0;\n}\n\n.groupHeading {\n padding: var(--spacing-1, 0.25rem) var(--spacing-3, 0.75rem) var(--spacing-1, 0.25rem);\n font-size: var(--font-size-xs, 0.75rem);\n font-weight: var(--font-weight-medium, 500);\n color: var(--text-secondary, #9ca3af);\n text-transform: uppercase;\n letter-spacing: 0.05em;\n}\n\n/* Separator */\n.separator {\n list-style: none;\n height: 1px;\n margin: var(--spacing-1, 0.25rem) calc(-1 * var(--spacing-1, 0.25rem));\n background-color: var(--border-default, #e5e7eb);\n}\n"
|
|
1303
1303
|
}
|
|
1304
1304
|
]
|
|
1305
1305
|
},
|
|
@@ -1324,7 +1324,7 @@
|
|
|
1324
1324
|
{
|
|
1325
1325
|
"path": "components/ui/composer/composer.module.css",
|
|
1326
1326
|
"type": "registry:ui",
|
|
1327
|
-
"content": "/* Composer\n *\n * AI-chat composer — a rounded card container holding a multi-line\n * auto-growing text field and a tools row with icon buttons, an arbitrary\n * status-chip slot, and a circular primary send button.\n *\n * Visual source: docs/design/brand-workbench/elicit-core (cbox selector)\n *\n * All values flow through CSS custom properties. No hard-coded colors or\n * magic numbers — every value traces to a design token or is documented.\n */\n\n/* ─── Root container ────────────────────────────────────────────────────── */\n\n.root {\n background: var(--surface-card, #ffffff);\n border: var(--stroke-width-thin, 1px) solid var(--border-default, #e5e7eb);\n border-radius: var(--radius-2xl, 1.5rem); /* ~24px, matches cbox prototype */\n box-shadow: var(--shadow-md, 0 4px 6px -1px rgb(0 0 0 / 0.1));\n padding: var(--spacing-3, 0.75rem) var(--spacing-4, 1rem); /* prototype 14/16/11px, snapped to 4px grid */\n display: flex;\n flex-direction: column;\n gap: 0;\n}\n\n.root[data-disabled] {\n opacity: var(--opacity-50, 0.5);\n pointer-events: none;\n}\n\n/* ─── Field row ─────────────────────────────────────────────────────────── */\n\n.fieldWrap {\n position: relative;\n /* The textarea and replica share the same box; replica drives the height */\n}\n\n/* Shared typographic baseline for both field and replica */\n.field {\n font-
|
|
1327
|
+
"content": "/* Composer\n *\n * AI-chat composer — a rounded card container holding a multi-line\n * auto-growing text field and a tools row with icon buttons, an arbitrary\n * status-chip slot, and a circular primary send button.\n *\n * Visual source: docs/design/brand-workbench/elicit-core (cbox selector)\n *\n * All values flow through CSS custom properties. No hard-coded colors or\n * magic numbers — every value traces to a design token or is documented.\n */\n\n/* ─── Root container ────────────────────────────────────────────────────── */\n\n.root {\n background: var(--surface-card, #ffffff);\n border: var(--stroke-width-thin, 1px) solid var(--border-default, #e5e7eb);\n border-radius: var(--radius-2xl, 1.5rem); /* ~24px, matches cbox prototype */\n box-shadow: var(--shadow-md, 0 4px 6px -1px rgb(0 0 0 / 0.1));\n padding: var(--spacing-3, 0.75rem) var(--spacing-4, 1rem); /* prototype 14/16/11px, snapped to 4px grid */\n display: flex;\n flex-direction: column;\n gap: 0;\n}\n\n.root[data-disabled] {\n opacity: var(--opacity-50, 0.5);\n pointer-events: none;\n}\n\n/* ─── Field row ─────────────────────────────────────────────────────────── */\n\n.fieldWrap {\n position: relative;\n /* The textarea and replica share the same box; replica drives the height */\n}\n\n/* Shared typographic baseline for both field and replica */\n.field {\n font-size: var(--font-size-base, 1rem); /* ~15px in prototype */\n line-height: var(--line-height-normal, 1.5);\n color: var(--text-primary, #111827);\n background: transparent;\n border: none;\n outline: none;\n resize: none;\n padding: 0;\n margin: 0;\n width: 100%;\n display: block;\n min-height: 22px; /* prototype: min-height 22px */\n overflow: hidden;\n}\n\n/* Hidden replica — same metrics as textarea, invisible, used for auto-grow */\n.fieldReplica {\n position: absolute;\n top: 0;\n left: 0;\n pointer-events: none;\n visibility: hidden;\n white-space: pre-wrap;\n word-break: break-word;\n overflow: hidden;\n}\n\n/* Textarea itself */\n.field:not(.fieldReplica) {\n position: relative;\n color: var(--text-primary, #111827);\n caret-color: var(--primary, #111827);\n}\n\n.field:not(.fieldReplica)::placeholder {\n color: var(--text-tertiary, #6b7280);\n}\n\n.field:not(.fieldReplica):focus-visible {\n outline: var(--focus-ring-width, 2px) solid var(--primary, #111827);\n outline-offset: var(--focus-ring-offset, 2px);\n border-radius: var(--radius-sm, 0.25rem);\n}\n\n/* ─── Toolbar row ───────────────────────────────────────────────────────── */\n\n.toolbar {\n display: flex;\n align-items: center;\n gap: var(--spacing-2, 0.5rem); /* prototype: 7px ≈ spacing-2 */\n margin-top: var(--spacing-3, 0.75rem); /* prototype 11px, snapped to 4px grid */\n}\n\n/* ─── Tool button ───────────────────────────────────────────────────────── */\n\n.toolBtn {\n width: 32px;\n height: 32px;\n border-radius: var(--radius-full, 9999px);\n border: var(--stroke-width-thin, 1px) solid var(--border-default, #e5e7eb);\n background: transparent;\n display: grid;\n place-items: center;\n color: var(--text-secondary, #374151);\n flex: none;\n cursor: pointer;\n transition:\n background-color var(--motion-duration-150, 150ms) var(--motion-easing-default, ease-in-out),\n border-color var(--motion-duration-150, 150ms) var(--motion-easing-default, ease-in-out),\n color var(--motion-duration-150, 150ms) var(--motion-easing-default, ease-in-out);\n}\n\n.toolBtn:hover:not(:disabled) {\n background: var(--surface-hover, color-mix(in srgb, var(--border-default, #e5e7eb) 40%, transparent));\n border-color: var(--border-strong, #9ca3af);\n}\n\n.toolBtn:focus-visible {\n outline: var(--focus-ring-width, 2px) solid var(--primary, #111827);\n outline-offset: var(--focus-ring-offset, 2px);\n}\n\n.toolBtn:disabled {\n opacity: var(--opacity-40, 0.4);\n cursor: not-allowed;\n}\n\n/* Icon inside tool button — 16px per prototype */\n.toolBtn > svg,\n.toolBtn > * > svg {\n width: 16px;\n height: 16px;\n}\n\n/* ─── Spacer ────────────────────────────────────────────────────────────── */\n\n.spacer {\n flex: 1;\n}\n\n/* ─── Send button ───────────────────────────────────────────────────────── */\n\n.send {\n width: 34px;\n height: 34px;\n border-radius: var(--radius-full, 9999px);\n background: var(--primary, #111827);\n color: var(--primary-foreground, #ffffff);\n display: grid;\n place-items: center;\n box-shadow: var(--shadow-sm, 0 1px 2px 0 rgb(0 0 0 / 0.05));\n flex: none;\n border: none;\n cursor: pointer;\n transition:\n background-color var(--motion-duration-150, 150ms) var(--motion-easing-default, ease-in-out),\n opacity var(--motion-duration-150, 150ms) var(--motion-easing-default, ease-in-out),\n box-shadow var(--motion-duration-150, 150ms) var(--motion-easing-default, ease-in-out);\n}\n\n.send:hover:not(:disabled) {\n background: color-mix(in srgb, var(--primary, #111827) 88%, white);\n box-shadow: var(--shadow-md, 0 4px 6px -1px rgb(0 0 0 / 0.1));\n}\n\n.send:focus-visible {\n outline: var(--focus-ring-width, 2px) solid var(--primary, #111827);\n outline-offset: var(--focus-ring-offset, 2px);\n}\n\n.send:disabled {\n opacity: var(--opacity-40, 0.4);\n cursor: not-allowed;\n}\n\n/* Icon inside send button — 17px per prototype */\n.send > svg,\n.send > * > svg {\n width: 17px;\n height: 17px;\n}\n\n/* ─── Reduced motion ────────────────────────────────────────────────────── */\n\n@media (prefers-reduced-motion: reduce) {\n .toolBtn,\n .send {\n transition: none;\n }\n}\n"
|
|
1328
1328
|
}
|
|
1329
1329
|
]
|
|
1330
1330
|
},
|
|
@@ -1800,7 +1800,7 @@
|
|
|
1800
1800
|
{
|
|
1801
1801
|
"path": "components/ui/search-input/search-input.module.css",
|
|
1802
1802
|
"type": "registry:ui",
|
|
1803
|
-
"content": "/* Search input wrapper\n *\n * The leading magnifier is provided by Input's leadingIcon prop; this\n * wrapper only exists to overlay the optional clear button on top of\n * the field when there's a value to clear. */\n.wrapper {\n position: relative;\n display: flex;\n align-items: center;\n width: 100%;\n}\n\n/* Reserve right padding on the input when the clear button is rendered\n * so the text doesn't slide under the button. */\n.inputWithClear {\n padding-right: var(--spacing-8, 2rem);\n}\n\n/* Hide browser-native search clear button — we ship our own */\n.wrapper input[type=\"search\"]::-webkit-search-cancel-button {\n display: none;\n}\n\n/* Clear button */\n.clearButton {\n position: absolute;\n right: var(--spacing-1, 0.25rem);\n display: flex;\n align-items: center;\n justify-content: center;\n width: 1.75rem;\n height: 1.75rem;\n padding: 0;\n border: none;\n border-radius: var(--radius-sm, 0.25rem);\n background: transparent;\n color: var(--text-secondary, #9ca3af);\n cursor: pointer;\n transition: color var(--motion-duration-150, 150ms) var(--motion-easing-default, ease-in-out);\n}\n\n@media (hover: hover) {\n .clearButton:hover {\n color: var(--text-primary, #111827);\n }\n}\n\n.clearButton:focus-visible {\n outline: var(--focus-ring-width, 2px) solid var(--border-focus, #111827);\n outline-offset: var(--focus-ring-offset, -2px);\n}\n\n.clearButton svg {\n width: 0.875rem;\n height: 0.875rem;\n}\n
|
|
1803
|
+
"content": "/* Search input wrapper\n *\n * The leading magnifier is provided by Input's leadingIcon prop; this\n * wrapper only exists to overlay the optional clear button on top of\n * the field when there's a value to clear. */\n.wrapper {\n position: relative;\n display: flex;\n align-items: center;\n width: 100%;\n}\n\n/* Reserve right padding on the input when the clear button is rendered\n * so the text doesn't slide under the button. */\n.inputWithClear {\n padding-right: var(--spacing-8, 2rem);\n}\n\n/* Hide browser-native search clear button — we ship our own */\n.wrapper input[type=\"search\"]::-webkit-search-cancel-button {\n display: none;\n}\n\n/* Clear button */\n.clearButton {\n position: absolute;\n right: var(--spacing-1, 0.25rem);\n display: flex;\n align-items: center;\n justify-content: center;\n width: 1.75rem;\n height: 1.75rem;\n padding: 0;\n border: none;\n border-radius: var(--radius-sm, 0.25rem);\n background: transparent;\n color: var(--text-secondary, #9ca3af);\n cursor: pointer;\n transition: color var(--motion-duration-150, 150ms) var(--motion-easing-default, ease-in-out);\n}\n\n@media (hover: hover) {\n .clearButton:hover {\n color: var(--text-primary, #111827);\n }\n}\n\n.clearButton:focus-visible {\n outline: var(--focus-ring-width, 2px) solid var(--border-focus, #111827);\n outline-offset: var(--focus-ring-offset, -2px);\n}\n\n.clearButton svg {\n width: 0.875rem;\n height: 0.875rem;\n}\n"
|
|
1804
1804
|
}
|
|
1805
1805
|
]
|
|
1806
1806
|
},
|
|
@@ -1826,7 +1826,7 @@
|
|
|
1826
1826
|
{
|
|
1827
1827
|
"path": "components/ui/password-input/password-input.module.css",
|
|
1828
1828
|
"type": "registry:ui",
|
|
1829
|
-
"content": "/* Password input wrapper */\n.wrapper {\n width: 100%;\n}\n\n.inputWrapper {\n position: relative;\n display: flex;\n align-items: center;\n}\n\n/* Input override — pad right for toggle button */\n.input {\n padding-right: var(--spacing-10, 2.5rem);\n}\n\n/* Toggle visibility button */\n.toggleButton {\n position: absolute;\n right: var(--spacing-1, 0.25rem);\n display: flex;\n align-items: center;\n justify-content: center;\n width: 1.75rem;\n height: 1.75rem;\n padding: 0;\n border: none;\n border-radius: var(--radius-sm, 0.25rem);\n background: transparent;\n color: var(--text-secondary, #9ca3af);\n cursor: pointer;\n transition: color var(--motion-duration-150, 150ms) var(--motion-easing-default, ease-in-out);\n}\n\n@media (hover: hover) {\n .toggleButton:hover {\n color: var(--text-primary, #111827);\n }\n}\n\n.toggleButton:focus-visible {\n outline: var(--focus-ring-width, 2px) solid var(--border-focus, #111827);\n outline-offset: var(--focus-ring-offset, -2px);\n}\n\n.toggleButton svg {\n width: 1rem;\n height: 1rem;\n}\n\n/* Strength meter */\n.strengthMeter {\n display: flex;\n align-items: center;\n gap: var(--spacing-2, 0.5rem);\n margin-top: var(--spacing-1, 0.25rem);\n}\n\n.strengthTrack {\n display: flex;\n flex: 1;\n gap: var(--spacing-1, 0.25rem);\n}\n\n.strengthSegment {\n height: 0.25rem;\n flex: 1;\n border-radius: var(--radius-full, 9999px);\n background-color: var(--border-default, #e5e7eb);\n transition: background-color var(--motion-duration-150, 150ms) var(--motion-easing-default, ease-in-out);\n}\n\n.strengthWeak {\n background-color: var(--border-error, #ef4444);\n}\n\n.strengthFair {\n background-color: var(--surface-warning-default, #f59e0b);\n}\n\n.strengthGood {\n background-color: var(--surface-success-default, #10b981);\n}\n\n.strengthStrong {\n background-color: var(--surface-success-default, #10b981);\n}\n\n.strengthLabel {\n font-size: var(--font-size-xs, 0.75rem);\n color: var(--text-secondary, #9ca3af);\n min-width: 3rem;\n}\n
|
|
1829
|
+
"content": "/* Password input wrapper */\n.wrapper {\n width: 100%;\n}\n\n.inputWrapper {\n position: relative;\n display: flex;\n align-items: center;\n}\n\n/* Input override — pad right for toggle button */\n.input {\n padding-right: var(--spacing-10, 2.5rem);\n}\n\n/* Toggle visibility button */\n.toggleButton {\n position: absolute;\n right: var(--spacing-1, 0.25rem);\n display: flex;\n align-items: center;\n justify-content: center;\n width: 1.75rem;\n height: 1.75rem;\n padding: 0;\n border: none;\n border-radius: var(--radius-sm, 0.25rem);\n background: transparent;\n color: var(--text-secondary, #9ca3af);\n cursor: pointer;\n transition: color var(--motion-duration-150, 150ms) var(--motion-easing-default, ease-in-out);\n}\n\n@media (hover: hover) {\n .toggleButton:hover {\n color: var(--text-primary, #111827);\n }\n}\n\n.toggleButton:focus-visible {\n outline: var(--focus-ring-width, 2px) solid var(--border-focus, #111827);\n outline-offset: var(--focus-ring-offset, -2px);\n}\n\n.toggleButton svg {\n width: 1rem;\n height: 1rem;\n}\n\n/* Strength meter */\n.strengthMeter {\n display: flex;\n align-items: center;\n gap: var(--spacing-2, 0.5rem);\n margin-top: var(--spacing-1, 0.25rem);\n}\n\n.strengthTrack {\n display: flex;\n flex: 1;\n gap: var(--spacing-1, 0.25rem);\n}\n\n.strengthSegment {\n height: 0.25rem;\n flex: 1;\n border-radius: var(--radius-full, 9999px);\n background-color: var(--border-default, #e5e7eb);\n transition: background-color var(--motion-duration-150, 150ms) var(--motion-easing-default, ease-in-out);\n}\n\n.strengthWeak {\n background-color: var(--border-error, #ef4444);\n}\n\n.strengthFair {\n background-color: var(--surface-warning-default, #f59e0b);\n}\n\n.strengthGood {\n background-color: var(--surface-success-default, #10b981);\n}\n\n.strengthStrong {\n background-color: var(--surface-success-default, #10b981);\n}\n\n.strengthLabel {\n font-size: var(--font-size-xs, 0.75rem);\n color: var(--text-secondary, #9ca3af);\n min-width: 3rem;\n}\n"
|
|
1830
1830
|
}
|
|
1831
1831
|
]
|
|
1832
1832
|
},
|
|
@@ -1923,7 +1923,7 @@
|
|
|
1923
1923
|
{
|
|
1924
1924
|
"path": "components/ui/number-input/number-input.module.css",
|
|
1925
1925
|
"type": "registry:ui",
|
|
1926
|
-
"content": "/* Number input wrapper */\n.wrapper {\n display: inline-flex;\n align-items: center;\n border: 1px solid var(--number-input-border, var(--border-default, #e5e7eb));\n border-radius: var(--radius-md, 0.375rem);\n background-color: var(--number-input-bg, var(--surface-interactive-default, #f9fafb));\n overflow: hidden;\n transition: border-color var(--motion-duration-150, 150ms) var(--motion-easing-default, ease-in-out),\n box-shadow var(--motion-duration-150, 150ms) var(--motion-easing-default, ease-in-out);\n}\n\n@media (hover: hover) {\n .button:hover {\n color: var(--text-primary, #111827);\n background-color: var(--surface-muted, #f3f4f6);\n }\n}\n\n.wrapper:focus-within {\n border-color: var(--border-focus, #111827);\n box-shadow: 0 0 0 var(--focus-ring-width, 2px) color-mix(in srgb, var(--border-focus, #111827) 15%, transparent);\n}\n\n.wrapperDisabled {\n opacity: 0.5;\n pointer-events: none;\n}\n\n/* Stepper buttons */\n.button {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 2.25rem;\n height: 2.25rem;\n padding: 0;\n border: none;\n background: transparent;\n color: var(--text-secondary, #9ca3af);\n cursor: pointer;\n flex-shrink: 0;\n transition: color var(--motion-duration-150, 150ms) var(--motion-easing-default, ease-in-out),\n background-color var(--motion-duration-150, 150ms) var(--motion-easing-default, ease-in-out);\n}\n\n.button:active {\n background-color: var(--surface-interactive-hover, #e5e7eb);\n transition: none;\n}\n\n.button:focus-visible {\n outline: var(--focus-ring-width, 2px) solid var(--border-focus, currentColor);\n outline-offset: var(--focus-ring-offset, -2px);\n}\n\n.button:disabled {\n cursor: not-allowed;\n opacity: 0.5;\n}\n\n.buttonIcon {\n width: 0.875rem;\n height: 0.875rem;\n}\n\n/* Input */\n.input {\n width: 4rem;\n height: 2.25rem;\n padding: 0;\n border: none;\n background: transparent;\n text-align: center;\n font-size: var(--font-size-sm, 0.875rem);\n color: var(--text-primary, #111827);\n outline: none;\n}\n\n.input::placeholder {\n color: var(--text-secondary, #9ca3af);\n}\n
|
|
1926
|
+
"content": "/* Number input wrapper */\n.wrapper {\n display: inline-flex;\n align-items: center;\n border: 1px solid var(--number-input-border, var(--border-default, #e5e7eb));\n border-radius: var(--radius-md, 0.375rem);\n background-color: var(--number-input-bg, var(--surface-interactive-default, #f9fafb));\n overflow: hidden;\n transition: border-color var(--motion-duration-150, 150ms) var(--motion-easing-default, ease-in-out),\n box-shadow var(--motion-duration-150, 150ms) var(--motion-easing-default, ease-in-out);\n}\n\n@media (hover: hover) {\n .button:hover {\n color: var(--text-primary, #111827);\n background-color: var(--surface-muted, #f3f4f6);\n }\n}\n\n.wrapper:focus-within {\n border-color: var(--border-focus, #111827);\n box-shadow: 0 0 0 var(--focus-ring-width, 2px) color-mix(in srgb, var(--border-focus, #111827) 15%, transparent);\n}\n\n.wrapperDisabled {\n opacity: 0.5;\n pointer-events: none;\n}\n\n/* Stepper buttons */\n.button {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 2.25rem;\n height: 2.25rem;\n padding: 0;\n border: none;\n background: transparent;\n color: var(--text-secondary, #9ca3af);\n cursor: pointer;\n flex-shrink: 0;\n transition: color var(--motion-duration-150, 150ms) var(--motion-easing-default, ease-in-out),\n background-color var(--motion-duration-150, 150ms) var(--motion-easing-default, ease-in-out);\n}\n\n.button:active {\n background-color: var(--surface-interactive-hover, #e5e7eb);\n transition: none;\n}\n\n.button:focus-visible {\n outline: var(--focus-ring-width, 2px) solid var(--border-focus, currentColor);\n outline-offset: var(--focus-ring-offset, -2px);\n}\n\n.button:disabled {\n cursor: not-allowed;\n opacity: 0.5;\n}\n\n.buttonIcon {\n width: 0.875rem;\n height: 0.875rem;\n}\n\n/* Input */\n.input {\n width: 4rem;\n height: 2.25rem;\n padding: 0;\n border: none;\n background: transparent;\n text-align: center;\n font-size: var(--font-size-sm, 0.875rem);\n color: var(--text-primary, #111827);\n outline: none;\n}\n\n.input::placeholder {\n color: var(--text-secondary, #9ca3af);\n}\n"
|
|
1927
1927
|
}
|
|
1928
1928
|
]
|
|
1929
1929
|
},
|
|
@@ -1977,7 +1977,7 @@
|
|
|
1977
1977
|
{
|
|
1978
1978
|
"path": "components/ui/otp-input/otp-input.module.css",
|
|
1979
1979
|
"type": "registry:ui",
|
|
1980
|
-
"content": "/* OTP input wrapper */\n.wrapper {\n display: inline-flex;\n gap: var(--spacing-2, 0.5rem);\n}\n\n/* Individual digit cell */\n.cell {\n width: 2.5rem;\n height: 2.75rem;\n border: 1px solid var(--otp-border, var(--border-default, #e5e7eb));\n border-radius: var(--radius-md, 0.375rem);\n background-color: var(--otp-bg, var(--surface-interactive-default, #f9fafb));\n text-align: center;\n font-size: var(--font-size-lg, 1.125rem);\n font-weight: var(--font-weight-medium, 500);\n color: var(--text-primary, #111827);\n outline: none;\n transition: border-color var(--motion-duration-150, 150ms) var(--motion-easing-default, ease-in-out),\n box-shadow var(--motion-duration-150, 150ms) var(--motion-easing-default, ease-in-out);\n}\n\n.cell::placeholder {\n color: var(--text-secondary, #9ca3af);\n}\n\n@media (hover: hover) {\n .cell:hover:not(:focus-visible):not(:disabled) {\n border-color: var(--border-strong, #d1d5db);\n }\n}\n\n.cell:focus-visible {\n border-color: var(--border-focus, #111827);\n box-shadow: 0 0 0 var(--focus-ring-width, 2px) color-mix(in srgb, var(--border-focus, #111827) 15%, transparent);\n}\n\n.cell:disabled {\n pointer-events: none;\n cursor: not-allowed;\n opacity: 0.5;\n}\n\n.cellFilled {\n border-color: var(--border-focus, #111827);\n}\n
|
|
1980
|
+
"content": "/* OTP input wrapper */\n.wrapper {\n display: inline-flex;\n gap: var(--spacing-2, 0.5rem);\n}\n\n/* Individual digit cell */\n.cell {\n width: 2.5rem;\n height: 2.75rem;\n border: 1px solid var(--otp-border, var(--border-default, #e5e7eb));\n border-radius: var(--radius-md, 0.375rem);\n background-color: var(--otp-bg, var(--surface-interactive-default, #f9fafb));\n text-align: center;\n font-size: var(--font-size-lg, 1.125rem);\n font-weight: var(--font-weight-medium, 500);\n color: var(--text-primary, #111827);\n outline: none;\n transition: border-color var(--motion-duration-150, 150ms) var(--motion-easing-default, ease-in-out),\n box-shadow var(--motion-duration-150, 150ms) var(--motion-easing-default, ease-in-out);\n}\n\n.cell::placeholder {\n color: var(--text-secondary, #9ca3af);\n}\n\n@media (hover: hover) {\n .cell:hover:not(:focus-visible):not(:disabled) {\n border-color: var(--border-strong, #d1d5db);\n }\n}\n\n.cell:focus-visible {\n border-color: var(--border-focus, #111827);\n box-shadow: 0 0 0 var(--focus-ring-width, 2px) color-mix(in srgb, var(--border-focus, #111827) 15%, transparent);\n}\n\n.cell:disabled {\n pointer-events: none;\n cursor: not-allowed;\n opacity: 0.5;\n}\n\n.cellFilled {\n border-color: var(--border-focus, #111827);\n}\n"
|
|
1981
1981
|
}
|
|
1982
1982
|
]
|
|
1983
1983
|
},
|
|
@@ -2002,7 +2002,7 @@
|
|
|
2002
2002
|
{
|
|
2003
2003
|
"path": "components/ui/tag-input/tag-input.module.css",
|
|
2004
2004
|
"type": "registry:ui",
|
|
2005
|
-
"content": "/* Tag input wrapper — styled like an Input */\n.wrapper {\n display: flex;\n flex-wrap: wrap;\n align-items: center;\n gap: var(--spacing-1, 0.25rem);\n min-height: 2.25rem;\n width: 100%;\n border-radius: var(--radius-md, 0.375rem);\n border: 1px solid var(--tag-input-border, var(--border-default, #e5e7eb));\n background-color: var(--tag-input-bg, var(--surface-interactive-default, #f9fafb));\n padding: var(--spacing-1, 0.25rem) var(--spacing-2, 0.5rem);\n cursor: text;\n transition: border-color var(--motion-duration-150, 150ms) var(--motion-easing-default, ease-in-out),\n box-shadow var(--motion-duration-150, 150ms) var(--motion-easing-default, ease-in-out);\n}\n\n@media (hover: hover) {\n .wrapper:hover:not(.wrapperFocused):not(.wrapperDisabled) {\n border-color: var(--border-strong, #d1d5db);\n }\n}\n\n.wrapperFocused {\n border-color: var(--border-focus, #111827);\n box-shadow: 0 0 0 var(--focus-ring-width, 2px) color-mix(in srgb, var(--border-focus, #111827) 15%, transparent);\n}\n\n.wrapperDisabled {\n pointer-events: none;\n cursor: not-allowed;\n opacity: 0.5;\n}\n\n/* Individual tag chip */\n.tag {\n display: inline-flex;\n align-items: center;\n gap: var(--spacing-1, 0.25rem);\n padding: calc(var(--spacing-1, 0.25rem) / 4) var(--spacing-2, 0.5rem);\n border-radius: var(--radius-full, 9999px);\n background-color: var(--surface-muted, #f3f4f6);\n border: 1px solid var(--border-default, #e5e7eb);\n font-size: var(--font-size-xs, 0.75rem);\n line-height: 1.5;\n color: var(--text-primary, #111827);\n}\n\n.tagLabel {\n white-space: nowrap;\n}\n\n.tagRemove {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 0.875rem;\n height: 0.875rem;\n padding: 0;\n border: none;\n background: transparent;\n color: var(--text-secondary, #9ca3af);\n cursor: pointer;\n border-radius: var(--radius-full, 9999px);\n transition: color var(--motion-duration-150, 150ms) var(--motion-easing-default, ease-in-out);\n}\n\n@media (hover: hover) {\n .tagRemove:hover {\n color: var(--text-primary, #111827);\n }\n}\n\n.tagRemove svg {\n width: 0.625rem;\n height: 0.625rem;\n}\n\n/* Inline text input */\n.input {\n flex: 1;\n min-width: 4rem;\n height: 1.5rem;\n padding: 0;\n border: none;\n background: transparent;\n font-size: var(--font-size-sm, 0.875rem);\n color: var(--text-primary, #111827);\n outline: none;\n}\n\n.input::placeholder {\n color: var(--text-secondary, #9ca3af);\n}\n
|
|
2005
|
+
"content": "/* Tag input wrapper — styled like an Input */\n.wrapper {\n display: flex;\n flex-wrap: wrap;\n align-items: center;\n gap: var(--spacing-1, 0.25rem);\n min-height: 2.25rem;\n width: 100%;\n border-radius: var(--radius-md, 0.375rem);\n border: 1px solid var(--tag-input-border, var(--border-default, #e5e7eb));\n background-color: var(--tag-input-bg, var(--surface-interactive-default, #f9fafb));\n padding: var(--spacing-1, 0.25rem) var(--spacing-2, 0.5rem);\n cursor: text;\n transition: border-color var(--motion-duration-150, 150ms) var(--motion-easing-default, ease-in-out),\n box-shadow var(--motion-duration-150, 150ms) var(--motion-easing-default, ease-in-out);\n}\n\n@media (hover: hover) {\n .wrapper:hover:not(.wrapperFocused):not(.wrapperDisabled) {\n border-color: var(--border-strong, #d1d5db);\n }\n}\n\n.wrapperFocused {\n border-color: var(--border-focus, #111827);\n box-shadow: 0 0 0 var(--focus-ring-width, 2px) color-mix(in srgb, var(--border-focus, #111827) 15%, transparent);\n}\n\n.wrapperDisabled {\n pointer-events: none;\n cursor: not-allowed;\n opacity: 0.5;\n}\n\n/* Individual tag chip */\n.tag {\n display: inline-flex;\n align-items: center;\n gap: var(--spacing-1, 0.25rem);\n padding: calc(var(--spacing-1, 0.25rem) / 4) var(--spacing-2, 0.5rem);\n border-radius: var(--radius-full, 9999px);\n background-color: var(--surface-muted, #f3f4f6);\n border: 1px solid var(--border-default, #e5e7eb);\n font-size: var(--font-size-xs, 0.75rem);\n line-height: 1.5;\n color: var(--text-primary, #111827);\n}\n\n.tagLabel {\n white-space: nowrap;\n}\n\n.tagRemove {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 0.875rem;\n height: 0.875rem;\n padding: 0;\n border: none;\n background: transparent;\n color: var(--text-secondary, #9ca3af);\n cursor: pointer;\n border-radius: var(--radius-full, 9999px);\n transition: color var(--motion-duration-150, 150ms) var(--motion-easing-default, ease-in-out);\n}\n\n@media (hover: hover) {\n .tagRemove:hover {\n color: var(--text-primary, #111827);\n }\n}\n\n.tagRemove svg {\n width: 0.625rem;\n height: 0.625rem;\n}\n\n/* Inline text input */\n.input {\n flex: 1;\n min-width: 4rem;\n height: 1.5rem;\n padding: 0;\n border: none;\n background: transparent;\n font-size: var(--font-size-sm, 0.875rem);\n color: var(--text-primary, #111827);\n outline: none;\n}\n\n.input::placeholder {\n color: var(--text-secondary, #9ca3af);\n}\n"
|
|
2006
2006
|
}
|
|
2007
2007
|
]
|
|
2008
2008
|
},
|
|
@@ -2103,7 +2103,7 @@
|
|
|
2103
2103
|
{
|
|
2104
2104
|
"path": "components/ui/editable-block/editable-block.module.css",
|
|
2105
2105
|
"type": "registry:ui",
|
|
2106
|
-
"content": "/* EditableBlock\n *\n * Canvas brand block — a card tile with an uppercase label header (+ done\n * check), a value body, a hover-revealed edit icon, and an editing state\n * (focus ring, inline input + save button, AI action slot).\n *\n * Visual source: docs/design/brand-workbench/journey (HTML) L274-285\n * (prototype selectors: block, bk, bv, ed, editrow, aibtn)\n *\n * All values flow through CSS custom properties. No hard-coded colors or\n * magic numbers — every value traces to a design token or is documented.\n */\n\n/* ─── Root tile ─────────────────────────────────────────────────────────── */\n\n.root {\n background: var(--surface-card, #ffffff);\n border: var(--stroke-width-thin, 1px) solid var(--hairline, rgba(0,0,0,0.06));\n border-radius: var(--radius-lg, 0.75rem);\n padding: var(--spacing-3_5, 0.875rem); /* prototype: 14px */\n box-shadow: var(--shadow-sm, 0 1px 2px 0 rgb(0 0 0 / 0.05));\n min-height: 6rem; /* prototype: 96px */\n position: relative;\n cursor: pointer;\n display: flex;\n flex-direction: column;\n transition:\n border-color var(--motion-duration-150, 150ms) var(--motion-easing-default, ease-in-out),\n box-shadow var(--motion-duration-150, 150ms) var(--motion-easing-default, ease-in-out);\n}\n\n/* ─── State: default (hover) ────────────────────────────────────────────── */\n\n.stateDefault:hover {\n border-color: var(--border-default, #e5e7eb);\n}\n\n/* Reveal edit icon on hover — use CSS opacity so resting state is still\n in the DOM (avoids SSR/hydration race on mount). */\n.stateDefault:hover .editIcon {\n opacity: var(--opacity-80, 0.8);\n}\n\n/* ─── State: done ───────────────────────────────────────────────────────── */\n\n.stateDone:hover {\n border-color: var(--border-default, #e5e7eb);\n}\n\n.stateDone:hover .editIcon {\n opacity: var(--opacity-80, 0.8);\n}\n\n/* ─── State: editing ────────────────────────────────────────────────────── */\n\n.stateEditing {\n /* Focus-ring shadow — exception per token-rules Rule 2 (focus ring variant) */\n border-color: var(--primary, #111827);\n box-shadow: 0 0 0 var(--spacing-1, 0.25rem) var(--interactive-primary-soft, color-mix(in srgb, var(--interactive-primary-bg, #111827) 12%, transparent));\n cursor: default;\n}\n\n.stateEditing .label {\n color: var(--primary, #111827);\n}\n\n/* ─── Header row ────────────────────────────────────────────────────────── */\n\n.header {\n display: flex;\n align-items: center;\n gap: var(--spacing-1_5, 0.375rem); /* prototype: 7px ≈ 1.5 × 4px */\n margin-bottom: var(--spacing-2, 0.5rem); /* prototype: 8px */\n}\n\n/* ─── Label ─────────────────────────────────────────────────────────────── */\n\n.label {\n font-size: var(--font-size-2xs, 0.65625rem); /* prototype: 10.5px */\n font-weight: 800;\n letter-spacing: 0.07em;\n text-transform: uppercase;\n color: var(--text-tertiary, #6b7280);\n transition: color var(--motion-duration-150, 150ms) var(--motion-easing-default, ease-in-out);\n}\n\n/* ─── Done check icon ───────────────────────────────────────────────────── */\n\n.doneCheck {\n display: inline-flex;\n align-items: center;\n color: var(--success, #22c55e);\n}\n\n.doneCheck > svg {\n width: var(--spacing-3, 0.75rem); /* prototype: 12px */\n height: var(--spacing-3, 0.75rem);\n stroke-width: 3;\n}\n\n/* ─── Value body ────────────────────────────────────────────────────────── */\n\n.value {\n font-size: var(--font-size-sm, 0.84375rem); /* prototype: 13.5px ≈ sm */\n color: var(--text-primary, #111827);\n line-height: var(--line-height-snug, 1.45);\n flex: 1;\n}\n\n/* ─── Hover-revealed edit icon ──────────────────────────────────────────── */\n\n.editIcon {\n position: absolute;\n top: var(--spacing-2_5, 0.6875rem); /* prototype: 11px */\n right: var(--spacing-2_5, 0.6875rem);\n display: inline-flex;\n align-items: center;\n justify-content: center;\n color: var(--text-tertiary, #6b7280);\n /* Resting state opacity=0 via CSS (visible on hover via .stateDefault:hover rule).\n Must remain in DOM at rest for accessibility & SSR hydration safety. */\n opacity: 0;\n background: none;\n border: none;\n padding: 0;\n cursor: pointer;\n transition: opacity var(--motion-duration-150, 150ms) var(--motion-easing-default, ease-in-out);\n}\n\n.editIcon:focus-visible {\n opacity: var(--opacity-80, 0.8);\n outline: var(--focus-ring-width, 2px) solid var(--primary, #111827);\n outline-offset: var(--focus-ring-offset, 2px);\n border-radius: var(--radius-sm, 0.25rem);\n}\n\n.editIcon > svg {\n width: var(--spacing-3_5, 0.875rem); /* prototype: 14px */\n height: var(--spacing-3_5, 0.875rem);\n}\n\n/* ─── Edit row (input + save button) ────────────────────────────────────── */\n\n.editRow {\n display: flex;\n gap: var(--spacing-1_5, 0.375rem); /* prototype: 7px */\n margin-top: var(--spacing-2_5, 0.625rem); /* prototype: 10px */\n}\n\n/* Inline edit input */\n.editInput {\n flex: 1;\n height: var(--spacing-8, 2rem); /* prototype: 32px */\n border-radius: var(--radius-md, 0.5rem);\n background: var(--surface-subtle, #f9fafb);\n border: var(--stroke-width-thin, 1px) solid\n color-mix(in srgb, var(--primary, #111827) 30%, transparent);\n font-
|
|
2106
|
+
"content": "/* EditableBlock\n *\n * Canvas brand block — a card tile with an uppercase label header (+ done\n * check), a value body, a hover-revealed edit icon, and an editing state\n * (focus ring, inline input + save button, AI action slot).\n *\n * Visual source: docs/design/brand-workbench/journey (HTML) L274-285\n * (prototype selectors: block, bk, bv, ed, editrow, aibtn)\n *\n * All values flow through CSS custom properties. No hard-coded colors or\n * magic numbers — every value traces to a design token or is documented.\n */\n\n/* ─── Root tile ─────────────────────────────────────────────────────────── */\n\n.root {\n background: var(--surface-card, #ffffff);\n border: var(--stroke-width-thin, 1px) solid var(--hairline, rgba(0,0,0,0.06));\n border-radius: var(--radius-lg, 0.75rem);\n padding: var(--spacing-3_5, 0.875rem); /* prototype: 14px */\n box-shadow: var(--shadow-sm, 0 1px 2px 0 rgb(0 0 0 / 0.05));\n min-height: 6rem; /* prototype: 96px */\n position: relative;\n cursor: pointer;\n display: flex;\n flex-direction: column;\n transition:\n border-color var(--motion-duration-150, 150ms) var(--motion-easing-default, ease-in-out),\n box-shadow var(--motion-duration-150, 150ms) var(--motion-easing-default, ease-in-out);\n}\n\n/* ─── State: default (hover) ────────────────────────────────────────────── */\n\n.stateDefault:hover {\n border-color: var(--border-default, #e5e7eb);\n}\n\n/* Reveal edit icon on hover — use CSS opacity so resting state is still\n in the DOM (avoids SSR/hydration race on mount). */\n.stateDefault:hover .editIcon {\n opacity: var(--opacity-80, 0.8);\n}\n\n/* ─── State: done ───────────────────────────────────────────────────────── */\n\n.stateDone:hover {\n border-color: var(--border-default, #e5e7eb);\n}\n\n.stateDone:hover .editIcon {\n opacity: var(--opacity-80, 0.8);\n}\n\n/* ─── State: editing ────────────────────────────────────────────────────── */\n\n.stateEditing {\n /* Focus-ring shadow — exception per token-rules Rule 2 (focus ring variant) */\n border-color: var(--primary, #111827);\n box-shadow: 0 0 0 var(--spacing-1, 0.25rem) var(--interactive-primary-soft, color-mix(in srgb, var(--interactive-primary-bg, #111827) 12%, transparent));\n cursor: default;\n}\n\n.stateEditing .label {\n color: var(--primary, #111827);\n}\n\n/* ─── Header row ────────────────────────────────────────────────────────── */\n\n.header {\n display: flex;\n align-items: center;\n gap: var(--spacing-1_5, 0.375rem); /* prototype: 7px ≈ 1.5 × 4px */\n margin-bottom: var(--spacing-2, 0.5rem); /* prototype: 8px */\n}\n\n/* ─── Label ─────────────────────────────────────────────────────────────── */\n\n.label {\n font-size: var(--font-size-2xs, 0.65625rem); /* prototype: 10.5px */\n font-weight: 800;\n letter-spacing: 0.07em;\n text-transform: uppercase;\n color: var(--text-tertiary, #6b7280);\n transition: color var(--motion-duration-150, 150ms) var(--motion-easing-default, ease-in-out);\n}\n\n/* ─── Done check icon ───────────────────────────────────────────────────── */\n\n.doneCheck {\n display: inline-flex;\n align-items: center;\n color: var(--success, #22c55e);\n}\n\n.doneCheck > svg {\n width: var(--spacing-3, 0.75rem); /* prototype: 12px */\n height: var(--spacing-3, 0.75rem);\n stroke-width: 3;\n}\n\n/* ─── Value body ────────────────────────────────────────────────────────── */\n\n.value {\n font-size: var(--font-size-sm, 0.84375rem); /* prototype: 13.5px ≈ sm */\n color: var(--text-primary, #111827);\n line-height: var(--line-height-snug, 1.45);\n flex: 1;\n}\n\n/* ─── Hover-revealed edit icon ──────────────────────────────────────────── */\n\n.editIcon {\n position: absolute;\n top: var(--spacing-2_5, 0.6875rem); /* prototype: 11px */\n right: var(--spacing-2_5, 0.6875rem);\n display: inline-flex;\n align-items: center;\n justify-content: center;\n color: var(--text-tertiary, #6b7280);\n /* Resting state opacity=0 via CSS (visible on hover via .stateDefault:hover rule).\n Must remain in DOM at rest for accessibility & SSR hydration safety. */\n opacity: 0;\n background: none;\n border: none;\n padding: 0;\n cursor: pointer;\n transition: opacity var(--motion-duration-150, 150ms) var(--motion-easing-default, ease-in-out);\n}\n\n.editIcon:focus-visible {\n opacity: var(--opacity-80, 0.8);\n outline: var(--focus-ring-width, 2px) solid var(--primary, #111827);\n outline-offset: var(--focus-ring-offset, 2px);\n border-radius: var(--radius-sm, 0.25rem);\n}\n\n.editIcon > svg {\n width: var(--spacing-3_5, 0.875rem); /* prototype: 14px */\n height: var(--spacing-3_5, 0.875rem);\n}\n\n/* ─── Edit row (input + save button) ────────────────────────────────────── */\n\n.editRow {\n display: flex;\n gap: var(--spacing-1_5, 0.375rem); /* prototype: 7px */\n margin-top: var(--spacing-2_5, 0.625rem); /* prototype: 10px */\n}\n\n/* Inline edit input */\n.editInput {\n flex: 1;\n height: var(--spacing-8, 2rem); /* prototype: 32px */\n border-radius: var(--radius-md, 0.5rem);\n background: var(--surface-subtle, #f9fafb);\n border: var(--stroke-width-thin, 1px) solid\n color-mix(in srgb, var(--primary, #111827) 30%, transparent);\n font-size: var(--font-size-sm, 0.84375rem); /* prototype: 13px */\n font-weight: 600;\n color: var(--text-primary, #111827);\n padding: 0 var(--spacing-2_5, 0.625rem); /* prototype: 0 10px */\n outline: none;\n}\n\n.editInput:focus-visible {\n outline: var(--focus-ring-width, 2px) solid var(--primary, #111827);\n outline-offset: var(--focus-ring-offset, 2px);\n}\n\n/* Save button (checkmark) */\n.saveButton {\n width: var(--spacing-8, 2rem); /* prototype: 32px */\n height: var(--spacing-8, 2rem);\n border-radius: var(--radius-md, 0.5rem);\n background: var(--primary, #111827);\n color: var(--primary-text, #ffffff);\n display: grid;\n place-items: center;\n flex: none;\n border: none;\n cursor: pointer;\n transition:\n background-color var(--motion-duration-150, 150ms) var(--motion-easing-default, ease-in-out),\n opacity var(--motion-duration-150, 150ms) var(--motion-easing-default, ease-in-out);\n}\n\n.saveButton:hover {\n background: color-mix(in srgb, var(--primary, #111827) 88%, white);\n}\n\n.saveButton:focus-visible {\n outline: var(--focus-ring-width, 2px) solid var(--primary, #111827);\n outline-offset: var(--focus-ring-offset, 2px);\n}\n\n.saveButton > svg {\n width: var(--spacing-3_5, 0.9375rem); /* prototype: 15px */\n height: var(--spacing-3_5, 0.9375rem);\n stroke-width: 2.4;\n}\n\n/* ─── AI action button ───────────────────────────────────────────────────── */\n\n.aiAction {\n display: inline-flex;\n align-items: center;\n gap: var(--spacing-1_5, 0.375rem); /* prototype: 6px */\n margin-top: var(--spacing-2, 0.5rem); /* prototype: 9px ≈ spacing-2 */\n font-size: var(--font-size-xs, 0.71875rem); /* prototype: 11.5px */\n font-weight: 700;\n color: var(--primary, #111827);\n background: none;\n border: none;\n cursor: pointer;\n padding: 0;\n transition: opacity var(--motion-duration-150, 150ms) var(--motion-easing-default, ease-in-out);\n}\n\n.aiAction:hover {\n opacity: var(--opacity-80, 0.8);\n}\n\n.aiAction:focus-visible {\n outline: var(--focus-ring-width, 2px) solid var(--primary, #111827);\n outline-offset: var(--focus-ring-offset, 2px);\n border-radius: var(--radius-sm, 0.25rem);\n}\n\n.aiAction > svg {\n width: var(--spacing-3, 0.8125rem); /* prototype: 13px */\n height: var(--spacing-3, 0.8125rem);\n}\n\n/* ─── Reduced motion ─────────────────────────────────────────────────────── */\n\n@media (prefers-reduced-motion: reduce) {\n .root,\n .label,\n .editIcon,\n .saveButton,\n .aiAction {\n transition: none;\n }\n}\n"
|
|
2107
2107
|
}
|
|
2108
2108
|
]
|
|
2109
2109
|
},
|
|
@@ -2506,7 +2506,7 @@
|
|
|
2506
2506
|
{
|
|
2507
2507
|
"path": "components/ui/confirm-dialog/confirm-dialog.module.css",
|
|
2508
2508
|
"type": "registry:ui",
|
|
2509
|
-
"content": "/* ConfirmDialog — destructive-action confirmation compound wrapping Dialog. */\n\n.root {\n width: 100%;\n min-width: 0;\n container-type: inline-size;\n container-name: confirm-dialog;\n}\n\n/* ── Canonical default treatment (iconTreatment unset) ─────────────────────\n * A tinted circular plate (~2.5rem, surface-*-subtle wash) stacked above the\n * title/description. This is the unchanged default rendering. */\n\n/* Header layout — plate stacked above title/description */\n.headerStack {\n display: flex;\n flex-direction: column;\n align-items: flex-start;\n gap: var(--spacing-3, 0.75rem);\n}\n\n/* Tinted circular icon plate (~2.5rem) stacked above the dialog title */\n.iconPlate {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n flex-shrink: 0;\n width: var(--spacing-10, 2.5rem);\n height: var(--spacing-10, 2.5rem);\n border-radius: 9999px;\n}\n\n.iconPlate svg {\n width: var(--spacing-5, 1.25rem);\n height: var(--spacing-5, 1.25rem);\n}\n\n.plateInfo {\n background: var(--surface-info-subtle, #f0f9ff);\n color: var(--text-info, #0369a1);\n}\n\n.plateWarning {\n background: var(--surface-warning-subtle, #fffbeb);\n color: var(--text-warning, #b45309);\n}\n\n.plateDestructive {\n background: var(--surface-error-subtle, #fef2f2);\n color: var(--text-error, #b91c1c);\n}\n\n/* ── Blessed editorial treatments (iconTreatment=\"inline\" | \"plated\") ───────\n * Brought in from the blessed admin build's confirm-dialog. Opt-in via the\n * iconTreatment prop; the canonical default (above) is unchanged. */\n\n/* Title row with leading severity icon — blessed inline treatment. */\n.titleRow {\n display: flex;\n align-items: center;\n gap: var(--spacing-2, 0.5rem);\n}\n\n/* Plated layout — opt-in via iconTreatment=\"plated\". Stacks a tinted circular\n * icon container ABOVE the title (golden organization-management Feedback\n * screen). */\n.titleRowPlated {\n display: flex;\n flex-direction: column;\n align-items: flex-start;\n gap: var(--spacing-3, 0.75rem);\n}\n\n/* Plated severity icon container — ~40px tinted circle. */\n.iconPlated {\n width: var(--confirm-dialog-plate-size, 40px);\n height: var(--confirm-dialog-plate-size, 40px);\n border-radius: var(--radius-full, 999px);\n display: grid;\n place-items: center;\n flex-shrink: 0;\n}\n\n.iconPlated svg {\n width: var(--confirm-dialog-plate-icon-size, 22px);\n height: var(--confirm-dialog-plate-icon-size, 22px);\n}\n\n/* Plated severity tints — bg uses a tinted wash of the severity token;\n * foreground uses the solid severity token. Matches prototype-overlay\n * the prototype's warning / destructive icon plates exactly. */\n.iconPlatedInfo {\n background: color-mix(in srgb, var(--accent, #0369a1) 18%, transparent);\n color: var(--accent, #0369a1);\n}\n\n.iconPlatedWarning {\n background: color-mix(in srgb, var(--warning, #b45309) 22%, transparent);\n color: var(--warning, #b45309);\n}\n\n.iconPlatedDanger {\n background: color-mix(in srgb, var(--destructive, #b91c1c) 18%, transparent);\n color: var(--destructive, #b91c1c);\n}\n\n/* Inline severity icon — sized via svg to respect Phosphor sizing contract.\n * Also serves as the legacy `.iconInfo/.iconWarning/.iconDanger` color hook for\n * theme overrides targeting the old class names. */\n.icon {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n flex-shrink: 0;\n line-height: 1;\n}\n\n.icon svg {\n width: var(--spacing-5, 1.25rem);\n height: var(--spacing-5, 1.25rem);\n}\n\n.iconInfo {\n color: var(--text-info, #0369a1);\n}\n\n.iconWarning {\n color: var(--text-warning, #b45309);\n}\n\n.iconDanger {\n color: var(--text-error, #b91c1c);\n}\n\n/* Body slot — description paragraph or richer children */\n.body {\n margin-top: var(--spacing-2, 0.5rem);\n font-size: var(--font-size-sm, 0.875rem);\n color: var(--text-secondary, #6b7280);\n line-height: var(--line-height-relaxed, 1.6);\n}\n\n.body > :first-child {\n margin-top: 0;\n}\n\n.body > :last-child {\n margin-bottom: 0;\n}\n\n/* Confirm-text gate — labeled text input between body and actions */\n.confirmGate {\n display: flex;\n flex-direction: column;\n gap: var(--spacing-1, 0.25rem);\n margin-top: var(--spacing-4, 1rem);\n}\n\n.confirmGateLabel {\n font-size: var(--font-size-sm, 0.875rem);\n color: var(--text-primary, #111827);\n font-weight: var(--font-weight-medium, 500);\n}\n\n.confirmGateInput {\n width: 100%;\n padding: var(--spacing-2, 0.5rem) var(--spacing-3, 0.75rem);\n border-radius: var(--radius-md, 0.5rem);\n border: 1px solid var(--border-default, #e5e7eb);\n background-color: var(--surface-page, #ffffff);\n color: var(--text-primary, #111827);\n font-size: var(--font-size-sm, 0.875rem);\n
|
|
2509
|
+
"content": "/* ConfirmDialog — destructive-action confirmation compound wrapping Dialog. */\n\n.root {\n width: 100%;\n min-width: 0;\n container-type: inline-size;\n container-name: confirm-dialog;\n}\n\n/* ── Canonical default treatment (iconTreatment unset) ─────────────────────\n * A tinted circular plate (~2.5rem, surface-*-subtle wash) stacked above the\n * title/description. This is the unchanged default rendering. */\n\n/* Header layout — plate stacked above title/description */\n.headerStack {\n display: flex;\n flex-direction: column;\n align-items: flex-start;\n gap: var(--spacing-3, 0.75rem);\n}\n\n/* Tinted circular icon plate (~2.5rem) stacked above the dialog title */\n.iconPlate {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n flex-shrink: 0;\n width: var(--spacing-10, 2.5rem);\n height: var(--spacing-10, 2.5rem);\n border-radius: 9999px;\n}\n\n.iconPlate svg {\n width: var(--spacing-5, 1.25rem);\n height: var(--spacing-5, 1.25rem);\n}\n\n.plateInfo {\n background: var(--surface-info-subtle, #f0f9ff);\n color: var(--text-info, #0369a1);\n}\n\n.plateWarning {\n background: var(--surface-warning-subtle, #fffbeb);\n color: var(--text-warning, #b45309);\n}\n\n.plateDestructive {\n background: var(--surface-error-subtle, #fef2f2);\n color: var(--text-error, #b91c1c);\n}\n\n/* ── Blessed editorial treatments (iconTreatment=\"inline\" | \"plated\") ───────\n * Brought in from the blessed admin build's confirm-dialog. Opt-in via the\n * iconTreatment prop; the canonical default (above) is unchanged. */\n\n/* Title row with leading severity icon — blessed inline treatment. */\n.titleRow {\n display: flex;\n align-items: center;\n gap: var(--spacing-2, 0.5rem);\n}\n\n/* Plated layout — opt-in via iconTreatment=\"plated\". Stacks a tinted circular\n * icon container ABOVE the title (golden organization-management Feedback\n * screen). */\n.titleRowPlated {\n display: flex;\n flex-direction: column;\n align-items: flex-start;\n gap: var(--spacing-3, 0.75rem);\n}\n\n/* Plated severity icon container — ~40px tinted circle. */\n.iconPlated {\n width: var(--confirm-dialog-plate-size, 40px);\n height: var(--confirm-dialog-plate-size, 40px);\n border-radius: var(--radius-full, 999px);\n display: grid;\n place-items: center;\n flex-shrink: 0;\n}\n\n.iconPlated svg {\n width: var(--confirm-dialog-plate-icon-size, 22px);\n height: var(--confirm-dialog-plate-icon-size, 22px);\n}\n\n/* Plated severity tints — bg uses a tinted wash of the severity token;\n * foreground uses the solid severity token. Matches prototype-overlay\n * the prototype's warning / destructive icon plates exactly. */\n.iconPlatedInfo {\n background: color-mix(in srgb, var(--accent, #0369a1) 18%, transparent);\n color: var(--accent, #0369a1);\n}\n\n.iconPlatedWarning {\n background: color-mix(in srgb, var(--warning, #b45309) 22%, transparent);\n color: var(--warning, #b45309);\n}\n\n.iconPlatedDanger {\n background: color-mix(in srgb, var(--destructive, #b91c1c) 18%, transparent);\n color: var(--destructive, #b91c1c);\n}\n\n/* Inline severity icon — sized via svg to respect Phosphor sizing contract.\n * Also serves as the legacy `.iconInfo/.iconWarning/.iconDanger` color hook for\n * theme overrides targeting the old class names. */\n.icon {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n flex-shrink: 0;\n line-height: 1;\n}\n\n.icon svg {\n width: var(--spacing-5, 1.25rem);\n height: var(--spacing-5, 1.25rem);\n}\n\n.iconInfo {\n color: var(--text-info, #0369a1);\n}\n\n.iconWarning {\n color: var(--text-warning, #b45309);\n}\n\n.iconDanger {\n color: var(--text-error, #b91c1c);\n}\n\n/* Body slot — description paragraph or richer children */\n.body {\n margin-top: var(--spacing-2, 0.5rem);\n font-size: var(--font-size-sm, 0.875rem);\n color: var(--text-secondary, #6b7280);\n line-height: var(--line-height-relaxed, 1.6);\n}\n\n.body > :first-child {\n margin-top: 0;\n}\n\n.body > :last-child {\n margin-bottom: 0;\n}\n\n/* Confirm-text gate — labeled text input between body and actions */\n.confirmGate {\n display: flex;\n flex-direction: column;\n gap: var(--spacing-1, 0.25rem);\n margin-top: var(--spacing-4, 1rem);\n}\n\n.confirmGateLabel {\n font-size: var(--font-size-sm, 0.875rem);\n color: var(--text-primary, #111827);\n font-weight: var(--font-weight-medium, 500);\n}\n\n.confirmGateInput {\n width: 100%;\n padding: var(--spacing-2, 0.5rem) var(--spacing-3, 0.75rem);\n border-radius: var(--radius-md, 0.5rem);\n border: 1px solid var(--border-default, #e5e7eb);\n background-color: var(--surface-page, #ffffff);\n color: var(--text-primary, #111827);\n font-size: var(--font-size-sm, 0.875rem);\n line-height: var(--line-height-normal, 1.5);\n transition: border-color var(--motion-duration-150, 150ms) var(--motion-easing-default, ease-in-out);\n}\n\n.confirmGateInput:focus-visible {\n outline: var(--focus-ring-width, 2px) solid var(--border-focus, currentColor);\n outline-offset: var(--focus-ring-offset, 2px);\n border-color: var(--border-focus, currentColor);\n}\n\n.confirmGateInput:disabled {\n opacity: 0.6;\n cursor: not-allowed;\n}\n\n/* Action row — cancel + confirm, right-aligned on wide, stacked on narrow */\n.actions {\n display: flex;\n flex-direction: row;\n justify-content: flex-end;\n align-items: center;\n gap: var(--spacing-2, 0.5rem);\n margin-top: var(--spacing-6, 1.5rem);\n}\n\n.action {\n display: inline-flex;\n}\n\n/* Inline (non-portal) surface — opt-in via mode=\"inline\". Renders the dialog\n * content card in normal flow WITHOUT Radix DialogPortal/DialogOverlay/auto\n * X-close, so consumers can stack multiple dialogs inside one shared scrim.\n * Mirrors the dialog content card visuals (surface/radius/padding/shadow) but\n * uses static positioning instead of fixed centering.\n * Default: 32rem max-width, radius-lg, surface-card, spacing-6, shadow-xl.\n * Density axis: editorial uses 480px, radius-xl, surface-card, spacing-8, shadow-lg. */\n.inlineSurface {\n position: relative;\n width: 100%;\n max-width: 32rem;\n border-radius: var(--radius-lg, 0.5rem);\n background-color: var(--surface-card, var(--surface-page, #ffffff));\n padding: var(--spacing-6, 1.5rem);\n box-shadow: var(--shadow-xl);\n}\n\n/* Editorial density: the inline confirm card carries the editorial modal\n metrics (card surface, 480px, radius-xl, spacing-8, shadow-lg) — verified\n against the blessed user-states render. */\n:global([data-density=\"editorial\"]) .inlineSurface {\n background-color: var(--surface-card);\n max-width: 480px;\n border-radius: var(--radius-xl);\n padding: var(--spacing-8);\n box-shadow: var(--shadow-lg);\n}\n\n/* Inline header — replaces DialogHeader (which depends on the dialog stylesheet). */\n.inlineHeader {\n display: flex;\n flex-direction: column;\n gap: calc(var(--spacing-1, 0.25rem) * 1.5);\n margin-bottom: var(--spacing-4, 1rem);\n}\n\n/* Inline title — replaces Radix DialogTitle (no Dialog context in inline mode).\n * Default: font-size-lg / semibold. Density axis: editorial uses font-size-2xl / 700. */\n.inlineTitle {\n font-size: var(--font-size-lg, 1.125rem);\n font-weight: var(--font-weight-semibold, 600);\n color: var(--text-primary, #111827);\n margin: 0;\n}\n\n:global([data-density=\"editorial\"]) .inlineTitle {\n font-size: var(--font-size-2xl);\n font-weight: 700;\n}\n\n/* Inline description — replaces Radix DialogDescription.\n * Default: text-secondary. Density axis: editorial uses text-tertiary. */\n.inlineDescription {\n font-size: var(--font-size-sm, 0.875rem);\n color: var(--text-secondary, #6b7280);\n margin: 0;\n}\n\n:global([data-density=\"editorial\"]) .inlineDescription {\n color: var(--text-tertiary);\n}\n\n/* Container query: stack actions vertically on narrow dialog widths */\n@container confirm-dialog (max-width: 360px) {\n .actions {\n flex-direction: column-reverse;\n align-items: stretch;\n width: 100%;\n }\n\n .actions .action {\n width: 100%;\n }\n\n .actions .action > * {\n width: 100%;\n justify-content: center;\n }\n}\n"
|
|
2510
2510
|
}
|
|
2511
2511
|
]
|
|
2512
2512
|
},
|
|
@@ -2539,7 +2539,7 @@
|
|
|
2539
2539
|
{
|
|
2540
2540
|
"path": "components/ui/data-table/data-table.module.css",
|
|
2541
2541
|
"type": "registry:ui",
|
|
2542
|
-
"content": "/* DataTable root — inline-size container for responsive collapse */\n.root {\n display: flex;\n flex-direction: column;\n width: 100%;\n min-width: 0;\n gap: var(--spacing-3, 0.75rem);\n container-type: inline-size;\n container-name: data-table;\n color: var(--text-primary, #111827);\n}\n\n/* Density axis — vertical row padding step driven by `data-density` on the\n root (or any ancestor). The three tiers map the full density spectrum:\n compact (sub-content lists), default (backward-compatible baseline), and\n editorial (generous card-like rows; high-design admin patterns).\n\n Cells consume `--dt-row-py` via the `.root td` rule below. Horizontal cell\n padding stays at TableCell's `padding: var(--spacing-3)` shorthand cascade\n — we only override the top/bottom longhand properties here, so `default`\n density renders identically to pre-density-axis markup.\n\n Themes can override per-density values via their own selectors. Example:\n [data-theme=\"entr\"] [data-density=\"editorial\"] { --dt-row-py: var(--spacing-6); } */\n.root[data-density=\"compact\"] { --dt-row-py: var(--spacing-2, 0.5rem); }\n.root[data-density=\"default\"] { --dt-row-py: var(--spacing-3, 0.75rem); }\n.root[data-density=\"editorial\"] { --dt-row-py: var(--spacing-5, 1.25rem); }\n\n/* Editorial surface treatment — bakes the editorial-admin baseline values into\n the density axis. The var() reads keep --dt-* hooks working for per-theme\n overrides; the fallbacks resolve to the editorial values when no hook is set.\n Container goes flush (radius 0, no shadow); header and rows use card/page\n surface tiers instead of transparent. */\n.root[data-density=\"editorial\"] .stickyHeader,\n.root[data-density=\"editorial\"] [data-slot=\"table-container\"] {\n border-radius: var(--dt-container-radius, 0);\n box-shadow: var(--dt-container-shadow, none);\n}\n.root[data-density=\"editorial\"] [data-slot=\"table-head\"] {\n background-color: var(--dt-header-bg, var(--surface-card));\n}\n.root[data-density=\"editorial\"] [data-slot=\"table-cell\"] {\n background-color: var(--dt-row-bg, color-mix(in srgb, var(--surface-page) 75%, var(--surface-card) 25%));\n}\n\n/* Editorial column-header treatment — uppercase, 11px, tertiary color,\n tracked type (0.08em). Anchored on .root to avoid a bare attribute selector\n (Turbopack pure-selector rule). Overrides the TableHead default styles and\n the sort-button font-weight rule below. */\n.root[data-density=\"editorial\"] th {\n font-size: var(--dt-header-font-size, 11px);\n font-weight: var(--font-weight-medium, 500);\n color: var(--text-tertiary, #6b7280);\n letter-spacing: 0.08em;\n text-transform: uppercase;\n}\n\n/* Editorial density widens horizontal cell padding (spacing-5 / 20px) to match\n the editorial-admin baseline; vertical stays driven by --dt-row-py. The\n --dt-cell-px hook lets a theme tune it; default equals the editorial value. */\n.root[data-density=\"editorial\"] td,\n.root[data-density=\"editorial\"] th {\n padding-left: var(--dt-cell-px, var(--spacing-5, 1.25rem));\n padding-right: var(--dt-cell-px, var(--spacing-5, 1.25rem));\n}\n\n/* The sort button inherits font from its <th>, but explicitly overrides\n font-weight to semibold — reset to medium for the editorial treatment. */\n.root[data-density=\"editorial\"] .sortButton {\n font-weight: var(--font-weight-medium, 500);\n}\n\n.root td {\n padding-top: var(--dt-row-py, var(--spacing-3, 0.75rem));\n padding-bottom: var(--dt-row-py, var(--spacing-3, 0.75rem));\n}\n\n/* Sticky header wrapper — toggled when stickyHeader prop is true */\n.stickyHeader {\n position: sticky;\n top: 0;\n z-index: 1;\n background: var(--surface-card, #ffffff);\n}\n\n/* Sort-bar row — the thead <tr> that houses the column headers.\n `--data-table-sort-bar-radius` controls the top-corner radius of the first\n and last <th> cells. Defaults to the container's border-radius so the sort\n bar visually follows the table card's rounded top corners.\n\n Set `--data-table-sort-bar-radius: 0` on a parent scope for the\n borderless-admin pattern — straight corners without touching the container\n itself. */\n.sortBar th:first-child {\n border-top-left-radius: var(--data-table-sort-bar-radius, var(--radius-lg, 0.5rem));\n}\n\n.sortBar th:last-child {\n border-top-right-radius: var(--data-table-sort-bar-radius, var(--radius-lg, 0.5rem));\n}\n\n/* Editorial density: the flush admin shell has straight header corners — the\n sort-bar radius defaults to 0 (still overridable via the hook). */\n.root[data-density=\"editorial\"] .sortBar th:first-child {\n border-top-left-radius: var(--data-table-sort-bar-radius, 0);\n}\n\n.root[data-density=\"editorial\"] .sortBar th:last-child {\n border-top-right-radius: var(--data-table-sort-bar-radius, 0);\n}\n\n/* Sort button — renders inside the <th> */\n.sortButton {\n display: inline-flex;\n align-items: center;\n gap: var(--spacing-1, 0.25rem);\n padding: 0;\n margin: 0;\n background: transparent;\n border: 0;\n color: inherit;\n font: inherit;\n font-weight: var(--font-weight-semibold, 600);\n cursor: pointer;\n line-height: var(--line-height-tight, 1.25);\n border-radius: var(--radius-sm, 0.25rem);\n transition:\n color var(--motion-duration-fast, 150ms)\n var(--motion-easing-standard, ease),\n background-color var(--motion-duration-fast, 150ms)\n var(--motion-easing-standard, ease);\n}\n\n.sortButton:hover {\n color: var(--text-primary, #111827);\n}\n\n.sortButton:focus-visible {\n outline: var(--focus-ring-width, 2px) solid\n var(--focus-ring-color, #2563eb);\n outline-offset: var(--focus-ring-offset, 2px);\n}\n\n.sortLabel {\n display: inline-block;\n}\n\n.sortIcon {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: var(--spacing-4, 1rem);\n height: var(--spacing-4, 1rem);\n color: var(--text-tertiary, #6b7280);\n flex-shrink: 0;\n}\n\n.sortIcon svg {\n width: 100%;\n height: 100%;\n}\n\n/* Skeleton cell fills the cell width */\n.skeletonCell {\n width: 100%;\n height: var(--spacing-4, 1rem);\n}\n\n/* Empty-row cell centers the EmptyState slot */\n.emptyCell {\n padding: var(--spacing-6, 1.5rem) var(--spacing-4, 1rem);\n text-align: center;\n}\n\n/* Footer — info on the left, controls on the right */\n.footer {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: var(--spacing-4, 1rem);\n padding: var(--spacing-2, 0.5rem) var(--spacing-1, 0.25rem);\n min-width: 0;\n flex-wrap: wrap;\n}\n\n.footerInfo {\n font-size: var(--font-size-sm, 0.875rem);\n color: var(--text-secondary, #6b7280);\n min-width: 0;\n}\n\n.footerControls {\n display: flex;\n align-items: center;\n gap: var(--spacing-4, 1rem);\n flex-wrap: wrap;\n}\n\n.pageSizeLabel {\n display: inline-flex;\n align-items: center;\n gap: var(--spacing-2, 0.5rem);\n font-size: var(--font-size-sm, 0.875rem);\n color: var(--text-secondary, #6b7280);\n}\n\n.pageSizeLabelText {\n white-space: nowrap;\n}\n\n/* Native <select> styled to match Visor input controls */\n.pageSizeSelect {\n appearance: none;\n -webkit-appearance: none;\n -moz-appearance: none;\n height: var(--spacing-8, 2rem);\n padding: 0 var(--spacing-6, 1.5rem) 0 var(--spacing-2, 0.5rem);\n border-radius: var(--radius-md, 0.375rem);\n border: 1px solid var(--border-default, #e5e7eb);\n background-color: var(--surface-card, #ffffff);\n background-image: linear-gradient(\n 45deg,\n transparent 50%,\n var(--text-tertiary, #6b7280) 50%\n ),\n linear-gradient(\n 135deg,\n var(--text-tertiary, #6b7280) 50%,\n transparent 50%\n );\n background-position:\n right var(--spacing-3, 0.75rem) center,\n right var(--spacing-2, 0.5rem) center;\n background-size:\n 5px 5px,\n 5px 5px;\n background-repeat: no-repeat;\n color: var(--text-primary, #111827);\n font-size: var(--font-size-sm, 0.875rem);\n line-height: var(--line-height-tight, 1.25);\n cursor: pointer;\n transition:\n border-color var(--motion-duration-fast, 150ms)\n var(--motion-easing-standard, ease),\n box-shadow var(--motion-duration-fast, 150ms)\n var(--motion-easing-standard, ease);\n}\n\n.pageSizeSelect:hover {\n border-color: var(--border-strong, #d1d5db);\n}\n\n.pageSizeSelect:focus-visible {\n outline: var(--focus-ring-width, 2px) solid\n var(--focus-ring-color, #2563eb);\n outline-offset: var(--focus-ring-offset, 2px);\n}\n\n.pageNav {\n display: inline-flex;\n align-items: center;\n gap: var(--spacing-2, 0.5rem);\n}\n\n.pageCounter {\n font-size: var(--font-size-sm, 0.875rem);\n color: var(--text-secondary, #6b7280);\n white-space: nowrap;\n}\n\n/* Data row — base layer for the per-row data-state / data-tone / data-clickable\n variants below. The selectors are scoped to `.dataRow` so the tone/selected\n tints never bleed onto group-head rows or skeleton/empty rows. */\n.dataRow {\n transition: background-color var(--motion-duration-fast, 150ms)\n var(--motion-easing-standard, ease);\n}\n\n/* Selected row — wires the latent `data-state=\"selected\"` attribute (already\n emitted by TanStack on selected rows) to a subtle accent fill. Fixes a\n latent bug where selection had no visual feedback. */\n.dataRow[data-state=\"selected\"] {\n background-color: var(\n --surface-selected,\n var(--surface-interactive-active, #e5e7eb)\n );\n}\n\n/* Per-row tone tints — semantic background hints for editorial status.\n Mirrors the tone token mapping used by StatusBadge / StatusDot so a\n row tinted \"live\" reads consistently with a \"live\" badge inline.\n `scheduled` and `draft` intentionally have no tint — they render on\n the default surface to keep visual signal focused on actionable rows. */\n.dataRow[data-tone=\"live\"],\n.dataRow[data-tone=\"sold\"] {\n background-color: var(--surface-success-subtle, #ecfdf5);\n}\n\n.dataRow[data-tone=\"warn\"] {\n background-color: var(--surface-warning-subtle, #fffbeb);\n}\n\n.dataRow[data-tone=\"danger\"] {\n background-color: var(--surface-error-subtle, #fef2f2);\n}\n\n.dataRow[data-tone=\"info\"] {\n background-color: var(--surface-info-subtle, #eff6ff);\n}\n\n/* Selected state should win over tone tint — selection is a stronger\n signal than editorial status. */\n.dataRow[data-state=\"selected\"][data-tone] {\n background-color: var(\n --surface-selected,\n var(--surface-interactive-active, #e5e7eb)\n );\n}\n\n/* Clickable rows — opt-in affordance when `onRowClick` is supplied. */\n.dataRow[data-clickable=\"true\"] {\n cursor: pointer;\n}\n\n.dataRow[data-clickable=\"true\"]:hover {\n background-color: var(--surface-interactive-default, #f3f4f6);\n}\n\n.dataRow[data-clickable=\"true\"]:focus-visible {\n outline: var(--focus-ring-width, 2px) solid\n var(--focus-ring-color, #2563eb);\n outline-offset: calc(var(--focus-ring-offset, 2px) * -1);\n}\n\n/* Group-head row — full-width separator inside the table body. The colSpan\n cell carries the visual; the inner span owns the sticky positioning so it\n pins to the top of the scroll container as data rows scroll beneath. */\n.groupRow {\n background-color: transparent;\n cursor: default;\n}\n\n.groupRow:hover {\n background-color: transparent;\n}\n\n.groupCell {\n padding: 0;\n}\n\n.groupLabel {\n display: flex;\n align-items: center;\n gap: var(--spacing-2, 0.5rem);\n height: 28px;\n padding: 0 var(--spacing-4, 1rem);\n background: var(--surface-subtle, #f3f4f6);\n font-size: var(--font-size-xs, 0.6875rem);\n font-weight: var(--font-weight-medium, 500);\n letter-spacing: 0.14em;\n text-transform: uppercase;\n color: var(--text-tertiary, #6b7280);\n position: sticky;\n top: 0;\n z-index: 1;\n}\n\n.groupCount {\n font-size: var(--font-size-xs, 0.6875rem);\n color: var(--text-quaternary, #9ca3af);\n font-variant-numeric: tabular-nums;\n letter-spacing: 0;\n}\n\n/* Narrow containers — stack footer sections */\n@container data-table (max-width: 560px) {\n .footer {\n flex-direction: column;\n align-items: stretch;\n }\n\n .footerControls {\n justify-content: space-between;\n }\n}\n"
|
|
2542
|
+
"content": "/* DataTable root — inline-size container for responsive collapse */\n.root {\n display: flex;\n flex-direction: column;\n width: 100%;\n min-width: 0;\n gap: var(--spacing-3, 0.75rem);\n container-type: inline-size;\n container-name: data-table;\n color: var(--text-primary, #111827);\n}\n\n/* Density axis — vertical row padding step driven by `data-density` on the\n root (or any ancestor). The three tiers map the full density spectrum:\n compact (sub-content lists), default (backward-compatible baseline), and\n editorial (generous card-like rows; high-design admin patterns).\n\n Cells consume `--dt-row-py` via the `.root td` rule below. Horizontal cell\n padding stays at TableCell's `padding: var(--spacing-3)` shorthand cascade\n — we only override the top/bottom longhand properties here, so `default`\n density renders identically to pre-density-axis markup.\n\n Themes can override per-density values via their own selectors. Example:\n [data-theme=\"entr\"] [data-density=\"editorial\"] { --dt-row-py: var(--spacing-6); } */\n.root[data-density=\"compact\"] { --dt-row-py: var(--spacing-2, 0.5rem); }\n.root[data-density=\"default\"] { --dt-row-py: var(--spacing-3, 0.75rem); }\n.root[data-density=\"editorial\"] { --dt-row-py: var(--spacing-5, 1.25rem); }\n\n/* Editorial surface treatment — bakes the editorial-admin baseline values into\n the density axis. The var() reads keep --dt-* hooks working for per-theme\n overrides; the fallbacks resolve to the editorial values when no hook is set.\n Container goes flush (radius 0, no shadow); header and rows use card/page\n surface tiers instead of transparent. */\n.root[data-density=\"editorial\"] .stickyHeader,\n.root[data-density=\"editorial\"] [data-slot=\"table-container\"] {\n border-radius: var(--dt-container-radius, 0);\n box-shadow: var(--dt-container-shadow, none);\n}\n.root[data-density=\"editorial\"] [data-slot=\"table-head\"] {\n background-color: var(--dt-header-bg, var(--surface-card));\n}\n.root[data-density=\"editorial\"] [data-slot=\"table-cell\"] {\n background-color: var(--dt-row-bg, color-mix(in srgb, var(--surface-page) 75%, var(--surface-card) 25%));\n}\n\n/* Editorial column-header treatment — uppercase, 11px, tertiary color,\n tracked type (0.08em). Anchored on .root to avoid a bare attribute selector\n (Turbopack pure-selector rule). Overrides the TableHead default styles and\n the sort-button font-weight rule below. */\n.root[data-density=\"editorial\"] th {\n font-size: var(--dt-header-font-size, 11px);\n font-weight: var(--font-weight-medium, 500);\n color: var(--text-tertiary, #6b7280);\n letter-spacing: 0.08em;\n text-transform: uppercase;\n}\n\n/* Editorial density widens horizontal cell padding (spacing-5 / 20px) to match\n the editorial-admin baseline; vertical stays driven by --dt-row-py. The\n --dt-cell-px hook lets a theme tune it; default equals the editorial value. */\n.root[data-density=\"editorial\"] td,\n.root[data-density=\"editorial\"] th {\n padding-left: var(--dt-cell-px, var(--spacing-5, 1.25rem));\n padding-right: var(--dt-cell-px, var(--spacing-5, 1.25rem));\n}\n\n/* The sort button inherits font from its <th>, but explicitly overrides\n font-weight to semibold — reset to medium for the editorial treatment. */\n.root[data-density=\"editorial\"] .sortButton {\n font-weight: var(--font-weight-medium, 500);\n}\n\n.root td {\n padding-top: var(--dt-row-py, var(--spacing-3, 0.75rem));\n padding-bottom: var(--dt-row-py, var(--spacing-3, 0.75rem));\n}\n\n/* Sticky header wrapper — toggled when stickyHeader prop is true */\n.stickyHeader {\n position: sticky;\n top: 0;\n z-index: 1;\n background: var(--surface-card, #ffffff);\n}\n\n/* Sort-bar row — the thead <tr> that houses the column headers.\n `--data-table-sort-bar-radius` controls the top-corner radius of the first\n and last <th> cells. Defaults to the container's border-radius so the sort\n bar visually follows the table card's rounded top corners.\n\n Set `--data-table-sort-bar-radius: 0` on a parent scope for the\n borderless-admin pattern — straight corners without touching the container\n itself. */\n.sortBar th:first-child {\n border-top-left-radius: var(--data-table-sort-bar-radius, var(--radius-lg, 0.5rem));\n}\n\n.sortBar th:last-child {\n border-top-right-radius: var(--data-table-sort-bar-radius, var(--radius-lg, 0.5rem));\n}\n\n/* Editorial density: the flush admin shell has straight header corners — the\n sort-bar radius defaults to 0 (still overridable via the hook). */\n.root[data-density=\"editorial\"] .sortBar th:first-child {\n border-top-left-radius: var(--data-table-sort-bar-radius, 0);\n}\n\n.root[data-density=\"editorial\"] .sortBar th:last-child {\n border-top-right-radius: var(--data-table-sort-bar-radius, 0);\n}\n\n/* Sort button — renders inside the <th> */\n.sortButton {\n display: inline-flex;\n align-items: center;\n gap: var(--spacing-1, 0.25rem);\n padding: 0;\n margin: 0;\n background: transparent;\n border: 0;\n color: inherit;\n font-weight: var(--font-weight-semibold, 600);\n cursor: pointer;\n line-height: var(--line-height-tight, 1.25);\n border-radius: var(--radius-sm, 0.25rem);\n transition:\n color var(--motion-duration-fast, 150ms)\n var(--motion-easing-standard, ease),\n background-color var(--motion-duration-fast, 150ms)\n var(--motion-easing-standard, ease);\n}\n\n.sortButton:hover {\n color: var(--text-primary, #111827);\n}\n\n.sortButton:focus-visible {\n outline: var(--focus-ring-width, 2px) solid\n var(--focus-ring-color, #2563eb);\n outline-offset: var(--focus-ring-offset, 2px);\n}\n\n.sortLabel {\n display: inline-block;\n}\n\n.sortIcon {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: var(--spacing-4, 1rem);\n height: var(--spacing-4, 1rem);\n color: var(--text-tertiary, #6b7280);\n flex-shrink: 0;\n}\n\n.sortIcon svg {\n width: 100%;\n height: 100%;\n}\n\n/* Skeleton cell fills the cell width */\n.skeletonCell {\n width: 100%;\n height: var(--spacing-4, 1rem);\n}\n\n/* Empty-row cell centers the EmptyState slot */\n.emptyCell {\n padding: var(--spacing-6, 1.5rem) var(--spacing-4, 1rem);\n text-align: center;\n}\n\n/* Footer — info on the left, controls on the right */\n.footer {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: var(--spacing-4, 1rem);\n padding: var(--spacing-2, 0.5rem) var(--spacing-1, 0.25rem);\n min-width: 0;\n flex-wrap: wrap;\n}\n\n.footerInfo {\n font-size: var(--font-size-sm, 0.875rem);\n color: var(--text-secondary, #6b7280);\n min-width: 0;\n}\n\n.footerControls {\n display: flex;\n align-items: center;\n gap: var(--spacing-4, 1rem);\n flex-wrap: wrap;\n}\n\n.pageSizeLabel {\n display: inline-flex;\n align-items: center;\n gap: var(--spacing-2, 0.5rem);\n font-size: var(--font-size-sm, 0.875rem);\n color: var(--text-secondary, #6b7280);\n}\n\n.pageSizeLabelText {\n white-space: nowrap;\n}\n\n/* Native <select> styled to match Visor input controls */\n.pageSizeSelect {\n appearance: none;\n -webkit-appearance: none;\n -moz-appearance: none;\n height: var(--spacing-8, 2rem);\n padding: 0 var(--spacing-6, 1.5rem) 0 var(--spacing-2, 0.5rem);\n border-radius: var(--radius-md, 0.375rem);\n border: 1px solid var(--border-default, #e5e7eb);\n background-color: var(--surface-card, #ffffff);\n background-image: linear-gradient(\n 45deg,\n transparent 50%,\n var(--text-tertiary, #6b7280) 50%\n ),\n linear-gradient(\n 135deg,\n var(--text-tertiary, #6b7280) 50%,\n transparent 50%\n );\n background-position:\n right var(--spacing-3, 0.75rem) center,\n right var(--spacing-2, 0.5rem) center;\n background-size:\n 5px 5px,\n 5px 5px;\n background-repeat: no-repeat;\n color: var(--text-primary, #111827);\n font-size: var(--font-size-sm, 0.875rem);\n line-height: var(--line-height-tight, 1.25);\n cursor: pointer;\n transition:\n border-color var(--motion-duration-fast, 150ms)\n var(--motion-easing-standard, ease),\n box-shadow var(--motion-duration-fast, 150ms)\n var(--motion-easing-standard, ease);\n}\n\n.pageSizeSelect:hover {\n border-color: var(--border-strong, #d1d5db);\n}\n\n.pageSizeSelect:focus-visible {\n outline: var(--focus-ring-width, 2px) solid\n var(--focus-ring-color, #2563eb);\n outline-offset: var(--focus-ring-offset, 2px);\n}\n\n.pageNav {\n display: inline-flex;\n align-items: center;\n gap: var(--spacing-2, 0.5rem);\n}\n\n.pageCounter {\n font-size: var(--font-size-sm, 0.875rem);\n color: var(--text-secondary, #6b7280);\n white-space: nowrap;\n}\n\n/* Data row — base layer for the per-row data-state / data-tone / data-clickable\n variants below. The selectors are scoped to `.dataRow` so the tone/selected\n tints never bleed onto group-head rows or skeleton/empty rows. */\n.dataRow {\n transition: background-color var(--motion-duration-fast, 150ms)\n var(--motion-easing-standard, ease);\n}\n\n/* Selected row — wires the latent `data-state=\"selected\"` attribute (already\n emitted by TanStack on selected rows) to a subtle accent fill. Fixes a\n latent bug where selection had no visual feedback. */\n.dataRow[data-state=\"selected\"] {\n background-color: var(\n --surface-selected,\n var(--surface-interactive-active, #e5e7eb)\n );\n}\n\n/* Per-row tone tints — semantic background hints for editorial status.\n Mirrors the tone token mapping used by StatusBadge / StatusDot so a\n row tinted \"live\" reads consistently with a \"live\" badge inline.\n `scheduled` and `draft` intentionally have no tint — they render on\n the default surface to keep visual signal focused on actionable rows. */\n.dataRow[data-tone=\"live\"],\n.dataRow[data-tone=\"sold\"] {\n background-color: var(--surface-success-subtle, #ecfdf5);\n}\n\n.dataRow[data-tone=\"warn\"] {\n background-color: var(--surface-warning-subtle, #fffbeb);\n}\n\n.dataRow[data-tone=\"danger\"] {\n background-color: var(--surface-error-subtle, #fef2f2);\n}\n\n.dataRow[data-tone=\"info\"] {\n background-color: var(--surface-info-subtle, #eff6ff);\n}\n\n/* Selected state should win over tone tint — selection is a stronger\n signal than editorial status. */\n.dataRow[data-state=\"selected\"][data-tone] {\n background-color: var(\n --surface-selected,\n var(--surface-interactive-active, #e5e7eb)\n );\n}\n\n/* Clickable rows — opt-in affordance when `onRowClick` is supplied. */\n.dataRow[data-clickable=\"true\"] {\n cursor: pointer;\n}\n\n.dataRow[data-clickable=\"true\"]:hover {\n background-color: var(--surface-interactive-default, #f3f4f6);\n}\n\n.dataRow[data-clickable=\"true\"]:focus-visible {\n outline: var(--focus-ring-width, 2px) solid\n var(--focus-ring-color, #2563eb);\n outline-offset: calc(var(--focus-ring-offset, 2px) * -1);\n}\n\n/* Group-head row — full-width separator inside the table body. The colSpan\n cell carries the visual; the inner span owns the sticky positioning so it\n pins to the top of the scroll container as data rows scroll beneath. */\n.groupRow {\n background-color: transparent;\n cursor: default;\n}\n\n.groupRow:hover {\n background-color: transparent;\n}\n\n.groupCell {\n padding: 0;\n}\n\n.groupLabel {\n display: flex;\n align-items: center;\n gap: var(--spacing-2, 0.5rem);\n height: 28px;\n padding: 0 var(--spacing-4, 1rem);\n background: var(--surface-subtle, #f3f4f6);\n font-size: var(--font-size-xs, 0.6875rem);\n font-weight: var(--font-weight-medium, 500);\n letter-spacing: 0.14em;\n text-transform: uppercase;\n color: var(--text-tertiary, #6b7280);\n position: sticky;\n top: 0;\n z-index: 1;\n}\n\n.groupCount {\n font-size: var(--font-size-xs, 0.6875rem);\n color: var(--text-quaternary, #9ca3af);\n font-variant-numeric: tabular-nums;\n letter-spacing: 0;\n}\n\n/* Narrow containers — stack footer sections */\n@container data-table (max-width: 560px) {\n .footer {\n flex-direction: column;\n align-items: stretch;\n }\n\n .footerControls {\n justify-content: space-between;\n }\n}\n"
|
|
2543
2543
|
}
|
|
2544
2544
|
]
|
|
2545
2545
|
},
|
|
@@ -2816,7 +2816,7 @@
|
|
|
2816
2816
|
{
|
|
2817
2817
|
"path": "components/ui/doc-nav/doc-nav.module.css",
|
|
2818
2818
|
"type": "registry:ui",
|
|
2819
|
-
"content": "/* DocNav — manifest-driven, grouped/collapsible doc navigation.\n *\n * Renders peer, collapsible groups from a manifest slice: a pinned Shared set,\n * accordion product groups (one open at a time), and an Appendix bucket for\n * ad-hoc docs. The group row wraps (flex-wrap) and is NEVER an overflow-x\n * scroll strip — the run-off-the-edge defect this component exists to kill.\n *\n * Theme-agnostic: every value references a CSS custom property token.\n */\n\n/* Root — the wrapping row of peer groups. */\n.root {\n /* Accent-pop indirection (B2): the active pill / caret / hub / pinned frame\n * all route through this single token so a consumer (DocFrame) can retint the\n * whole nav in one place. Defaults to the theme's vivid `--accent` — not\n * `--primary`, which reads dull on muted-primary themes such as Strata. */\n --doc-nav-accent: var(--accent, #2563eb);\n /* Group cluster radius — a controlled, fixed radius the doc-nav owns, NOT the\n * theme `--radius-*` scale, which decorative themes inflate far past what a\n * dense nav cluster wants (for example Strata inflates `--radius-xl` to 32px).\n * The approved design pins ~12px per theme for exactly this reason; any single\n * theme radius token renders ~6px on some themes and ~32px on others.\n * Overridable by a consumer/theme via this variable. */\n --doc-nav-group-radius: 0.75rem;\n /* Resting pill fill — a recessed well, darker than the group's `--surface-card`\n * in BOTH modes. The surface ramp inverts light↔dark (page is darkest in dark\n * but lightest in light), so a single surface token can't stay \"below\" the card;\n * mixing the card toward neutral-950 darkens it directionally in either mode.\n * Overridable by a consumer/theme. */\n --doc-nav-pill-bg: color-mix(\n in srgb,\n var(--surface-card, #111827),\n var(--color-neutral-950, #030712) 20%\n );\n display: flex;\n flex-wrap: wrap;\n align-items: flex-start;\n gap: var(--spacing-2, 0.5rem);\n /* Deliberately no overflow-x: groups wrap down, never scroll sideways. */\n}\n\n/* Group — a bordered, surface-backed cluster: header + pill row. */\n.group {\n display: inline-flex;\n flex-direction: column;\n gap: var(--spacing-2, 0.5rem);\n padding: var(--spacing-2, 0.5rem);\n border: var(--stroke-width-thin, 1px) solid\n var(--hairline, var(--border-default, #e5e7eb));\n border-radius: var(--doc-nav-group-radius, var(--radius-md, 0.375rem));\n background: var(--surface-card, #ffffff);\n}\n\n/* Pinned — the Shared group stays open; a subtle frame keyed to the group hue.\n * Routed through overridable tokens (P5) so borderless themes (Animal / ENTR)\n * can null the frame — set `--doc-nav-pin-border: transparent` and\n * `--doc-nav-pin-bg: var(--surface-card)`. Default derives from the group's\n * shared hue, not `--primary` (which read as an unwanted border on those\n * borderless themes). */\n.groupPinned {\n border-color: var(\n --doc-nav-pin-border,\n color-mix(in srgb, var(--doc-nav-group-accent, var(--info, #0ea5e9)) 32%, transparent)\n );\n background: var(\n --doc-nav-pin-bg,\n color-mix(in srgb, var(--doc-nav-group-accent, var(--info, #0ea5e9)) 6%, var(--surface-card, #ffffff))\n );\n}\n\n/* Collapsed — a group reduces to a single pill-shaped chip. */\n.groupCollapsed {\n padding: 0;\n border-color: transparent;\n background: transparent;\n}\n\n/* Header — the group label row. As a chip when collapsed, plain when open. */\n.head {\n display: inline-flex;\n align-items: center;\n gap: var(--spacing-2, 0.5rem);\n padding: var(--spacing-1, 0.25rem) var(--spacing-2, 0.5rem);\n font-family: var(--font-mono, ui-monospace, \"SFMono-Regular\", Menlo, monospace);\n font-size: var(--font-size-2xs, 0.6875rem);\n font-weight: var(--font-weight-bold, 700);\n letter-spacing: 0.14em;\n text-transform: uppercase;\n /* Collapse the label's line box to the glyph height so the all-caps text\n * optically centers against the dot/caret (matching `.pill`). Without this the\n * caps ride high — the empty descender space pushes the line-box center below\n * the visual center of the caps. */\n line-height: 1;\n color: var(--text-secondary, #4b5563);\n}\n\n/* Button variant — collapsible group heads are clickable. */\n.headButton {\n cursor: pointer;\n border: 0;\n background: transparent;\n font-family: inherit;\n transition: color var(--motion-duration-fast, 150ms)\n var(--motion-easing-standard, ease);\n}\n\n.headButton:hover {\n color: var(--text-primary, #111827);\n}\n\n.headButton:focus-visible {\n outline: var(--focus-ring-width, 2px) solid\n var(--border-focus, currentColor);\n outline-offset: var(--focus-ring-offset, 2px);\n border-radius: var(--radius-sm, 0.25rem);\n}\n\n/* Collapsed group head — reads as a resting chip. */\n.groupCollapsed .head {\n border: var(--stroke-width-thin, 1px) solid\n var(--hairline, var(--border-default, #e5e7eb));\n border-radius: var(--radius-full, 9999px);\n /* A collapsed chip stands alone in the nav row, so it carries more vertical\n * padding than the tight open-group label (the design gives it ~7px 12px). */\n padding: var(--spacing-2, 0.5rem) var(--spacing-3, 0.75rem);\n /* The chip reads as the group's card surface (matching the design's chip-bg),\n * not a lighter subtle surface — `--surface-subtle` resolves as a mid-gray in\n * dark themes. */\n background: var(--surface-card, #111827);\n}\n\n/* Caret — accent-popped fill glyph (P6). */\n.caret {\n flex-shrink: 0;\n color: var(--doc-nav-accent, var(--accent, #2563eb));\n}\n\n/* Scope dot — a per-group grouping cue, color-coded with a soft glow (P1).\n * `color` carries the group hue so `currentColor` drives both the fill and the\n * glow; a consumer overrides the whole group via `--doc-nav-group-accent`.\n * Default (product groups) is the vivid accent; pinned/appendix retint below. */\n.scopeDot {\n width: var(--spacing-2, 0.5rem);\n height: var(--spacing-2, 0.5rem);\n flex-shrink: 0;\n border-radius: var(--radius-full, 9999px);\n color: var(--doc-nav-group-accent, var(--accent, #2563eb));\n background: currentColor;\n box-shadow: 0 0 var(--spacing-2, 0.5rem)\n color-mix(in srgb, currentColor 60%, transparent);\n}\n\n/* Shared (pinned) group reads in the info hue. */\n.groupPinned .scopeDot {\n color: var(--doc-nav-group-accent, var(--info, #0ea5e9));\n}\n\n/* Appendix reads muted and un-glowed — an ad-hoc bucket, not a product. */\n.group[data-role=\"appendix\"] .scopeDot {\n color: var(--doc-nav-group-accent, var(--text-tertiary, #9ca3af));\n box-shadow: none;\n}\n\n/* Group label text. */\n.groupLabel {\n min-width: 0;\n}\n\n/* Trailing count badge — a hairline mono pill on a collapsed group (N2). */\n.count {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n flex-shrink: 0;\n min-width: var(--spacing-4, 1rem);\n padding: 0 calc(var(--spacing-1, 0.25rem) * 1.5);\n border: var(--stroke-width-thin, 1px) solid\n var(--hairline, var(--border-default, #e5e7eb));\n border-radius: var(--radius-full, 9999px);\n font-family: var(--font-mono, ui-monospace, \"SFMono-Regular\", Menlo, monospace);\n /* ~9px — a quarter down from the xs step, matching the design's tiny badge. */\n font-size: calc(var(--font-size-xs, 0.75rem) * 0.75);\n font-variant-numeric: tabular-nums;\n color: var(--text-tertiary, #9ca3af);\n}\n\n/* Pill row — wraps within the group. */\n.pills {\n display: flex;\n flex-wrap: wrap;\n gap: var(--spacing-1, 0.25rem);\n}\n\n/* Pill — a single doc link. Mono · UPPERCASE · letter-spaced (B1). */\n.pill {\n display: inline-flex;\n align-items: center;\n gap: var(--spacing-2, 0.5rem);\n padding: calc(var(--spacing-1, 0.25rem) * 1.5) var(--spacing-3, 0.75rem);\n border: var(--stroke-width-thin, 1px) solid transparent;\n border-radius: var(--radius-full, 9999px);\n background: var(--doc-nav-pill-bg, var(--surface-card, #111827));\n font-family: var(--font-mono, ui-monospace, \"SFMono-Regular\", Menlo, monospace);\n font-size: var(--font-size-2xs, 0.6875rem);\n font-weight: var(--font-weight-medium, 500);\n letter-spacing: 0.05em;\n text-transform: uppercase;\n line-height: 1;\n white-space: nowrap;\n color: var(--text-secondary, #4b5563);\n text-decoration: none;\n cursor: pointer;\n transition: color var(--motion-duration-fast, 150ms)\n var(--motion-easing-standard, ease),\n border-color var(--motion-duration-fast, 150ms)\n var(--motion-easing-standard, ease),\n background-color var(--motion-duration-fast, 150ms)\n var(--motion-easing-standard, ease);\n}\n\n.pill:hover {\n color: var(--text-primary, #111827);\n border-color: var(--hairline, var(--border-default, #e5e7eb));\n}\n\n.pill:focus-visible {\n outline: var(--focus-ring-width, 2px) solid\n var(--border-focus, currentColor);\n outline-offset: var(--focus-ring-offset, 2px);\n}\n\n/* Shared-group pills carry the group's tint at rest (P4) — hover/active win. */\n.groupPinned .pill:not(.pillActive) {\n color: var(--doc-nav-group-accent, var(--info, #0ea5e9));\n}\n\n.groupPinned .pill:not(.pillActive):hover {\n color: var(--text-primary, #111827);\n}\n\n/* Active — the current doc, resolved from currentPath. Contrast-safe (VI-612):\n * the label is `--text-primary` (always legible), NOT raw `--doc-nav-accent`,\n * which is unreadable when a theme's accent is white/near-white (Blacklight, say)\n * on a light card. The active pill reads as active via a distinct opaque surface\n * plus an accent ring blended with a hairline so it never fully vanishes. */\n.pillActive {\n color: var(--text-primary, #111827);\n border-color: color-mix(\n in srgb,\n var(--doc-nav-accent, var(--accent, #2563eb)) 55%,\n var(--hairline, var(--border-default, #e5e7eb))\n );\n background: var(\n --surface-selected,\n color-mix(\n in srgb,\n var(--surface-card, #111827),\n var(--doc-nav-accent, var(--accent, #2563eb)) 14%\n )\n );\n}\n\n/* Hub — the group's overview entry gets a leading accent dot with a glow (N1).\n * `color` carries the accent so `currentColor` drives fill + glow together. */\n.pillHub::before {\n content: \"\";\n width: calc(var(--spacing-1, 0.25rem) * 1.25);\n height: calc(var(--spacing-1, 0.25rem) * 1.25);\n flex-shrink: 0;\n border-radius: var(--radius-full, 9999px);\n color: var(--doc-nav-accent, var(--accent, #2563eb));\n background: currentColor;\n box-shadow: 0 0 var(--spacing-2, 0.5rem)\n color-mix(in srgb, currentColor 60%, transparent);\n}\n\n/* Leading order number — mono, a step under the pill (B1). */\n.pillNum {\n font-family: var(--font-mono, ui-monospace, \"SFMono-Regular\", Menlo, monospace);\n font-size: calc(var(--font-size-xs, 0.75rem) * 0.8);\n font-variant-numeric: tabular-nums;\n color: var(--text-tertiary, #9ca3af);\n}\n\n.pillActive .pillNum {\n color: var(--doc-nav-accent, var(--accent, #2563eb));\n}\n\n/* Label text. */\n.pillLabel {\n min-width: 0;\n}\n\n/* External-link badge. */\n.pillExternal {\n flex-shrink: 0;\n color: var(--text-tertiary, #9ca3af);\n}\n\n/* Visually-hidden text for assistive technology. */\n.srOnly {\n position: absolute;\n width: var(--stroke-width-thin, 1px);\n height: var(--stroke-width-thin, 1px);\n padding: 0;\n margin: calc(-1 * var(--stroke-width-thin, 1px));\n overflow: hidden;\n clip: rect(0, 0, 0, 0);\n white-space: nowrap;\n border: 0;\n}\n"
|
|
2819
|
+
"content": "/* DocNav — manifest-driven, grouped/collapsible doc navigation.\n *\n * Renders peer, collapsible groups from a manifest slice: a pinned Shared set,\n * accordion product groups (one open at a time), and an Appendix bucket for\n * ad-hoc docs. The group row wraps (flex-wrap) and is NEVER an overflow-x\n * scroll strip — the run-off-the-edge defect this component exists to kill.\n *\n * Theme-agnostic: every value references a CSS custom property token.\n */\n\n/* Root — the wrapping row of peer groups. */\n.root {\n /* Accent-pop indirection (B2): the active pill / caret / hub / pinned frame\n * all route through this single token so a consumer (DocFrame) can retint the\n * whole nav in one place. Defaults to the theme's vivid `--accent` — not\n * `--primary`, which reads dull on muted-primary themes such as Strata. */\n --doc-nav-accent: var(--accent, #2563eb);\n /* Group cluster radius — a controlled, fixed radius the doc-nav owns, NOT the\n * theme `--radius-*` scale, which decorative themes inflate far past what a\n * dense nav cluster wants (for example Strata inflates `--radius-xl` to 32px).\n * The approved design pins ~12px per theme for exactly this reason; any single\n * theme radius token renders ~6px on some themes and ~32px on others.\n * Overridable by a consumer/theme via this variable. */\n --doc-nav-group-radius: 0.75rem;\n /* Resting pill fill — a recessed well, darker than the group's `--surface-card`\n * in BOTH modes. The surface ramp inverts light↔dark (page is darkest in dark\n * but lightest in light), so a single surface token can't stay \"below\" the card;\n * mixing the card toward neutral-950 darkens it directionally in either mode.\n * Overridable by a consumer/theme. */\n --doc-nav-pill-bg: color-mix(\n in srgb,\n var(--surface-card, #111827),\n var(--color-neutral-950, #030712) 20%\n );\n display: flex;\n flex-wrap: wrap;\n align-items: flex-start;\n gap: var(--spacing-2, 0.5rem);\n /* Deliberately no overflow-x: groups wrap down, never scroll sideways. */\n}\n\n/* Group — a bordered, surface-backed cluster: header + pill row. */\n.group {\n display: inline-flex;\n flex-direction: column;\n gap: var(--spacing-2, 0.5rem);\n padding: var(--spacing-2, 0.5rem);\n border: var(--stroke-width-thin, 1px) solid\n var(--hairline, var(--border-default, #e5e7eb));\n border-radius: var(--doc-nav-group-radius, var(--radius-md, 0.375rem));\n background: var(--surface-card, #ffffff);\n}\n\n/* Pinned — the Shared group stays open; a subtle frame keyed to the group hue.\n * Routed through overridable tokens (P5) so borderless themes (Animal / ENTR)\n * can null the frame — set `--doc-nav-pin-border: transparent` and\n * `--doc-nav-pin-bg: var(--surface-card)`. Default derives from the group's\n * shared hue, not `--primary` (which read as an unwanted border on those\n * borderless themes). */\n.groupPinned {\n border-color: var(\n --doc-nav-pin-border,\n color-mix(in srgb, var(--doc-nav-group-accent, var(--info, #0ea5e9)) 32%, transparent)\n );\n background: var(\n --doc-nav-pin-bg,\n color-mix(in srgb, var(--doc-nav-group-accent, var(--info, #0ea5e9)) 6%, var(--surface-card, #ffffff))\n );\n}\n\n/* Collapsed — a group reduces to a single pill-shaped chip. */\n.groupCollapsed {\n padding: 0;\n border-color: transparent;\n background: transparent;\n}\n\n/* Header — the group label row. As a chip when collapsed, plain when open. */\n.head {\n display: inline-flex;\n align-items: center;\n gap: var(--spacing-2, 0.5rem);\n padding: var(--spacing-1, 0.25rem) var(--spacing-2, 0.5rem);\n font-family: var(--font-mono, ui-monospace, \"SFMono-Regular\", Menlo, monospace);\n font-size: var(--font-size-2xs, 0.6875rem);\n font-weight: var(--font-weight-bold, 700);\n letter-spacing: 0.14em;\n text-transform: uppercase;\n /* Collapse the label's line box to the glyph height so the all-caps text\n * optically centers against the dot/caret (matching `.pill`). Without this the\n * caps ride high — the empty descender space pushes the line-box center below\n * the visual center of the caps. */\n line-height: 1;\n color: var(--text-secondary, #4b5563);\n}\n\n/* Button variant — collapsible group heads are clickable. */\n.headButton {\n cursor: pointer;\n border: 0;\n background: transparent;\n transition: color var(--motion-duration-fast, 150ms)\n var(--motion-easing-standard, ease);\n}\n\n.headButton:hover {\n color: var(--text-primary, #111827);\n}\n\n.headButton:focus-visible {\n outline: var(--focus-ring-width, 2px) solid\n var(--border-focus, currentColor);\n outline-offset: var(--focus-ring-offset, 2px);\n border-radius: var(--radius-sm, 0.25rem);\n}\n\n/* Collapsed group head — reads as a resting chip. */\n.groupCollapsed .head {\n border: var(--stroke-width-thin, 1px) solid\n var(--hairline, var(--border-default, #e5e7eb));\n border-radius: var(--radius-full, 9999px);\n /* A collapsed chip stands alone in the nav row, so it carries more vertical\n * padding than the tight open-group label (the design gives it ~7px 12px). */\n padding: var(--spacing-2, 0.5rem) var(--spacing-3, 0.75rem);\n /* The chip reads as the group's card surface (matching the design's chip-bg),\n * not a lighter subtle surface — `--surface-subtle` resolves as a mid-gray in\n * dark themes. */\n background: var(--surface-card, #111827);\n}\n\n/* Caret — accent-popped fill glyph (P6). */\n.caret {\n flex-shrink: 0;\n color: var(--doc-nav-accent, var(--accent, #2563eb));\n}\n\n/* Scope dot — a per-group grouping cue, color-coded with a soft glow (P1).\n * `color` carries the group hue so `currentColor` drives both the fill and the\n * glow; a consumer overrides the whole group via `--doc-nav-group-accent`.\n * Default (product groups) is the vivid accent; pinned/appendix retint below. */\n.scopeDot {\n width: var(--spacing-2, 0.5rem);\n height: var(--spacing-2, 0.5rem);\n flex-shrink: 0;\n border-radius: var(--radius-full, 9999px);\n color: var(--doc-nav-group-accent, var(--accent, #2563eb));\n background: currentColor;\n box-shadow: 0 0 var(--spacing-2, 0.5rem)\n color-mix(in srgb, currentColor 60%, transparent);\n}\n\n/* Shared (pinned) group reads in the info hue. */\n.groupPinned .scopeDot {\n color: var(--doc-nav-group-accent, var(--info, #0ea5e9));\n}\n\n/* Appendix reads muted and un-glowed — an ad-hoc bucket, not a product. */\n.group[data-role=\"appendix\"] .scopeDot {\n color: var(--doc-nav-group-accent, var(--text-tertiary, #9ca3af));\n box-shadow: none;\n}\n\n/* Group label text. */\n.groupLabel {\n min-width: 0;\n}\n\n/* Trailing count badge — a hairline mono pill on a collapsed group (N2). */\n.count {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n flex-shrink: 0;\n min-width: var(--spacing-4, 1rem);\n padding: 0 calc(var(--spacing-1, 0.25rem) * 1.5);\n border: var(--stroke-width-thin, 1px) solid\n var(--hairline, var(--border-default, #e5e7eb));\n border-radius: var(--radius-full, 9999px);\n font-family: var(--font-mono, ui-monospace, \"SFMono-Regular\", Menlo, monospace);\n /* ~9px — a quarter down from the xs step, matching the design's tiny badge. */\n font-size: calc(var(--font-size-xs, 0.75rem) * 0.75);\n font-variant-numeric: tabular-nums;\n color: var(--text-tertiary, #9ca3af);\n}\n\n/* Pill row — wraps within the group. */\n.pills {\n display: flex;\n flex-wrap: wrap;\n gap: var(--spacing-1, 0.25rem);\n}\n\n/* Pill — a single doc link. Mono · UPPERCASE · letter-spaced (B1). */\n.pill {\n display: inline-flex;\n align-items: center;\n gap: var(--spacing-2, 0.5rem);\n padding: calc(var(--spacing-1, 0.25rem) * 1.5) var(--spacing-3, 0.75rem);\n border: var(--stroke-width-thin, 1px) solid transparent;\n border-radius: var(--radius-full, 9999px);\n background: var(--doc-nav-pill-bg, var(--surface-card, #111827));\n font-family: var(--font-mono, ui-monospace, \"SFMono-Regular\", Menlo, monospace);\n font-size: var(--font-size-2xs, 0.6875rem);\n font-weight: var(--font-weight-medium, 500);\n letter-spacing: 0.05em;\n text-transform: uppercase;\n line-height: 1;\n white-space: nowrap;\n color: var(--text-secondary, #4b5563);\n text-decoration: none;\n cursor: pointer;\n transition: color var(--motion-duration-fast, 150ms)\n var(--motion-easing-standard, ease),\n border-color var(--motion-duration-fast, 150ms)\n var(--motion-easing-standard, ease),\n background-color var(--motion-duration-fast, 150ms)\n var(--motion-easing-standard, ease);\n}\n\n.pill:hover {\n color: var(--text-primary, #111827);\n border-color: var(--hairline, var(--border-default, #e5e7eb));\n}\n\n.pill:focus-visible {\n outline: var(--focus-ring-width, 2px) solid\n var(--border-focus, currentColor);\n outline-offset: var(--focus-ring-offset, 2px);\n}\n\n/* Shared-group pills carry the group's tint at rest (P4) — hover/active win. */\n.groupPinned .pill:not(.pillActive) {\n color: var(--doc-nav-group-accent, var(--info, #0ea5e9));\n}\n\n.groupPinned .pill:not(.pillActive):hover {\n color: var(--text-primary, #111827);\n}\n\n/* Active — the current doc, resolved from currentPath. Contrast-safe (VI-612):\n * the label is `--text-primary` (always legible), NOT raw `--doc-nav-accent`,\n * which is unreadable when a theme's accent is white/near-white (Blacklight, say)\n * on a light card. The active pill reads as active via a distinct opaque surface\n * plus an accent ring blended with a hairline so it never fully vanishes. */\n.pillActive {\n color: var(--text-primary, #111827);\n border-color: color-mix(\n in srgb,\n var(--doc-nav-accent, var(--accent, #2563eb)) 55%,\n var(--hairline, var(--border-default, #e5e7eb))\n );\n background: var(\n --surface-selected,\n color-mix(\n in srgb,\n var(--surface-card, #111827),\n var(--doc-nav-accent, var(--accent, #2563eb)) 14%\n )\n );\n}\n\n/* Hub — the group's overview entry gets a leading accent dot with a glow (N1).\n * `color` carries the accent so `currentColor` drives fill + glow together. */\n.pillHub::before {\n content: \"\";\n width: calc(var(--spacing-1, 0.25rem) * 1.25);\n height: calc(var(--spacing-1, 0.25rem) * 1.25);\n flex-shrink: 0;\n border-radius: var(--radius-full, 9999px);\n color: var(--doc-nav-accent, var(--accent, #2563eb));\n background: currentColor;\n box-shadow: 0 0 var(--spacing-2, 0.5rem)\n color-mix(in srgb, currentColor 60%, transparent);\n}\n\n/* Leading order number — mono, a step under the pill (B1). */\n.pillNum {\n font-family: var(--font-mono, ui-monospace, \"SFMono-Regular\", Menlo, monospace);\n font-size: calc(var(--font-size-xs, 0.75rem) * 0.8);\n font-variant-numeric: tabular-nums;\n color: var(--text-tertiary, #9ca3af);\n}\n\n.pillActive .pillNum {\n color: var(--doc-nav-accent, var(--accent, #2563eb));\n}\n\n/* Label text. */\n.pillLabel {\n min-width: 0;\n}\n\n/* External-link badge. */\n.pillExternal {\n flex-shrink: 0;\n color: var(--text-tertiary, #9ca3af);\n}\n\n/* Visually-hidden text for assistive technology. */\n.srOnly {\n position: absolute;\n width: var(--stroke-width-thin, 1px);\n height: var(--stroke-width-thin, 1px);\n padding: 0;\n margin: calc(-1 * var(--stroke-width-thin, 1px));\n overflow: hidden;\n clip: rect(0, 0, 0, 0);\n white-space: nowrap;\n border: 0;\n}\n"
|
|
2820
2820
|
}
|
|
2821
2821
|
]
|
|
2822
2822
|
},
|
|
@@ -2867,7 +2867,7 @@
|
|
|
2867
2867
|
{
|
|
2868
2868
|
"path": "components/ui/fidelity-mirror/fidelity-mirror.module.css",
|
|
2869
2869
|
"type": "registry:ui",
|
|
2870
|
-
"content": "/* FidelityMirror — the design-left / built-right comparison surface.\n *\n * Renders the pure DESIGN source (left) beside the BUILT render (right) in\n * recessed capture wells, with a verdict/diff indicator, numbered delta\n * callouts, a classed delta legend, and a drag-to-reveal overlay mode. Composes\n * inside DocFrame's content, and goes full-bleed on widescreen so each pane is\n * ~50vw (the compare is meant for fullscreen monitors).\n *\n * Theme-agnostic: every value references a Visor token. The card/cluster radius\n * and the recessed well fill are component-OWNED (fixed) tokens, NOT the theme\n * `--radius-*` scale or a bare `--surface-*` token — decorative themes inflate\n * `--radius-xl` to 32px and lift `--surface-subtle` ABOVE the card in dark mode,\n * which is precisely the drift this component exists to surface.\n */\n\n/* Root — the framed compare. */\n.root {\n /* Fixed cluster radius the component OWNS — NOT the theme `--radius-*` scale,\n * which decorative themes inflate far past what a dense compare cluster wants\n * (Space inflates `--radius-xl` to 32px). Overridable by a consumer/theme. */\n --fm-radius: 0.75rem;\n --fm-well-radius: 0.625rem;\n /* Widescreen gutter/padding — the outer left/right padding AND the center\n * gutter resolve to the SAME value, so each pane is ~50vw: (100vw - 3*pad)/2. */\n --fm-pad: clamp(1.25rem, 3.2vw, 3.5rem);\n /* Recessed well fill — darker than `--surface-card` in BOTH modes (the DocNav\n * pill-bg convention). The surface ramp inverts light<->dark, so a single\n * surface token can't stay \"below\" the card; mixing the card toward\n * neutral-950 darkens it directionally in either mode. Overridable. */\n --fm-well: color-mix(\n in srgb,\n var(--surface-card, #111827),\n var(--color-neutral-950, #030712) 22%\n );\n /* Source identity hues (kept across split + overlay): design = info, built =\n * accent. These carry SOURCE identity, not decoration — do not retint. */\n --fm-design-hue: var(--info, #0ea5e9);\n --fm-built-hue: var(--accent, #2563eb);\n\n display: flex;\n flex-direction: column;\n border: var(--stroke-width-thin, 1px) solid var(--hairline, #e5e7eb);\n border-radius: var(--fm-radius);\n background: var(--surface-card, #ffffff);\n box-shadow: var(--shadow-md);\n overflow: hidden;\n font-family: var(--font-sans, system-ui, sans-serif);\n}\n\n/* Widescreen full-bleed — escape DocFrame's centered column and span the\n * viewport. Header + legend align to the panes' outer edge via `--fm-pad`; the\n * panes grid uses `gap: var(--fm-pad)` so each column resolves to ~50vw. */\n.bleed {\n width: 100vw;\n margin-left: calc(50% - 50vw);\n border-radius: 0;\n border-inline: 0;\n}\n.bleed .bar {\n padding-inline: var(--fm-pad);\n}\n.bleed .panes {\n padding-inline: var(--fm-pad);\n gap: var(--fm-pad);\n}\n.bleed .legend {\n padding-inline: var(--fm-pad);\n}\n.bleed .overlay {\n padding-inline: var(--fm-pad);\n}\n\n/* ── Header bar ──────────────────────────────────────────────────────────── */\n.bar {\n display: flex;\n align-items: center;\n gap: var(--spacing-3, 0.75rem);\n flex-wrap: wrap;\n padding: var(--spacing-3, 0.75rem) var(--spacing-4, 1rem);\n border-bottom: var(--stroke-width-thin, 1px) solid var(--hairline, #e5e7eb);\n}\n.titleWrap {\n display: inline-flex;\n flex-direction: column;\n gap: calc(var(--spacing-1, 0.25rem) * 1.5);\n min-width: 0;\n}\n.title {\n font-family: var(--font-mono, ui-monospace, \"SFMono-Regular\", Menlo, monospace);\n font-size: var(--font-size-sm, 0.8125rem);\n font-weight: var(--font-weight-bold, 700);\n letter-spacing: 0.02em;\n line-height: 1;\n color: var(--text-primary, #111827);\n}\n.subtitle {\n font-family: var(--font-mono, ui-monospace, \"SFMono-Regular\", Menlo, monospace);\n font-size: var(--font-size-2xs, 0.6875rem);\n font-weight: var(--font-weight-medium, 500);\n letter-spacing: 0.12em;\n text-transform: uppercase;\n line-height: 1;\n color: var(--text-tertiary, #9ca3af);\n}\n\n/* Spacer — pushes the status + toggle to the right edge. */\n.spacer {\n flex: 1 1 auto;\n}\n\n/* Platform chip — mono caps pill, hairline, card bg. */\n.chip {\n display: inline-flex;\n align-items: center;\n gap: var(--spacing-2, 0.5rem);\n padding: calc(var(--spacing-1, 0.25rem) * 1.25) var(--spacing-3, 0.75rem);\n border: var(--stroke-width-thin, 1px) solid var(--hairline, #e5e7eb);\n border-radius: var(--radius-full, 9999px);\n background: var(--surface-card, #ffffff);\n font-family: var(--font-mono, ui-monospace, \"SFMono-Regular\", Menlo, monospace);\n font-size: var(--font-size-2xs, 0.6875rem);\n font-weight: var(--font-weight-medium, 500);\n letter-spacing: 0.06em;\n line-height: 1;\n text-transform: uppercase;\n white-space: nowrap;\n color: var(--text-secondary, #4b5563);\n}\n.chipDot {\n width: 0.375rem;\n height: 0.375rem;\n border-radius: var(--radius-full, 9999px);\n background: var(--success, #22c55e);\n box-shadow: 0 0 0.375rem color-mix(in srgb, var(--success, #22c55e) 70%, transparent);\n}\n.chipIcon {\n width: 0.75rem;\n height: 0.75rem;\n color: var(--text-tertiary, #9ca3af);\n}\n\n/* Status pill — the diff indicator, tinted by verdict. */\n.status {\n display: inline-flex;\n align-items: center;\n gap: var(--spacing-2, 0.5rem);\n padding: calc(var(--spacing-1, 0.25rem) * 1.25) var(--spacing-3, 0.75rem);\n border: var(--stroke-width-thin, 1px) solid transparent;\n border-radius: var(--radius-full, 9999px);\n font-family: var(--font-mono, ui-monospace, \"SFMono-Regular\", Menlo, monospace);\n font-size: var(--font-size-2xs, 0.6875rem);\n font-weight: var(--font-weight-bold, 700);\n letter-spacing: 0.08em;\n line-height: 1;\n text-transform: uppercase;\n white-space: nowrap;\n}\n.status[data-verdict=\"match\"] {\n color: var(--success, #22c55e);\n border-color: color-mix(in srgb, var(--success, #22c55e) 40%, transparent);\n background: color-mix(in srgb, var(--success, #22c55e) 12%, var(--surface-card, #ffffff));\n}\n.status[data-verdict=\"drift\"] {\n color: var(--warning, #f59e0b);\n border-color: color-mix(in srgb, var(--warning, #f59e0b) 42%, transparent);\n background: color-mix(in srgb, var(--warning, #f59e0b) 12%, var(--surface-card, #ffffff));\n}\n.status[data-verdict=\"fail\"] {\n color: var(--destructive, #ef4444);\n border-color: color-mix(in srgb, var(--destructive, #ef4444) 42%, transparent);\n background: color-mix(in srgb, var(--destructive, #ef4444) 12%, var(--surface-card, #ffffff));\n}\n.statusGlyph {\n width: 0.625rem;\n height: 0.625rem;\n border-radius: var(--radius-full, 9999px);\n background: currentColor;\n box-shadow: 0 0 0.4375rem currentColor;\n}\n.score {\n font-variant-numeric: tabular-nums;\n letter-spacing: 0.02em;\n opacity: var(--opacity-80, 0.85);\n}\n\n/* Segmented compare-mode toggle — split / overlay. */\n.seg {\n display: inline-flex;\n gap: calc(var(--spacing-1, 0.25rem) * 0.5);\n padding: calc(var(--spacing-1, 0.25rem) * 0.75);\n border: var(--stroke-width-thin, 1px) solid var(--hairline, #e5e7eb);\n border-radius: var(--radius-full, 9999px);\n background: var(--fm-well);\n}\n.segBtn {\n display: inline-flex;\n align-items: center;\n gap: var(--spacing-2, 0.5rem);\n padding: calc(var(--spacing-1, 0.25rem) * 1.25) calc(var(--spacing-1, 0.25rem) * 2.5);\n border: 0;\n border-radius: var(--radius-full, 9999px);\n background: transparent;\n font-family: var(--font-mono, ui-monospace, \"SFMono-Regular\", Menlo, monospace);\n font-size: var(--font-size-2xs, 0.6875rem);\n font-weight: var(--font-weight-medium, 500);\n letter-spacing: 0.06em;\n text-transform: uppercase;\n line-height: 1;\n color: var(--text-tertiary, #9ca3af);\n cursor: pointer;\n transition: color var(--motion-duration-fast, 150ms) var(--motion-easing-standard, ease),\n background-color var(--motion-duration-fast, 150ms) var(--motion-easing-standard, ease);\n}\n.segIcon {\n width: 0.8125rem;\n height: 0.8125rem;\n}\n.segBtn[aria-pressed=\"true\"] {\n color: var(--text-primary, #111827);\n background: var(--surface-card, #ffffff);\n box-shadow: var(--shadow-md);\n}\n.segBtn:focus-visible {\n outline: var(--focus-ring-width, 2px) solid var(--border-focus, currentColor);\n outline-offset: var(--focus-ring-offset, 2px);\n}\n\n/* ── Panes: side-by-side ─────────────────────────────────────────────────── */\n.panes {\n display: grid;\n grid-template-columns: 1fr 1fr;\n gap: var(--spacing-4, 1rem);\n padding: var(--spacing-4, 1rem);\n align-items: start;\n}\n.pane {\n display: flex;\n flex-direction: column;\n gap: var(--spacing-2, 0.5rem);\n min-width: 0;\n}\n.paneLabel {\n display: inline-flex;\n align-items: center;\n gap: var(--spacing-2, 0.5rem);\n font-family: var(--font-mono, ui-monospace, \"SFMono-Regular\", Menlo, monospace);\n font-size: var(--font-size-2xs, 0.6875rem);\n font-weight: var(--font-weight-bold, 700);\n letter-spacing: 0.14em;\n text-transform: uppercase;\n line-height: 1;\n color: var(--text-secondary, #4b5563);\n}\n.scopeDot {\n width: 0.5rem;\n height: 0.5rem;\n flex-shrink: 0;\n border-radius: var(--radius-full, 9999px);\n background: currentColor;\n box-shadow: 0 0 0.5rem color-mix(in srgb, currentColor 60%, transparent);\n}\n.pane[data-side=\"design\"] .scopeDot {\n color: var(--fm-design-hue);\n}\n.pane[data-side=\"built\"] .scopeDot {\n color: var(--fm-built-hue);\n}\n.paneMeta {\n margin-left: auto;\n color: var(--text-tertiary, #9ca3af);\n letter-spacing: 0.1em;\n font-weight: var(--font-weight-medium, 500);\n}\n\n/* Capture well — the recessed frame that holds a captured surface. */\n.well {\n position: relative;\n border: var(--stroke-width-thin, 1px) solid var(--hairline, #e5e7eb);\n border-radius: var(--fm-well-radius);\n background: var(--fm-well);\n padding: var(--spacing-3, 0.75rem);\n overflow: hidden;\n}\n.pane[data-side=\"built\"] .well {\n box-shadow: inset 0 0 0 var(--stroke-width-thin, 1px)\n color-mix(in srgb, var(--fm-built-hue) 22%, transparent);\n}\n\n/* Captured media — an image or a live-route/external iframe fills the well. */\n.media {\n display: block;\n width: 100%;\n height: auto;\n border: 0;\n border-radius: calc(var(--fm-well-radius) - 0.25rem);\n}\n\n/* Device bezel — native / flutter screenshots read inside a subtle frame. */\n.bezel {\n width: 10.5rem;\n margin: 0 auto;\n border: 0.375rem solid color-mix(in srgb, var(--text-primary, #111827) 78%, transparent);\n border-radius: 1.625rem;\n overflow: hidden;\n background: var(--surface-page, #ffffff);\n box-shadow: var(--shadow-lg);\n}\n.bezel .media {\n border-radius: 0;\n}\n\n/* Delta callout marker — a numbered accent dot pinned over a drift location. */\n.delta {\n position: absolute;\n z-index: 3;\n display: grid;\n place-items: center;\n width: 1.25rem;\n height: 1.25rem;\n border-radius: var(--radius-full, 9999px);\n background: var(--warning, #f59e0b);\n color: var(--color-neutral-950, #030712);\n font-family: var(--font-mono, ui-monospace, \"SFMono-Regular\", Menlo, monospace);\n font-size: var(--font-size-2xs, 0.6875rem);\n font-weight: var(--font-weight-bold, 700);\n line-height: 1;\n box-shadow: 0 0 0 3px color-mix(in srgb, var(--warning, #f59e0b) 30%, transparent),\n var(--shadow-md);\n}\n\n/* ── Overlay / slider mode ───────────────────────────────────────────────── */\n.overlay {\n position: relative;\n padding: var(--spacing-4, 1rem);\n}\n.overlayFrame {\n position: relative;\n border: var(--stroke-width-thin, 1px) solid var(--hairline, #e5e7eb);\n border-radius: var(--fm-well-radius);\n background: var(--fm-well);\n overflow: hidden;\n}\n.layer {\n padding: var(--spacing-3, 0.75rem);\n}\n/* Clear space below the corner ribbons so they never collide with content. */\n.overlayFrame .layer {\n padding-top: var(--spacing-10, 2.5rem);\n}\n.layerTop {\n position: absolute;\n inset: 0;\n /* Revealed portion driven by `--fm-split` (design shows on the left). */\n clip-path: inset(0 calc(100% - var(--fm-split, 55%)) 0 0);\n}\n.handle {\n position: absolute;\n top: 0;\n bottom: 0;\n left: var(--fm-split, 55%);\n width: 2px;\n background: var(--accent, #2563eb);\n box-shadow: 0 0 0.625rem color-mix(in srgb, var(--accent, #2563eb) 70%, transparent);\n z-index: 4;\n}\n.grip {\n position: absolute;\n top: 50%;\n left: 50%;\n transform: translate(-50%, -50%);\n display: grid;\n place-items: center;\n width: 1.75rem;\n height: 1.75rem;\n border-radius: var(--radius-full, 9999px);\n background: var(--accent, #2563eb);\n color: var(--color-white, #ffffff);\n box-shadow: 0 0 0 4px color-mix(in srgb, var(--accent, #2563eb) 26%, transparent),\n var(--shadow-md);\n}\n.gripIcon {\n width: 0.9375rem;\n height: 0.9375rem;\n}\n.ribbon {\n position: absolute;\n z-index: 5;\n top: var(--spacing-3, 0.75rem);\n padding: var(--spacing-1, 0.25rem) var(--spacing-2, 0.5rem);\n border-radius: var(--radius-full, 9999px);\n font-family: var(--font-mono, ui-monospace, \"SFMono-Regular\", Menlo, monospace);\n font-size: calc(var(--font-size-2xs, 0.6875rem) * 0.9);\n font-weight: var(--font-weight-bold, 700);\n letter-spacing: 0.12em;\n text-transform: uppercase;\n line-height: 1;\n color: var(--color-white, #ffffff);\n}\n.ribbon[data-side=\"design\"] {\n left: var(--spacing-3, 0.75rem);\n background: color-mix(in srgb, var(--fm-design-hue) 85%, var(--color-neutral-950, #030712));\n}\n.ribbon[data-side=\"built\"] {\n right: var(--spacing-3, 0.75rem);\n background: color-mix(in srgb, var(--fm-built-hue) 85%, var(--color-neutral-950, #030712));\n}\n.range {\n width: 100%;\n margin-top: var(--spacing-3, 0.75rem);\n accent-color: var(--accent, #2563eb);\n cursor: ew-resize;\n}\n.range:focus-visible {\n outline: var(--focus-ring-width, 2px) solid var(--border-focus, currentColor);\n outline-offset: var(--focus-ring-offset, 2px);\n}\n\n/* ── Delta legend ────────────────────────────────────────────────────────── */\n.legend {\n display: flex;\n flex-direction: column;\n gap: var(--spacing-2, 0.5rem);\n padding: var(--spacing-3, 0.75rem) var(--spacing-4, 1rem);\n border-top: var(--stroke-width-thin, 1px) solid var(--hairline, #e5e7eb);\n}\n.legendHead {\n font-family: var(--font-mono, ui-monospace, \"SFMono-Regular\", Menlo, monospace);\n font-size: var(--font-size-2xs, 0.6875rem);\n font-weight: var(--font-weight-bold, 700);\n letter-spacing: 0.14em;\n text-transform: uppercase;\n color: var(--text-tertiary, #9ca3af);\n}\n.legendRow {\n display: flex;\n align-items: center;\n gap: var(--spacing-3, 0.75rem);\n}\n.legendNum {\n flex-shrink: 0;\n display: grid;\n place-items: center;\n width: 1.125rem;\n height: 1.125rem;\n border-radius: var(--radius-full, 9999px);\n background: var(--warning, #f59e0b);\n color: var(--color-neutral-950, #030712);\n font-family: var(--font-mono, ui-monospace, \"SFMono-Regular\", Menlo, monospace);\n font-size: calc(var(--font-size-2xs, 0.6875rem) * 0.9);\n font-weight: var(--font-weight-bold, 700);\n}\n.tag {\n flex-shrink: 0;\n padding: calc(var(--spacing-1, 0.25rem) * 0.75) var(--spacing-2, 0.5rem);\n border: var(--stroke-width-thin, 1px) solid var(--hairline, #e5e7eb);\n border-radius: var(--radius-sm, 0.25rem);\n background: var(--surface-subtle, #f3f4f6);\n font-family: var(--font-mono, ui-monospace, \"SFMono-Regular\", Menlo, monospace);\n font-size: calc(var(--font-size-2xs, 0.6875rem) * 0.9);\n font-weight: var(--font-weight-bold, 700);\n letter-spacing: 0.08em;\n text-transform: uppercase;\n color: var(--text-secondary, #4b5563);\n}\n.legendText {\n font-family: var(--font-mono, ui-monospace, \"SFMono-Regular\", Menlo, monospace);\n font-size: var(--font-size-sm, 0.8125rem);\n color: var(--text-secondary, #4b5563);\n}\n.legendText b {\n color: var(--text-primary, #111827);\n font-weight: var(--font-weight-bold, 700);\n}\n\n/* Visually-hidden text for assistive technology. */\n.srOnly {\n position: absolute;\n width: var(--stroke-width-thin, 1px);\n height: var(--stroke-width-thin, 1px);\n padding: 0;\n margin: calc(-1 * var(--stroke-width-thin, 1px));\n overflow: hidden;\n clip: rect(0, 0, 0, 0);\n white-space: nowrap;\n border: 0;\n}\n\n/* Responsive: panes stack under 768px (design over built) — NEVER a sideways\n * scroll strip (the defect the doc-set surfaces exist to kill). */\n@media (max-width: 767px) {\n .panes {\n grid-template-columns: 1fr;\n }\n .bar {\n gap: var(--spacing-2, 0.5rem);\n }\n}\n"
|
|
2870
|
+
"content": "/* FidelityMirror — the design-left / built-right comparison surface.\n *\n * Renders the pure DESIGN source (left) beside the BUILT render (right) in\n * recessed capture wells, with a verdict/diff indicator, numbered delta\n * callouts, a classed delta legend, and a drag-to-reveal overlay mode. Composes\n * inside DocFrame's content, and goes full-bleed on widescreen so each pane is\n * ~50vw (the compare is meant for fullscreen monitors).\n *\n * Theme-agnostic: every value references a Visor token. The card/cluster radius\n * and the recessed well fill are component-OWNED (fixed) tokens, NOT the theme\n * `--radius-*` scale or a bare `--surface-*` token — decorative themes inflate\n * `--radius-xl` to 32px and lift `--surface-subtle` ABOVE the card in dark mode,\n * which is precisely the drift this component exists to surface.\n */\n\n/* Root — the framed compare. */\n.root {\n /* Fixed cluster radius the component OWNS — NOT the theme `--radius-*` scale,\n * which decorative themes inflate far past what a dense compare cluster wants\n * (Space inflates `--radius-xl` to 32px). Overridable by a consumer/theme. */\n --fm-radius: 0.75rem;\n --fm-well-radius: 0.625rem;\n /* Widescreen gutter/padding — the outer left/right padding AND the center\n * gutter resolve to the SAME value, so each pane is ~50vw: (100vw - 3*pad)/2. */\n --fm-pad: clamp(1.25rem, 3.2vw, 3.5rem);\n /* Recessed well fill — darker than `--surface-card` in BOTH modes (the DocNav\n * pill-bg convention). The surface ramp inverts light<->dark, so a single\n * surface token can't stay \"below\" the card; mixing the card toward\n * neutral-950 darkens it directionally in either mode. Overridable. */\n --fm-well: color-mix(\n in srgb,\n var(--surface-card, #111827),\n var(--color-neutral-950, #030712) 22%\n );\n /* Source identity hues (kept across split + overlay): design = info, built =\n * accent. These carry SOURCE identity, not decoration — do not retint. */\n --fm-design-hue: var(--info, #0ea5e9);\n --fm-built-hue: var(--accent, #2563eb);\n\n display: flex;\n flex-direction: column;\n border: var(--stroke-width-thin, 1px) solid var(--hairline, #e5e7eb);\n border-radius: var(--fm-radius);\n background: var(--surface-card, #ffffff);\n box-shadow: var(--shadow-md);\n overflow: hidden;\n font-family: var(--font-sans, inherit);\n}\n\n/* Widescreen full-bleed — escape DocFrame's centered column and span the\n * viewport. Header + legend align to the panes' outer edge via `--fm-pad`; the\n * panes grid uses `gap: var(--fm-pad)` so each column resolves to ~50vw. */\n.bleed {\n width: 100vw;\n margin-left: calc(50% - 50vw);\n border-radius: 0;\n border-inline: 0;\n}\n.bleed .bar {\n padding-inline: var(--fm-pad);\n}\n.bleed .panes {\n padding-inline: var(--fm-pad);\n gap: var(--fm-pad);\n}\n.bleed .legend {\n padding-inline: var(--fm-pad);\n}\n.bleed .overlay {\n padding-inline: var(--fm-pad);\n}\n\n/* ── Header bar ──────────────────────────────────────────────────────────── */\n.bar {\n display: flex;\n align-items: center;\n gap: var(--spacing-3, 0.75rem);\n flex-wrap: wrap;\n padding: var(--spacing-3, 0.75rem) var(--spacing-4, 1rem);\n border-bottom: var(--stroke-width-thin, 1px) solid var(--hairline, #e5e7eb);\n}\n.titleWrap {\n display: inline-flex;\n flex-direction: column;\n gap: calc(var(--spacing-1, 0.25rem) * 1.5);\n min-width: 0;\n}\n.title {\n font-family: var(--font-mono, ui-monospace, \"SFMono-Regular\", Menlo, monospace);\n font-size: var(--font-size-sm, 0.8125rem);\n font-weight: var(--font-weight-bold, 700);\n letter-spacing: 0.02em;\n line-height: 1;\n color: var(--text-primary, #111827);\n}\n.subtitle {\n font-family: var(--font-mono, ui-monospace, \"SFMono-Regular\", Menlo, monospace);\n font-size: var(--font-size-2xs, 0.6875rem);\n font-weight: var(--font-weight-medium, 500);\n letter-spacing: 0.12em;\n text-transform: uppercase;\n line-height: 1;\n color: var(--text-tertiary, #9ca3af);\n}\n\n/* Spacer — pushes the status + toggle to the right edge. */\n.spacer {\n flex: 1 1 auto;\n}\n\n/* Platform chip — mono caps pill, hairline, card bg. */\n.chip {\n display: inline-flex;\n align-items: center;\n gap: var(--spacing-2, 0.5rem);\n padding: calc(var(--spacing-1, 0.25rem) * 1.25) var(--spacing-3, 0.75rem);\n border: var(--stroke-width-thin, 1px) solid var(--hairline, #e5e7eb);\n border-radius: var(--radius-full, 9999px);\n background: var(--surface-card, #ffffff);\n font-family: var(--font-mono, ui-monospace, \"SFMono-Regular\", Menlo, monospace);\n font-size: var(--font-size-2xs, 0.6875rem);\n font-weight: var(--font-weight-medium, 500);\n letter-spacing: 0.06em;\n line-height: 1;\n text-transform: uppercase;\n white-space: nowrap;\n color: var(--text-secondary, #4b5563);\n}\n.chipDot {\n width: 0.375rem;\n height: 0.375rem;\n border-radius: var(--radius-full, 9999px);\n background: var(--success, #22c55e);\n box-shadow: 0 0 0.375rem color-mix(in srgb, var(--success, #22c55e) 70%, transparent);\n}\n.chipIcon {\n width: 0.75rem;\n height: 0.75rem;\n color: var(--text-tertiary, #9ca3af);\n}\n\n/* Status pill — the diff indicator, tinted by verdict. */\n.status {\n display: inline-flex;\n align-items: center;\n gap: var(--spacing-2, 0.5rem);\n padding: calc(var(--spacing-1, 0.25rem) * 1.25) var(--spacing-3, 0.75rem);\n border: var(--stroke-width-thin, 1px) solid transparent;\n border-radius: var(--radius-full, 9999px);\n font-family: var(--font-mono, ui-monospace, \"SFMono-Regular\", Menlo, monospace);\n font-size: var(--font-size-2xs, 0.6875rem);\n font-weight: var(--font-weight-bold, 700);\n letter-spacing: 0.08em;\n line-height: 1;\n text-transform: uppercase;\n white-space: nowrap;\n}\n.status[data-verdict=\"match\"] {\n color: var(--success, #22c55e);\n border-color: color-mix(in srgb, var(--success, #22c55e) 40%, transparent);\n background: color-mix(in srgb, var(--success, #22c55e) 12%, var(--surface-card, #ffffff));\n}\n.status[data-verdict=\"drift\"] {\n color: var(--warning, #f59e0b);\n border-color: color-mix(in srgb, var(--warning, #f59e0b) 42%, transparent);\n background: color-mix(in srgb, var(--warning, #f59e0b) 12%, var(--surface-card, #ffffff));\n}\n.status[data-verdict=\"fail\"] {\n color: var(--destructive, #ef4444);\n border-color: color-mix(in srgb, var(--destructive, #ef4444) 42%, transparent);\n background: color-mix(in srgb, var(--destructive, #ef4444) 12%, var(--surface-card, #ffffff));\n}\n.statusGlyph {\n width: 0.625rem;\n height: 0.625rem;\n border-radius: var(--radius-full, 9999px);\n background: currentColor;\n box-shadow: 0 0 0.4375rem currentColor;\n}\n.score {\n font-variant-numeric: tabular-nums;\n letter-spacing: 0.02em;\n opacity: var(--opacity-80, 0.85);\n}\n\n/* Segmented compare-mode toggle — split / overlay. */\n.seg {\n display: inline-flex;\n gap: calc(var(--spacing-1, 0.25rem) * 0.5);\n padding: calc(var(--spacing-1, 0.25rem) * 0.75);\n border: var(--stroke-width-thin, 1px) solid var(--hairline, #e5e7eb);\n border-radius: var(--radius-full, 9999px);\n background: var(--fm-well);\n}\n.segBtn {\n display: inline-flex;\n align-items: center;\n gap: var(--spacing-2, 0.5rem);\n padding: calc(var(--spacing-1, 0.25rem) * 1.25) calc(var(--spacing-1, 0.25rem) * 2.5);\n border: 0;\n border-radius: var(--radius-full, 9999px);\n background: transparent;\n font-family: var(--font-mono, ui-monospace, \"SFMono-Regular\", Menlo, monospace);\n font-size: var(--font-size-2xs, 0.6875rem);\n font-weight: var(--font-weight-medium, 500);\n letter-spacing: 0.06em;\n text-transform: uppercase;\n line-height: 1;\n color: var(--text-tertiary, #9ca3af);\n cursor: pointer;\n transition: color var(--motion-duration-fast, 150ms) var(--motion-easing-standard, ease),\n background-color var(--motion-duration-fast, 150ms) var(--motion-easing-standard, ease);\n}\n.segIcon {\n width: 0.8125rem;\n height: 0.8125rem;\n}\n.segBtn[aria-pressed=\"true\"] {\n color: var(--text-primary, #111827);\n background: var(--surface-card, #ffffff);\n box-shadow: var(--shadow-md);\n}\n.segBtn:focus-visible {\n outline: var(--focus-ring-width, 2px) solid var(--border-focus, currentColor);\n outline-offset: var(--focus-ring-offset, 2px);\n}\n\n/* ── Panes: side-by-side ─────────────────────────────────────────────────── */\n.panes {\n display: grid;\n grid-template-columns: 1fr 1fr;\n gap: var(--spacing-4, 1rem);\n padding: var(--spacing-4, 1rem);\n align-items: start;\n}\n.pane {\n display: flex;\n flex-direction: column;\n gap: var(--spacing-2, 0.5rem);\n min-width: 0;\n}\n.paneLabel {\n display: inline-flex;\n align-items: center;\n gap: var(--spacing-2, 0.5rem);\n font-family: var(--font-mono, ui-monospace, \"SFMono-Regular\", Menlo, monospace);\n font-size: var(--font-size-2xs, 0.6875rem);\n font-weight: var(--font-weight-bold, 700);\n letter-spacing: 0.14em;\n text-transform: uppercase;\n line-height: 1;\n color: var(--text-secondary, #4b5563);\n}\n.scopeDot {\n width: 0.5rem;\n height: 0.5rem;\n flex-shrink: 0;\n border-radius: var(--radius-full, 9999px);\n background: currentColor;\n box-shadow: 0 0 0.5rem color-mix(in srgb, currentColor 60%, transparent);\n}\n.pane[data-side=\"design\"] .scopeDot {\n color: var(--fm-design-hue);\n}\n.pane[data-side=\"built\"] .scopeDot {\n color: var(--fm-built-hue);\n}\n.paneMeta {\n margin-left: auto;\n color: var(--text-tertiary, #9ca3af);\n letter-spacing: 0.1em;\n font-weight: var(--font-weight-medium, 500);\n}\n\n/* Capture well — the recessed frame that holds a captured surface. */\n.well {\n position: relative;\n border: var(--stroke-width-thin, 1px) solid var(--hairline, #e5e7eb);\n border-radius: var(--fm-well-radius);\n background: var(--fm-well);\n padding: var(--spacing-3, 0.75rem);\n overflow: hidden;\n}\n.pane[data-side=\"built\"] .well {\n box-shadow: inset 0 0 0 var(--stroke-width-thin, 1px)\n color-mix(in srgb, var(--fm-built-hue) 22%, transparent);\n}\n\n/* Captured media — an image or a live-route/external iframe fills the well. */\n.media {\n display: block;\n width: 100%;\n height: auto;\n border: 0;\n border-radius: calc(var(--fm-well-radius) - 0.25rem);\n}\n\n/* Device bezel — native / flutter screenshots read inside a subtle frame. */\n.bezel {\n width: 10.5rem;\n margin: 0 auto;\n border: 0.375rem solid color-mix(in srgb, var(--text-primary, #111827) 78%, transparent);\n border-radius: 1.625rem;\n overflow: hidden;\n background: var(--surface-page, #ffffff);\n box-shadow: var(--shadow-lg);\n}\n.bezel .media {\n border-radius: 0;\n}\n\n/* Delta callout marker — a numbered accent dot pinned over a drift location. */\n.delta {\n position: absolute;\n z-index: 3;\n display: grid;\n place-items: center;\n width: 1.25rem;\n height: 1.25rem;\n border-radius: var(--radius-full, 9999px);\n background: var(--warning, #f59e0b);\n color: var(--color-neutral-950, #030712);\n font-family: var(--font-mono, ui-monospace, \"SFMono-Regular\", Menlo, monospace);\n font-size: var(--font-size-2xs, 0.6875rem);\n font-weight: var(--font-weight-bold, 700);\n line-height: 1;\n box-shadow: 0 0 0 3px color-mix(in srgb, var(--warning, #f59e0b) 30%, transparent),\n var(--shadow-md);\n}\n\n/* ── Overlay / slider mode ───────────────────────────────────────────────── */\n.overlay {\n position: relative;\n padding: var(--spacing-4, 1rem);\n}\n.overlayFrame {\n position: relative;\n border: var(--stroke-width-thin, 1px) solid var(--hairline, #e5e7eb);\n border-radius: var(--fm-well-radius);\n background: var(--fm-well);\n overflow: hidden;\n}\n.layer {\n padding: var(--spacing-3, 0.75rem);\n}\n/* Clear space below the corner ribbons so they never collide with content. */\n.overlayFrame .layer {\n padding-top: var(--spacing-10, 2.5rem);\n}\n.layerTop {\n position: absolute;\n inset: 0;\n /* Revealed portion driven by `--fm-split` (design shows on the left). */\n clip-path: inset(0 calc(100% - var(--fm-split, 55%)) 0 0);\n}\n.handle {\n position: absolute;\n top: 0;\n bottom: 0;\n left: var(--fm-split, 55%);\n width: 2px;\n background: var(--accent, #2563eb);\n box-shadow: 0 0 0.625rem color-mix(in srgb, var(--accent, #2563eb) 70%, transparent);\n z-index: 4;\n}\n.grip {\n position: absolute;\n top: 50%;\n left: 50%;\n transform: translate(-50%, -50%);\n display: grid;\n place-items: center;\n width: 1.75rem;\n height: 1.75rem;\n border-radius: var(--radius-full, 9999px);\n background: var(--accent, #2563eb);\n color: var(--color-white, #ffffff);\n box-shadow: 0 0 0 4px color-mix(in srgb, var(--accent, #2563eb) 26%, transparent),\n var(--shadow-md);\n}\n.gripIcon {\n width: 0.9375rem;\n height: 0.9375rem;\n}\n.ribbon {\n position: absolute;\n z-index: 5;\n top: var(--spacing-3, 0.75rem);\n padding: var(--spacing-1, 0.25rem) var(--spacing-2, 0.5rem);\n border-radius: var(--radius-full, 9999px);\n font-family: var(--font-mono, ui-monospace, \"SFMono-Regular\", Menlo, monospace);\n font-size: calc(var(--font-size-2xs, 0.6875rem) * 0.9);\n font-weight: var(--font-weight-bold, 700);\n letter-spacing: 0.12em;\n text-transform: uppercase;\n line-height: 1;\n color: var(--color-white, #ffffff);\n}\n.ribbon[data-side=\"design\"] {\n left: var(--spacing-3, 0.75rem);\n background: color-mix(in srgb, var(--fm-design-hue) 85%, var(--color-neutral-950, #030712));\n}\n.ribbon[data-side=\"built\"] {\n right: var(--spacing-3, 0.75rem);\n background: color-mix(in srgb, var(--fm-built-hue) 85%, var(--color-neutral-950, #030712));\n}\n.range {\n width: 100%;\n margin-top: var(--spacing-3, 0.75rem);\n accent-color: var(--accent, #2563eb);\n cursor: ew-resize;\n}\n.range:focus-visible {\n outline: var(--focus-ring-width, 2px) solid var(--border-focus, currentColor);\n outline-offset: var(--focus-ring-offset, 2px);\n}\n\n/* ── Delta legend ────────────────────────────────────────────────────────── */\n.legend {\n display: flex;\n flex-direction: column;\n gap: var(--spacing-2, 0.5rem);\n padding: var(--spacing-3, 0.75rem) var(--spacing-4, 1rem);\n border-top: var(--stroke-width-thin, 1px) solid var(--hairline, #e5e7eb);\n}\n.legendHead {\n font-family: var(--font-mono, ui-monospace, \"SFMono-Regular\", Menlo, monospace);\n font-size: var(--font-size-2xs, 0.6875rem);\n font-weight: var(--font-weight-bold, 700);\n letter-spacing: 0.14em;\n text-transform: uppercase;\n color: var(--text-tertiary, #9ca3af);\n}\n.legendRow {\n display: flex;\n align-items: center;\n gap: var(--spacing-3, 0.75rem);\n}\n.legendNum {\n flex-shrink: 0;\n display: grid;\n place-items: center;\n width: 1.125rem;\n height: 1.125rem;\n border-radius: var(--radius-full, 9999px);\n background: var(--warning, #f59e0b);\n color: var(--color-neutral-950, #030712);\n font-family: var(--font-mono, ui-monospace, \"SFMono-Regular\", Menlo, monospace);\n font-size: calc(var(--font-size-2xs, 0.6875rem) * 0.9);\n font-weight: var(--font-weight-bold, 700);\n}\n.tag {\n flex-shrink: 0;\n padding: calc(var(--spacing-1, 0.25rem) * 0.75) var(--spacing-2, 0.5rem);\n border: var(--stroke-width-thin, 1px) solid var(--hairline, #e5e7eb);\n border-radius: var(--radius-sm, 0.25rem);\n background: var(--surface-subtle, #f3f4f6);\n font-family: var(--font-mono, ui-monospace, \"SFMono-Regular\", Menlo, monospace);\n font-size: calc(var(--font-size-2xs, 0.6875rem) * 0.9);\n font-weight: var(--font-weight-bold, 700);\n letter-spacing: 0.08em;\n text-transform: uppercase;\n color: var(--text-secondary, #4b5563);\n}\n.legendText {\n font-family: var(--font-mono, ui-monospace, \"SFMono-Regular\", Menlo, monospace);\n font-size: var(--font-size-sm, 0.8125rem);\n color: var(--text-secondary, #4b5563);\n}\n.legendText b {\n color: var(--text-primary, #111827);\n font-weight: var(--font-weight-bold, 700);\n}\n\n/* Visually-hidden text for assistive technology. */\n.srOnly {\n position: absolute;\n width: var(--stroke-width-thin, 1px);\n height: var(--stroke-width-thin, 1px);\n padding: 0;\n margin: calc(-1 * var(--stroke-width-thin, 1px));\n overflow: hidden;\n clip: rect(0, 0, 0, 0);\n white-space: nowrap;\n border: 0;\n}\n\n/* Responsive: panes stack under 768px (design over built) — NEVER a sideways\n * scroll strip (the defect the doc-set surfaces exist to kill). */\n@media (max-width: 767px) {\n .panes {\n grid-template-columns: 1fr;\n }\n .bar {\n gap: var(--spacing-2, 0.5rem);\n }\n}\n"
|
|
2871
2871
|
}
|
|
2872
2872
|
]
|
|
2873
2873
|
},
|
|
@@ -3086,7 +3086,7 @@
|
|
|
3086
3086
|
{
|
|
3087
3087
|
"path": "components/ui/theme-switcher/theme-switcher.module.css",
|
|
3088
3088
|
"type": "registry:ui",
|
|
3089
|
-
"content": ".root {\n position: fixed;\n bottom: var(--spacing-3, 0.75rem);\n right: var(--spacing-3, 0.75rem);\n z-index: 1000;\n\n display: inline-flex;\n align-items: center;\n gap: var(--spacing-2, 0.5rem);\n\n padding: var(--spacing-1, 0.25rem) var(--spacing-2, 0.5rem);\n border-radius: var(--radius-full, 9999px);\n background: var(--surface-popover, var(--surface-card, #111827));\n color: var(--text-secondary, #4b5563);\n backdrop-filter: blur(8px);\n -webkit-backdrop-filter: blur(8px);\n\n font-family: var(--font-body,
|
|
3089
|
+
"content": ".root {\n position: fixed;\n bottom: var(--spacing-3, 0.75rem);\n right: var(--spacing-3, 0.75rem);\n z-index: 1000;\n\n display: inline-flex;\n align-items: center;\n gap: var(--spacing-2, 0.5rem);\n\n padding: var(--spacing-1, 0.25rem) var(--spacing-2, 0.5rem);\n border-radius: var(--radius-full, 9999px);\n background: var(--surface-popover, var(--surface-card, #111827));\n color: var(--text-secondary, #4b5563);\n backdrop-filter: blur(8px);\n -webkit-backdrop-filter: blur(8px);\n\n font-family: var(--font-body, inherit);\n font-size: var(--font-size-xs, 0.75rem);\n letter-spacing: 0.04em;\n\n outline: var(--stroke-width-thin, 1px) solid color-mix(in srgb, var(--text-tertiary, #9ca3af) 30%, transparent);\n outline-offset: 0;\n box-shadow: var(--shadow-md, 0 4px 6px -1px rgba(0, 0, 0, 0.1));\n}\n\n.label {\n font-size: var(--font-size-xs, 0.75rem);\n text-transform: uppercase;\n letter-spacing: 0.12em;\n color: var(--text-tertiary, #9ca3af);\n font-weight: var(--font-weight-medium, 500);\n}\n\n.divider {\n display: inline-block;\n width: var(--stroke-width-thin, 1px);\n height: 14px;\n background: color-mix(in srgb, var(--text-tertiary, #9ca3af) 35%, transparent);\n}\n\n.segment {\n display: inline-flex;\n align-items: center;\n gap: calc(var(--spacing-1, 0.25rem) / 2);\n padding: calc(var(--spacing-1, 0.25rem) / 2);\n background: color-mix(in srgb, var(--text-tertiary, #9ca3af) 14%, transparent);\n border-radius: var(--radius-full, 9999px);\n}\n\n.option {\n appearance: none;\n background: transparent;\n border: 0;\n padding: calc(var(--spacing-1, 0.25rem) * 0.75) var(--spacing-2, 0.5rem);\n border-radius: var(--radius-full, 9999px);\n font-size: var(--font-size-xs, 0.75rem);\n font-weight: var(--font-weight-medium, 500);\n color: var(--text-secondary, #4b5563);\n cursor: pointer;\n letter-spacing: 0.02em;\n transition: background-color var(--motion-duration-100, 100ms) var(--motion-easing-default, ease-in-out),\n color var(--motion-duration-100, 100ms) var(--motion-easing-default, ease-in-out);\n}\n\n.option:hover {\n color: var(--text-primary, #111827);\n}\n\n.option[data-active=\"true\"] {\n background: var(--surface-card, #ffffff);\n color: var(--text-primary, #111827);\n box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--text-tertiary, #9ca3af) 25%, transparent);\n}\n\n.option:focus-visible {\n outline: var(--focus-ring-width, 2px) solid var(--border-focus, currentColor);\n outline-offset: var(--focus-ring-offset, 2px);\n}\n"
|
|
3090
3090
|
}
|
|
3091
3091
|
]
|
|
3092
3092
|
},
|
|
@@ -3231,7 +3231,7 @@
|
|
|
3231
3231
|
{
|
|
3232
3232
|
"path": "components/ui/color-picker/color-picker.module.css",
|
|
3233
3233
|
"type": "registry:ui",
|
|
3234
|
-
"content": "/* ColorPicker — theme-agnostic OKLCH picker.\n *\n * All surface, border, focus, shadow, and motion declarations use semantic\n * tokens via var() with Tailwind Gray fallbacks. Canvas pixels are computed\n * colors — outputs of the picker, not theme surfaces — so they reference no\n * tokens. The indicator dimensions (crosshair 12px, hue indicator 4px) are\n * documented as intentional pixel values for pointing precision per\n * the token-rules doc, rule 12.\n */\n\n/* ─── Root container ──────────────────────────────────────────────────── */\n\n.root {\n display: inline-block;\n}\n\n.root[data-mode=\"inline\"] {\n display: block;\n width: 100%;\n}\n\n/* ─── Trigger (popover mode) ──────────────────────────────────────────── */\n\n.trigger {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n padding: 0;\n background-color: transparent;\n border: var(--stroke-width-thin, 1px) solid var(--border-default, #e5e7eb);\n border-radius: var(--radius-sm, 0.5rem);\n cursor: pointer;\n transition: border-color var(--motion-duration-150, 150ms) var(--motion-easing-default, ease-in-out),\n box-shadow var(--motion-duration-150, 150ms) var(--motion-easing-default, ease-in-out);\n outline: none;\n overflow: hidden;\n}\n\n@media (hover: hover) {\n .trigger:hover:not(:focus-visible):not(:disabled) {\n border-color: var(--border-strong, #d1d5db);\n }\n}\n\n.trigger:focus-visible {\n border-color: var(--border-focus, #111827);\n box-shadow: 0 0 0 var(--focus-ring-width, 2px) color-mix(in srgb, var(--border-focus, #111827) 15%, transparent);\n}\n\n.trigger:disabled {\n cursor: not-allowed;\n opacity: var(--opacity-40, 0.4);\n}\n\n.triggerSm {\n width: 1.5rem;\n height: 1.5rem;\n}\n\n.triggerMd {\n width: 2rem;\n height: 2rem;\n}\n\n.triggerLg {\n width: 2.5rem;\n height: 2.5rem;\n}\n\n.triggerSwatch {\n display: block;\n width: 100%;\n height: 100%;\n}\n\n/* ─── Popover content ─────────────────────────────────────────────────── */\n\n.popoverContent {\n z-index: 50;\n min-width: 16rem;\n padding: var(--spacing-4, 1rem);\n background-color: var(--surface-popover, var(--surface-card, #ffffff));\n color: var(--text-primary, #111827);\n border: var(--stroke-width-thin, 1px) solid var(--border-default, #e5e7eb);\n border-radius: var(--radius-sm, 0.5rem);\n box-shadow: var(--shadow-md);\n}\n\n.popoverContent[data-state=\"open\"] {\n animation: contentShow var(--motion-duration-fast, 100ms) var(--motion-easing-enter, ease-out);\n}\n\n.popoverContent[data-state=\"closed\"] {\n animation: contentHide var(--motion-duration-fast, 100ms) var(--motion-easing-exit, ease-in);\n}\n\n@keyframes contentShow {\n from {\n opacity: 0;\n transform: scale(0.96);\n }\n to {\n opacity: 1;\n transform: scale(1);\n }\n}\n\n@keyframes contentHide {\n from {\n opacity: 1;\n transform: scale(1);\n }\n to {\n opacity: 0;\n transform: scale(0.96);\n }\n}\n\n/* ─── Picker surface (the actual picker UI) ───────────────────────────── */\n\n.picker {\n display: flex;\n flex-direction: column;\n gap: var(--spacing-3, 0.75rem);\n min-width: 16rem;\n}\n\n.picker[data-disabled] {\n opacity: var(--opacity-40, 0.4);\n pointer-events: none;\n}\n\n/* ─── 2D Lightness × Chroma plane ─────────────────────────────────────── */\n\n.planeWrapper {\n position: relative;\n width: 100%;\n aspect-ratio: 1.4;\n border-radius: var(--radius-sm, 0.25rem);\n overflow: hidden;\n cursor: crosshair;\n border: var(--stroke-width-thin, 1px) solid var(--border-default, #e5e7eb);\n outline: none;\n}\n\n.planeWrapper:focus-visible {\n border-color: var(--border-focus, #111827);\n box-shadow: 0 0 0 var(--focus-ring-width, 2px) color-mix(in srgb, var(--border-focus, #111827) 15%, transparent);\n}\n\n.planeCanvas {\n display: block;\n width: 100%;\n height: 100%;\n}\n\n.crosshair {\n /* Crosshair is a floating overlay on top of the computed-color canvas, not\n * a theme surface. The 12px diameter is an intentional pixel value chosen\n * for pointing precision (documented under token-rules rule 12). The white\n * stroke + dark micro-shadow give the indicator legibility against any\n * underlying canvas color regardless of theme — that's the whole point of\n * the marker. Themes can opt to override these via the color-picker tokens\n * declared in the planeWrapper rule above. */\n position: absolute;\n width: 12px;\n height: 12px;\n border: var(--stroke-width-medium, 2px) solid var(--color-picker-indicator, #ffffff);\n border-radius: 50%;\n box-shadow: var(\n --color-picker-indicator-shadow,\n 0 0 0 var(--stroke-width-thin, 1px) rgba(0, 0, 0, 0.3)\n ),\n inset 0 0 0 var(--stroke-width-thin, 1px) var(--color-picker-indicator-shadow-color, rgba(0, 0, 0, 0.3));\n pointer-events: none;\n transform: translate(-50%, -50%);\n transition: left var(--motion-duration-fast, 100ms) var(--motion-easing-default, ease-in-out),\n top var(--motion-duration-fast, 100ms) var(--motion-easing-default, ease-in-out);\n}\n\n@media (prefers-reduced-motion: reduce) {\n .crosshair {\n transition: none;\n }\n}\n\n/* ─── Hue slider ──────────────────────────────────────────────────────── */\n\n.hueWrapper {\n position: relative;\n width: 100%;\n height: var(--spacing-4, 1rem);\n border-radius: var(--radius-sm, 0.25rem);\n overflow: hidden;\n cursor: crosshair;\n border: var(--stroke-width-thin, 1px) solid var(--border-default, #e5e7eb);\n outline: none;\n}\n\n.hueWrapper:focus-visible {\n border-color: var(--border-focus, #111827);\n box-shadow: 0 0 0 var(--focus-ring-width, 2px) color-mix(in srgb, var(--border-focus, #111827) 15%, transparent);\n}\n\n.hueCanvas {\n display: block;\n width: 100%;\n height: 100%;\n}\n\n.hueIndicator {\n /* Hue indicator is a floating overlay on top of the computed-color hue\n * canvas, not a theme surface. The 4px width is an intentional pixel value\n * chosen for pointing precision (documented under token-rules rule 12).\n * The white stroke + dark micro-shadow give the indicator legibility\n * against any underlying hue regardless of theme. Themes can opt to\n * override via the color-picker tokens declared in the planeWrapper rule\n * above. */\n position: absolute;\n top: calc(-1 * var(--stroke-width-thin, 1px));\n bottom: calc(-1 * var(--stroke-width-thin, 1px));\n width: 4px;\n border: var(--stroke-width-medium, 2px) solid var(--color-picker-indicator, #ffffff);\n border-radius: 1px;\n box-shadow: var(\n --color-picker-indicator-shadow,\n 0 0 0 var(--stroke-width-thin, 1px) rgba(0, 0, 0, 0.3)\n );\n pointer-events: none;\n transform: translateX(-50%);\n transition: left var(--motion-duration-fast, 100ms) var(--motion-easing-default, ease-in-out);\n}\n\n@media (prefers-reduced-motion: reduce) {\n .hueIndicator {\n transition: none;\n }\n}\n\n/* ─── Readout (L / C / H) ─────────────────────────────────────────────── */\n\n.readout {\n display: flex;\n justify-content: space-between;\n font-size: var(--font-size-xs, 0.75rem);\n color: var(--text-tertiary, #9ca3af);\n font-variant-numeric: tabular-nums;\n}\n\n/* ─── Hex row (chip + input) ──────────────────────────────────────────── */\n\n.hexRow {\n display: flex;\n gap: var(--spacing-2, 0.5rem);\n align-items: center;\n}\n\n.hexChip {\n width: 2rem;\n height: 2rem;\n border: var(--stroke-width-thin, 1px) solid var(--border-default, #e5e7eb);\n border-radius: var(--radius-sm, 0.5rem);\n flex-shrink: 0;\n}\n\n.hexInput {\n flex: 1;\n min-width: 0;\n height: 2.25rem;\n padding: var(--spacing-1, 0.25rem) var(--spacing-3, 0.75rem);\n border: var(--stroke-width-thin, 1px) solid var(--border-default, #e5e7eb);\n border-radius: var(--radius-sm, 0.5rem);\n background-color: var(--surface-interactive-default, #f9fafb);\n color: var(--text-primary, #111827);\n font-family: ui-monospace, SFMono-Regular, Menlo, monospace;\n font-size: var(--font-size-sm, 0.875rem);\n font-variant-numeric: tabular-nums;\n outline: none;\n transition: border-color var(--motion-duration-150, 150ms) var(--motion-easing-default, ease-in-out),\n box-shadow var(--motion-duration-150, 150ms) var(--motion-easing-default, ease-in-out);\n}\n\n.hexInput:focus-visible {\n border-color: var(--border-focus, #111827);\n box-shadow: 0 0 0 var(--focus-ring-width, 2px) color-mix(in srgb, var(--border-focus, #111827) 15%, transparent);\n}\n\n.hexInput[aria-invalid=\"true\"] {\n border-color: var(--border-error, #ef4444);\n box-shadow: 0 0 0 var(--focus-ring-width, 2px) color-mix(in srgb, var(--border-error, #ef4444) 15%, transparent);\n}\n\n.hexInput:disabled {\n cursor: not-allowed;\n opacity: var(--opacity-40, 0.4);\n}\n\n/* ─── Preset chips ────────────────────────────────────────────────────── */\n\n.presets {\n display: flex;\n gap: var(--spacing-2, 0.5rem);\n flex-wrap: wrap;\n}\n\n.presetChip {\n width: 1.5rem;\n height: 1.5rem;\n padding: 0;\n border: var(--stroke-width-thin, 1px) solid var(--border-default, #e5e7eb);\n border-radius: var(--radius-sm, 0.25rem);\n cursor: pointer;\n outline: none;\n transition: border-color var(--motion-duration-150, 150ms) var(--motion-easing-default, ease-in-out),\n box-shadow var(--motion-duration-150, 150ms) var(--motion-easing-default, ease-in-out);\n}\n\n@media (hover: hover) {\n .presetChip:hover:not(:focus-visible):not(:disabled) {\n border-color: var(--border-strong, #d1d5db);\n }\n}\n\n.presetChip:focus-visible {\n border-color: var(--border-focus, #111827);\n box-shadow: 0 0 0 var(--focus-ring-width, 2px) color-mix(in srgb, var(--border-focus, #111827) 15%, transparent);\n}\n\n.presetChip:disabled {\n cursor: not-allowed;\n opacity: var(--opacity-40, 0.4);\n}\n"
|
|
3234
|
+
"content": "/* ColorPicker — theme-agnostic OKLCH picker.\n *\n * All surface, border, focus, shadow, and motion declarations use semantic\n * tokens via var() with Tailwind Gray fallbacks. Canvas pixels are computed\n * colors — outputs of the picker, not theme surfaces — so they reference no\n * tokens. The indicator dimensions (crosshair 12px, hue indicator 4px) are\n * documented as intentional pixel values for pointing precision per\n * the token-rules doc, rule 12.\n */\n\n/* ─── Root container ──────────────────────────────────────────────────── */\n\n.root {\n display: inline-block;\n}\n\n.root[data-mode=\"inline\"] {\n display: block;\n width: 100%;\n}\n\n/* ─── Trigger (popover mode) ──────────────────────────────────────────── */\n\n.trigger {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n padding: 0;\n background-color: transparent;\n border: var(--stroke-width-thin, 1px) solid var(--border-default, #e5e7eb);\n border-radius: var(--radius-sm, 0.5rem);\n cursor: pointer;\n transition: border-color var(--motion-duration-150, 150ms) var(--motion-easing-default, ease-in-out),\n box-shadow var(--motion-duration-150, 150ms) var(--motion-easing-default, ease-in-out);\n outline: none;\n overflow: hidden;\n}\n\n@media (hover: hover) {\n .trigger:hover:not(:focus-visible):not(:disabled) {\n border-color: var(--border-strong, #d1d5db);\n }\n}\n\n.trigger:focus-visible {\n border-color: var(--border-focus, #111827);\n box-shadow: 0 0 0 var(--focus-ring-width, 2px) color-mix(in srgb, var(--border-focus, #111827) 15%, transparent);\n}\n\n.trigger:disabled {\n cursor: not-allowed;\n opacity: var(--opacity-40, 0.4);\n}\n\n.triggerSm {\n width: 1.5rem;\n height: 1.5rem;\n}\n\n.triggerMd {\n width: 2rem;\n height: 2rem;\n}\n\n.triggerLg {\n width: 2.5rem;\n height: 2.5rem;\n}\n\n.triggerSwatch {\n display: block;\n width: 100%;\n height: 100%;\n}\n\n/* ─── Popover content ─────────────────────────────────────────────────── */\n\n.popoverContent {\n z-index: 50;\n min-width: 16rem;\n padding: var(--spacing-4, 1rem);\n background-color: var(--surface-popover, var(--surface-card, #ffffff));\n color: var(--text-primary, #111827);\n border: var(--stroke-width-thin, 1px) solid var(--border-default, #e5e7eb);\n border-radius: var(--radius-sm, 0.5rem);\n box-shadow: var(--shadow-md);\n}\n\n.popoverContent[data-state=\"open\"] {\n animation: contentShow var(--motion-duration-fast, 100ms) var(--motion-easing-enter, ease-out);\n}\n\n.popoverContent[data-state=\"closed\"] {\n animation: contentHide var(--motion-duration-fast, 100ms) var(--motion-easing-exit, ease-in);\n}\n\n@keyframes contentShow {\n from {\n opacity: 0;\n transform: scale(0.96);\n }\n to {\n opacity: 1;\n transform: scale(1);\n }\n}\n\n@keyframes contentHide {\n from {\n opacity: 1;\n transform: scale(1);\n }\n to {\n opacity: 0;\n transform: scale(0.96);\n }\n}\n\n/* ─── Picker surface (the actual picker UI) ───────────────────────────── */\n\n.picker {\n display: flex;\n flex-direction: column;\n gap: var(--spacing-3, 0.75rem);\n min-width: 16rem;\n}\n\n.picker[data-disabled] {\n opacity: var(--opacity-40, 0.4);\n pointer-events: none;\n}\n\n/* ─── 2D Lightness × Chroma plane ─────────────────────────────────────── */\n\n.planeWrapper {\n position: relative;\n width: 100%;\n aspect-ratio: 1.4;\n border-radius: var(--radius-sm, 0.25rem);\n overflow: hidden;\n cursor: crosshair;\n border: var(--stroke-width-thin, 1px) solid var(--border-default, #e5e7eb);\n outline: none;\n}\n\n.planeWrapper:focus-visible {\n border-color: var(--border-focus, #111827);\n box-shadow: 0 0 0 var(--focus-ring-width, 2px) color-mix(in srgb, var(--border-focus, #111827) 15%, transparent);\n}\n\n.planeCanvas {\n display: block;\n width: 100%;\n height: 100%;\n}\n\n.crosshair {\n /* Crosshair is a floating overlay on top of the computed-color canvas, not\n * a theme surface. The 12px diameter is an intentional pixel value chosen\n * for pointing precision (documented under token-rules rule 12). The white\n * stroke + dark micro-shadow give the indicator legibility against any\n * underlying canvas color regardless of theme — that's the whole point of\n * the marker. Themes can opt to override these via the color-picker tokens\n * declared in the planeWrapper rule above. */\n position: absolute;\n width: 12px;\n height: 12px;\n border: var(--stroke-width-medium, 2px) solid var(--color-picker-indicator, #ffffff);\n border-radius: 50%;\n box-shadow: var(\n --color-picker-indicator-shadow,\n 0 0 0 var(--stroke-width-thin, 1px) rgba(0, 0, 0, 0.3)\n ),\n inset 0 0 0 var(--stroke-width-thin, 1px) var(--color-picker-indicator-shadow-color, rgba(0, 0, 0, 0.3));\n pointer-events: none;\n transform: translate(-50%, -50%);\n transition: left var(--motion-duration-fast, 100ms) var(--motion-easing-default, ease-in-out),\n top var(--motion-duration-fast, 100ms) var(--motion-easing-default, ease-in-out);\n}\n\n@media (prefers-reduced-motion: reduce) {\n .crosshair {\n transition: none;\n }\n}\n\n/* ─── Hue slider ──────────────────────────────────────────────────────── */\n\n.hueWrapper {\n position: relative;\n width: 100%;\n height: var(--spacing-4, 1rem);\n border-radius: var(--radius-sm, 0.25rem);\n overflow: hidden;\n cursor: crosshair;\n border: var(--stroke-width-thin, 1px) solid var(--border-default, #e5e7eb);\n outline: none;\n}\n\n.hueWrapper:focus-visible {\n border-color: var(--border-focus, #111827);\n box-shadow: 0 0 0 var(--focus-ring-width, 2px) color-mix(in srgb, var(--border-focus, #111827) 15%, transparent);\n}\n\n.hueCanvas {\n display: block;\n width: 100%;\n height: 100%;\n}\n\n.hueIndicator {\n /* Hue indicator is a floating overlay on top of the computed-color hue\n * canvas, not a theme surface. The 4px width is an intentional pixel value\n * chosen for pointing precision (documented under token-rules rule 12).\n * The white stroke + dark micro-shadow give the indicator legibility\n * against any underlying hue regardless of theme. Themes can opt to\n * override via the color-picker tokens declared in the planeWrapper rule\n * above. */\n position: absolute;\n top: calc(-1 * var(--stroke-width-thin, 1px));\n bottom: calc(-1 * var(--stroke-width-thin, 1px));\n width: 4px;\n border: var(--stroke-width-medium, 2px) solid var(--color-picker-indicator, #ffffff);\n border-radius: 1px;\n box-shadow: var(\n --color-picker-indicator-shadow,\n 0 0 0 var(--stroke-width-thin, 1px) rgba(0, 0, 0, 0.3)\n );\n pointer-events: none;\n transform: translateX(-50%);\n transition: left var(--motion-duration-fast, 100ms) var(--motion-easing-default, ease-in-out);\n}\n\n@media (prefers-reduced-motion: reduce) {\n .hueIndicator {\n transition: none;\n }\n}\n\n/* ─── Readout (L / C / H) ─────────────────────────────────────────────── */\n\n.readout {\n display: flex;\n justify-content: space-between;\n font-size: var(--font-size-xs, 0.75rem);\n color: var(--text-tertiary, #9ca3af);\n font-variant-numeric: tabular-nums;\n}\n\n/* ─── Hex row (chip + input) ──────────────────────────────────────────── */\n\n.hexRow {\n display: flex;\n gap: var(--spacing-2, 0.5rem);\n align-items: center;\n}\n\n.hexChip {\n width: 2rem;\n height: 2rem;\n border: var(--stroke-width-thin, 1px) solid var(--border-default, #e5e7eb);\n border-radius: var(--radius-sm, 0.5rem);\n flex-shrink: 0;\n}\n\n.hexInput {\n flex: 1;\n min-width: 0;\n height: 2.25rem;\n padding: var(--spacing-1, 0.25rem) var(--spacing-3, 0.75rem);\n border: var(--stroke-width-thin, 1px) solid var(--border-default, #e5e7eb);\n border-radius: var(--radius-sm, 0.5rem);\n background-color: var(--surface-interactive-default, #f9fafb);\n color: var(--text-primary, #111827);\n font-family: var(--font-mono, ui-monospace, SFMono-Regular, Menlo, monospace);\n font-size: var(--font-size-sm, 0.875rem);\n font-variant-numeric: tabular-nums;\n outline: none;\n transition: border-color var(--motion-duration-150, 150ms) var(--motion-easing-default, ease-in-out),\n box-shadow var(--motion-duration-150, 150ms) var(--motion-easing-default, ease-in-out);\n}\n\n.hexInput:focus-visible {\n border-color: var(--border-focus, #111827);\n box-shadow: 0 0 0 var(--focus-ring-width, 2px) color-mix(in srgb, var(--border-focus, #111827) 15%, transparent);\n}\n\n.hexInput[aria-invalid=\"true\"] {\n border-color: var(--border-error, #ef4444);\n box-shadow: 0 0 0 var(--focus-ring-width, 2px) color-mix(in srgb, var(--border-error, #ef4444) 15%, transparent);\n}\n\n.hexInput:disabled {\n cursor: not-allowed;\n opacity: var(--opacity-40, 0.4);\n}\n\n/* ─── Preset chips ────────────────────────────────────────────────────── */\n\n.presets {\n display: flex;\n gap: var(--spacing-2, 0.5rem);\n flex-wrap: wrap;\n}\n\n.presetChip {\n width: 1.5rem;\n height: 1.5rem;\n padding: 0;\n border: var(--stroke-width-thin, 1px) solid var(--border-default, #e5e7eb);\n border-radius: var(--radius-sm, 0.25rem);\n cursor: pointer;\n outline: none;\n transition: border-color var(--motion-duration-150, 150ms) var(--motion-easing-default, ease-in-out),\n box-shadow var(--motion-duration-150, 150ms) var(--motion-easing-default, ease-in-out);\n}\n\n@media (hover: hover) {\n .presetChip:hover:not(:focus-visible):not(:disabled) {\n border-color: var(--border-strong, #d1d5db);\n }\n}\n\n.presetChip:focus-visible {\n border-color: var(--border-focus, #111827);\n box-shadow: 0 0 0 var(--focus-ring-width, 2px) color-mix(in srgb, var(--border-focus, #111827) 15%, transparent);\n}\n\n.presetChip:disabled {\n cursor: not-allowed;\n opacity: var(--opacity-40, 0.4);\n}\n"
|
|
3235
3235
|
},
|
|
3236
3236
|
{
|
|
3237
3237
|
"path": "components/ui/color-picker/oklch.ts",
|
|
@@ -3260,7 +3260,7 @@
|
|
|
3260
3260
|
{
|
|
3261
3261
|
"path": "components/ui/structured-prompt/structured-prompt.module.css",
|
|
3262
3262
|
"type": "registry:ui",
|
|
3263
|
-
"content": "/* StructuredPrompt\n *\n * Inline \"mad-lib\" fill-in-the-blank card used in brand elicitation and\n * structured-prompt workflows. A card with an eyebrow header, flowing prose\n * at tall line-height, and inline slot chips (filled or empty) embedded in\n * the prose, plus a hint footer.\n */\n\n.root {\n width: 100%;\n border-radius: var(--radius-xl, 1rem);\n background: var(--surface-card, #ffffff);\n border: var(--stroke-width-thin, 1px) solid var(--border-default, #e5e7eb);\n box-shadow: var(--shadow-sm, 0 1px 2px 0 rgba(0, 0, 0, 0.05));\n overflow: hidden;\n}\n\n/* Header bar — small icon + uppercase eyebrow label, hairline bottom border */\n.header {\n display: flex;\n align-items: center;\n gap: var(--spacing-2, 0.5rem);\n padding: var(--spacing-2-5, 0.625rem) var(--spacing-3-5, 0.875rem);\n border-bottom: var(--stroke-width-thin, 1px) solid var(--hairline, #e5e7eb);\n /* 11.5px — no line-height token matches this tall-prose context; intentional */\n font-size: 11.5px;\n font-weight: 700;\n letter-spacing: 0.04em;\n text-transform: uppercase;\n color: var(--text-tertiary, #6b7280);\n}\n\n.headerIcon {\n display: inline-flex;\n align-items: center;\n /* Use accent color for the eyebrow icon, matching the design spec */\n color: var(--surface-accent-default, #3b82f6);\n flex-shrink: 0;\n /* 13px icon — sized to match the 11.5px label rhythm */\n font-size: 13px;\n line-height: 1;\n}\n\n.headerLabel {\n flex: 1;\n min-width: 0;\n}\n\n/* Body — prose container with tall line-height so inline chips breathe */\n.body {\n padding: var(--spacing-3-5, 0.875rem);\n /* 15px — closest to --font-size-base but intentionally smaller for prose density */\n font-size: 15px;\n /* 2.05 line-height — no token matches; intentional value from design spec (elicit-core HiFi prototype) */\n line-height: 2.05;\n color: var(--text-primary, #111827);\n}\n\n/* Slot chip — inline; rendered inside flowing prose text */\n.slot {\n display: inline-flex;\n align-items: center;\n /* min-height 30px — no spacing token; intentional to match chip rhythm */\n min-height: 30px;\n padding: var(--spacing-0-5, 0.125rem) var(--spacing-2-5, 0.625rem);\n margin: 0 var(--spacing-0-5, 0.125rem);\n border-radius: var(--radius-md, 0.5rem);\n border-width: var(--stroke-width-thin, 1px);\n border-style: solid;\n /* 14px — intentionally one step below body prose for visual hierarchy */\n font-size: 14px;\n cursor: default;\n vertical-align: middle;\n line-height: 1.4;\n
|
|
3263
|
+
"content": "/* StructuredPrompt\n *\n * Inline \"mad-lib\" fill-in-the-blank card used in brand elicitation and\n * structured-prompt workflows. A card with an eyebrow header, flowing prose\n * at tall line-height, and inline slot chips (filled or empty) embedded in\n * the prose, plus a hint footer.\n */\n\n.root {\n width: 100%;\n border-radius: var(--radius-xl, 1rem);\n background: var(--surface-card, #ffffff);\n border: var(--stroke-width-thin, 1px) solid var(--border-default, #e5e7eb);\n box-shadow: var(--shadow-sm, 0 1px 2px 0 rgba(0, 0, 0, 0.05));\n overflow: hidden;\n}\n\n/* Header bar — small icon + uppercase eyebrow label, hairline bottom border */\n.header {\n display: flex;\n align-items: center;\n gap: var(--spacing-2, 0.5rem);\n padding: var(--spacing-2-5, 0.625rem) var(--spacing-3-5, 0.875rem);\n border-bottom: var(--stroke-width-thin, 1px) solid var(--hairline, #e5e7eb);\n /* 11.5px — no line-height token matches this tall-prose context; intentional */\n font-size: 11.5px;\n font-weight: 700;\n letter-spacing: 0.04em;\n text-transform: uppercase;\n color: var(--text-tertiary, #6b7280);\n}\n\n.headerIcon {\n display: inline-flex;\n align-items: center;\n /* Use accent color for the eyebrow icon, matching the design spec */\n color: var(--surface-accent-default, #3b82f6);\n flex-shrink: 0;\n /* 13px icon — sized to match the 11.5px label rhythm */\n font-size: 13px;\n line-height: 1;\n}\n\n.headerLabel {\n flex: 1;\n min-width: 0;\n}\n\n/* Body — prose container with tall line-height so inline chips breathe */\n.body {\n padding: var(--spacing-3-5, 0.875rem);\n /* 15px — closest to --font-size-base but intentionally smaller for prose density */\n font-size: 15px;\n /* 2.05 line-height — no token matches; intentional value from design spec (elicit-core HiFi prototype) */\n line-height: 2.05;\n color: var(--text-primary, #111827);\n}\n\n/* Slot chip — inline; rendered inside flowing prose text */\n.slot {\n display: inline-flex;\n align-items: center;\n /* min-height 30px — no spacing token; intentional to match chip rhythm */\n min-height: 30px;\n padding: var(--spacing-0-5, 0.125rem) var(--spacing-2-5, 0.625rem);\n margin: 0 var(--spacing-0-5, 0.125rem);\n border-radius: var(--radius-md, 0.5rem);\n border-width: var(--stroke-width-thin, 1px);\n border-style: solid;\n /* 14px — intentionally one step below body prose for visual hierarchy */\n font-size: 14px;\n cursor: default;\n vertical-align: middle;\n line-height: 1.4;\n text-decoration: none;\n -webkit-appearance: none;\n appearance: none;\n}\n\n/* Focus ring — only when rendered as <button> */\n.slot:focus-visible {\n outline: var(--focus-ring-width, 2px) solid var(--border-focus, #3b82f6);\n outline-offset: var(--focus-ring-offset, 2px);\n}\n\n/* Filled slot — accent-subtle bg + accent-default border + text-link color + 600 weight.\n * Uses the same token triplet as Chip's selected state so it adapts correctly in dark mode.\n */\n.slotFilled {\n background: var(--surface-accent-subtle, #eff6ff);\n border-color: var(--surface-accent-default, #3b82f6);\n color: var(--text-link, #2563eb);\n font-weight: var(--font-weight-semibold, 600);\n}\n\n/* Empty slot — dashed border, muted bg, italic, tertiary text */\n.slotEmpty {\n color: var(--text-tertiary, #6b7280);\n font-style: italic;\n font-weight: var(--font-weight-medium, 500);\n background: var(--surface-subtle, #f9fafb);\n border-style: dashed;\n border-color: var(--border-default, #e5e7eb);\n cursor: text;\n}\n\n/* Hint footer — small tertiary text below the body */\n.hint {\n padding: 0 var(--spacing-3-5, 0.875rem) var(--spacing-3, 0.75rem);\n /* 11.5px — matches header eyebrow size; intentional */\n font-size: 11.5px;\n color: var(--text-tertiary, #6b7280);\n}\n\n/* Respect reduced motion */\n@media (prefers-reduced-motion: reduce) {\n .slot {\n transition: none;\n }\n}\n"
|
|
3264
3264
|
}
|
|
3265
3265
|
]
|
|
3266
3266
|
},
|
|
@@ -4230,7 +4230,7 @@
|
|
|
4230
4230
|
{
|
|
4231
4231
|
"path": "blocks/month-calendar/month-calendar.module.css",
|
|
4232
4232
|
"type": "registry:block",
|
|
4233
|
-
"content": "/* Month Calendar\n * A theme-portable month event-grid (scheduler) block: a 6×7 day-cell grid\n * under a weekday header, with month navigation, a view-mode segmented control,\n * and per-cell event chips carrying a status dot and an optional series tint.\n *\n * Every color, size, spacing, stroke, radius, and motion value binds to a Visor\n * token so the block adopts the active theme without modification. Selectors are\n * anchored on a local class to satisfy the docs bundler's pure-selector rule.\n */\n\n.root {\n display: flex;\n flex-direction: column;\n background: var(--surface-card);\n border: var(--stroke-width-thin) solid var(--border-muted);\n border-radius: var(--radius-lg);\n overflow: hidden;\n color: var(--text-primary);\n}\n\n/* ── Header: month nav + view segmented control ── */\n.header {\n display: flex;\n flex-wrap: wrap;\n align-items: center;\n justify-content: space-between;\n gap: var(--spacing-3, 0.75rem);\n padding: var(--spacing-4, 1rem);\n}\n\n.nav {\n display: flex;\n align-items: center;\n gap: var(--spacing-2, 0.5rem);\n}\n\n.navButton {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n /* 32px — icon-button sizing; sizing tokens deferred (Rule 5 exception). */\n width: 2rem;\n height: 2rem;\n padding: 0;\n color: var(--text-secondary);\n background: transparent;\n border: var(--stroke-width-thin) solid transparent;\n border-radius: var(--radius-md);\n cursor: pointer;\n}\n\n.navButton:hover:not(:disabled) {\n background: var(--surface-interactive-hover);\n color: var(--text-primary);\n}\n\n.navButton:disabled {\n opacity: var(--opacity-40);\n cursor: default;\n}\n\n.navButton:focus-visible {\n outline: var(--focus-ring-width) solid var(--border-focus);\n outline-offset: var(--focus-ring-offset);\n}\n\n.monthLabel {\n margin: 0;\n min-width: 10ch;\n text-align: center;\n font-size: var(--font-size-lg, 1.125rem);\n font-weight: var(--font-weight-semibold, 600);\n color: var(--text-primary);\n}\n\n/* ── View-mode segmented control ── */\n.segmented {\n display: inline-flex;\n align-items: center;\n gap: var(--stroke-width-thin);\n padding: var(--spacing-1, 0.25rem);\n background: var(--surface-subtle);\n border: var(--stroke-width-thin) solid var(--border-muted);\n border-radius: var(--radius-md);\n}\n\n.segment {\n appearance: none;\n padding: var(--spacing-1, 0.25rem) var(--spacing-3, 0.75rem);\n font-size: var(--font-size-sm, 0.875rem);\n font-weight: var(--font-weight-medium, 500);\n color: var(--text-secondary);\n background: transparent;\n border: none;\n border-radius: var(--radius-sm);\n cursor: pointer;\n transition: color var(--motion-duration-fast, 100ms)\n var(--motion-easing-default, ease-in-out),\n background-color var(--motion-duration-fast, 100ms)\n var(--motion-easing-default, ease-in-out);\n}\n\n.segment:hover:not([data-active]) {\n color: var(--text-primary);\n}\n\n.segment[data-active] {\n color: var(--text-primary);\n background: var(--surface-card);\n box-shadow: var(--shadow-xs);\n}\n\n.segment:focus-visible {\n outline: var(--focus-ring-width) solid var(--border-focus);\n outline-offset: var(--focus-ring-offset);\n}\n\n/* ── Weekday header row ── */\n.weekdays {\n display: grid;\n grid-template-columns: repeat(7, minmax(0, 1fr));\n border-top: var(--stroke-width-thin) solid var(--border-muted);\n background: var(--surface-subtle);\n}\n\n.weekday {\n padding: var(--spacing-2, 0.5rem);\n text-align: center;\n font-size: var(--font-size-xs, 0.75rem);\n font-weight: var(--font-weight-medium, 500);\n letter-spacing: 0.04em;\n text-transform: uppercase;\n color: var(--text-tertiary);\n}\n\n/* ── 6×7 day grid ── */\n/* The hairline background shows through the 1px gaps to draw the grid lines. */\n.grid {\n display: grid;\n grid-template-columns: repeat(7, minmax(0, 1fr));\n grid-auto-rows: minmax(0, 1fr);\n gap: var(--stroke-width-thin);\n background: var(--border-muted);\n border-top: var(--stroke-width-thin) solid var(--border-muted);\n}\n\n.cell {\n display: flex;\n flex-direction: column;\n gap: var(--spacing-1, 0.25rem);\n /* 104px — day-cell min height; sizing tokens deferred (Rule 5 exception). */\n min-height: 6.5rem;\n padding: var(--spacing-1, 0.25rem);\n background: var(--surface-card);\n}\n\n.cell[data-outside] {\n background: var(--surface-subtle);\n}\n\n.cell[data-outside] .dayNumber {\n color: var(--text-disabled);\n}\n\n.cell[data-selected] {\n background: var(--interactive-primary-soft);\n}\n\n/* ── Day number head (button when the day is selectable) ── */\n.dayHead {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n align-self: flex-start;\n /* 24px — day-number badge sizing; sizing tokens deferred (Rule 5 exception). */\n min-width: 1.5rem;\n height: 1.5rem;\n padding: 0 var(--spacing-1, 0.25rem);\n
|
|
4233
|
+
"content": "/* Month Calendar\n * A theme-portable month event-grid (scheduler) block: a 6×7 day-cell grid\n * under a weekday header, with month navigation, a view-mode segmented control,\n * and per-cell event chips carrying a status dot and an optional series tint.\n *\n * Every color, size, spacing, stroke, radius, and motion value binds to a Visor\n * token so the block adopts the active theme without modification. Selectors are\n * anchored on a local class to satisfy the docs bundler's pure-selector rule.\n */\n\n.root {\n display: flex;\n flex-direction: column;\n background: var(--surface-card);\n border: var(--stroke-width-thin) solid var(--border-muted);\n border-radius: var(--radius-lg);\n overflow: hidden;\n color: var(--text-primary);\n}\n\n/* ── Header: month nav + view segmented control ── */\n.header {\n display: flex;\n flex-wrap: wrap;\n align-items: center;\n justify-content: space-between;\n gap: var(--spacing-3, 0.75rem);\n padding: var(--spacing-4, 1rem);\n}\n\n.nav {\n display: flex;\n align-items: center;\n gap: var(--spacing-2, 0.5rem);\n}\n\n.navButton {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n /* 32px — icon-button sizing; sizing tokens deferred (Rule 5 exception). */\n width: 2rem;\n height: 2rem;\n padding: 0;\n color: var(--text-secondary);\n background: transparent;\n border: var(--stroke-width-thin) solid transparent;\n border-radius: var(--radius-md);\n cursor: pointer;\n}\n\n.navButton:hover:not(:disabled) {\n background: var(--surface-interactive-hover);\n color: var(--text-primary);\n}\n\n.navButton:disabled {\n opacity: var(--opacity-40);\n cursor: default;\n}\n\n.navButton:focus-visible {\n outline: var(--focus-ring-width) solid var(--border-focus);\n outline-offset: var(--focus-ring-offset);\n}\n\n.monthLabel {\n margin: 0;\n min-width: 10ch;\n text-align: center;\n font-size: var(--font-size-lg, 1.125rem);\n font-weight: var(--font-weight-semibold, 600);\n color: var(--text-primary);\n}\n\n/* ── View-mode segmented control ── */\n.segmented {\n display: inline-flex;\n align-items: center;\n gap: var(--stroke-width-thin);\n padding: var(--spacing-1, 0.25rem);\n background: var(--surface-subtle);\n border: var(--stroke-width-thin) solid var(--border-muted);\n border-radius: var(--radius-md);\n}\n\n.segment {\n appearance: none;\n padding: var(--spacing-1, 0.25rem) var(--spacing-3, 0.75rem);\n font-size: var(--font-size-sm, 0.875rem);\n font-weight: var(--font-weight-medium, 500);\n color: var(--text-secondary);\n background: transparent;\n border: none;\n border-radius: var(--radius-sm);\n cursor: pointer;\n transition: color var(--motion-duration-fast, 100ms)\n var(--motion-easing-default, ease-in-out),\n background-color var(--motion-duration-fast, 100ms)\n var(--motion-easing-default, ease-in-out);\n}\n\n.segment:hover:not([data-active]) {\n color: var(--text-primary);\n}\n\n.segment[data-active] {\n color: var(--text-primary);\n background: var(--surface-card);\n box-shadow: var(--shadow-xs);\n}\n\n.segment:focus-visible {\n outline: var(--focus-ring-width) solid var(--border-focus);\n outline-offset: var(--focus-ring-offset);\n}\n\n/* ── Weekday header row ── */\n.weekdays {\n display: grid;\n grid-template-columns: repeat(7, minmax(0, 1fr));\n border-top: var(--stroke-width-thin) solid var(--border-muted);\n background: var(--surface-subtle);\n}\n\n.weekday {\n padding: var(--spacing-2, 0.5rem);\n text-align: center;\n font-size: var(--font-size-xs, 0.75rem);\n font-weight: var(--font-weight-medium, 500);\n letter-spacing: 0.04em;\n text-transform: uppercase;\n color: var(--text-tertiary);\n}\n\n/* ── 6×7 day grid ── */\n/* The hairline background shows through the 1px gaps to draw the grid lines. */\n.grid {\n display: grid;\n grid-template-columns: repeat(7, minmax(0, 1fr));\n grid-auto-rows: minmax(0, 1fr);\n gap: var(--stroke-width-thin);\n background: var(--border-muted);\n border-top: var(--stroke-width-thin) solid var(--border-muted);\n}\n\n.cell {\n display: flex;\n flex-direction: column;\n gap: var(--spacing-1, 0.25rem);\n /* 104px — day-cell min height; sizing tokens deferred (Rule 5 exception). */\n min-height: 6.5rem;\n padding: var(--spacing-1, 0.25rem);\n background: var(--surface-card);\n}\n\n.cell[data-outside] {\n background: var(--surface-subtle);\n}\n\n.cell[data-outside] .dayNumber {\n color: var(--text-disabled);\n}\n\n.cell[data-selected] {\n background: var(--interactive-primary-soft);\n}\n\n/* ── Day number head (button when the day is selectable) ── */\n.dayHead {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n align-self: flex-start;\n /* 24px — day-number badge sizing; sizing tokens deferred (Rule 5 exception). */\n min-width: 1.5rem;\n height: 1.5rem;\n padding: 0 var(--spacing-1, 0.25rem);\n color: inherit;\n background: transparent;\n border: none;\n border-radius: var(--radius-full);\n cursor: default;\n}\n\n.dayHead:is(button) {\n cursor: pointer;\n}\n\n.dayHead:is(button):hover {\n background: var(--surface-interactive-hover);\n}\n\n.dayHead:focus-visible {\n outline: var(--focus-ring-width) solid var(--border-focus);\n outline-offset: var(--focus-ring-offset);\n}\n\n.dayNumber {\n font-size: var(--font-size-sm, 0.875rem);\n font-weight: var(--font-weight-medium, 500);\n color: var(--text-secondary);\n font-variant-numeric: tabular-nums;\n}\n\n.cell[data-today] .dayHead {\n background: var(--interactive-primary-bg);\n}\n\n.cell[data-today] .dayNumber {\n color: var(--interactive-primary-text);\n font-weight: var(--font-weight-semibold, 600);\n}\n\n/* ── Event chips ── */\n.events {\n display: flex;\n flex-direction: column;\n gap: var(--spacing-1, 0.25rem);\n min-width: 0;\n}\n\n.chip {\n display: flex;\n align-items: center;\n gap: var(--spacing-1, 0.25rem);\n width: 100%;\n padding: var(--spacing-1, 0.25rem) var(--spacing-2, 0.5rem);\n font-size: var(--font-size-xs, 0.75rem);\n font-weight: var(--font-weight-medium, 500);\n text-align: start;\n color: var(--text-primary);\n background: var(--surface-subtle);\n border: none;\n border-radius: var(--radius-sm);\n cursor: default;\n}\n\n.chip:is(button) {\n cursor: pointer;\n}\n\n.chip:is(button):hover {\n background: var(--surface-interactive-hover);\n}\n\n.chip:focus-visible {\n outline: var(--focus-ring-width) solid var(--border-focus);\n outline-offset: var(--focus-ring-offset);\n}\n\n/* Series tint — background wash + leading accent bar keyed to the chart ramp. */\n.chip[data-series=\"1\"] {\n --mc-series: var(--chart-1);\n}\n.chip[data-series=\"2\"] {\n --mc-series: var(--chart-2);\n}\n.chip[data-series=\"3\"] {\n --mc-series: var(--chart-3);\n}\n.chip[data-series=\"4\"] {\n --mc-series: var(--chart-4);\n}\n.chip[data-series=\"5\"] {\n --mc-series: var(--chart-5);\n}\n\n.chip[data-series] {\n background: color-mix(in srgb, var(--mc-series) 16%, transparent);\n box-shadow: inset var(--stroke-width-medium) 0 0 0 var(--mc-series);\n}\n\n.chip[data-series]:is(button):hover {\n background: color-mix(in srgb, var(--mc-series) 28%, transparent);\n}\n\n.chipLabel {\n flex: 1;\n min-width: 0;\n overflow: hidden;\n white-space: nowrap;\n text-overflow: ellipsis;\n}\n\n/* ── Status dot ── */\n.dot {\n flex-shrink: 0;\n /* 8px dot — bound to the spacing scale. */\n width: var(--spacing-2, 0.5rem);\n height: var(--spacing-2, 0.5rem);\n border-radius: var(--radius-full);\n background: var(--text-tertiary);\n}\n\n.dot[data-status=\"success\"] {\n background: var(--surface-success-default);\n}\n.dot[data-status=\"warning\"] {\n background: var(--surface-warning-default);\n}\n.dot[data-status=\"danger\"] {\n background: var(--surface-error-default);\n}\n.dot[data-status=\"info\"] {\n background: var(--surface-info-default);\n}\n\n/* ── Overflow row ── */\n.overflow {\n padding: 0 var(--spacing-2, 0.5rem);\n font-size: var(--font-size-xs, 0.75rem);\n font-weight: var(--font-weight-medium, 500);\n color: var(--text-tertiary);\n}\n\n@media (prefers-reduced-motion: reduce) {\n .segment {\n transition: none;\n }\n}\n"
|
|
4234
4234
|
}
|
|
4235
4235
|
]
|
|
4236
4236
|
},
|
|
@@ -4257,7 +4257,7 @@
|
|
|
4257
4257
|
{
|
|
4258
4258
|
"path": "blocks/workspace-switcher/workspace-switcher.module.css",
|
|
4259
4259
|
"type": "registry:block",
|
|
4260
|
-
"content": "/* Trigger button */\n.trigger {\n display: flex;\n align-items: center;\n gap: var(--spacing-2, 0.5rem);\n width: 100%;\n padding: var(--spacing-2, 0.5rem) var(--spacing-3, 0.75rem);\n background: transparent;\n color: var(--text-primary, #111827);\n border: 1px solid transparent;\n border-radius: var(--radius-md, 0.375rem);\n font-
|
|
4260
|
+
"content": "/* Trigger button */\n.trigger {\n display: flex;\n align-items: center;\n gap: var(--spacing-2, 0.5rem);\n width: 100%;\n padding: var(--spacing-2, 0.5rem) var(--spacing-3, 0.75rem);\n background: transparent;\n color: var(--text-primary, #111827);\n border: 1px solid transparent;\n border-radius: var(--radius-md, 0.375rem);\n font-size: var(--font-size-sm, 0.875rem);\n text-align: start;\n cursor: pointer;\n min-width: 0;\n transition:\n background-color var(--motion-duration-fast, 150ms)\n var(--motion-easing-standard, ease),\n border-color var(--motion-duration-fast, 150ms)\n var(--motion-easing-standard, ease);\n}\n\n.trigger:hover {\n background: var(--surface-interactive-hover, var(--surface-hover, #f3f4f6));\n}\n\n.trigger:focus-visible {\n outline: var(--focus-ring-width, 2px) solid\n var(--focus-ring-color, var(--primary, #3b82f6));\n outline-offset: var(--focus-ring-offset, 2px);\n}\n\n.trigger[data-state=\"open\"] {\n background: var(--surface-interactive-hover, var(--surface-hover, #f3f4f6));\n}\n\n.triggerCompact {\n width: auto;\n padding: var(--spacing-2, 0.5rem);\n}\n\n.triggerAvatar {\n flex-shrink: 0;\n}\n\n.triggerText {\n display: flex;\n flex-direction: column;\n align-items: flex-start;\n flex: 1 1 auto;\n min-width: 0;\n line-height: 1.2;\n}\n\n.triggerName {\n font-weight: var(--font-weight-semibold, 600);\n font-size: var(--font-size-sm, 0.875rem);\n color: var(--text-primary, #111827);\n width: 100%;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n.triggerPlan {\n font-weight: var(--font-weight-regular, 400);\n font-size: var(--font-size-xs, 0.75rem);\n color: var(--text-tertiary, var(--text-secondary, #6b7280));\n width: 100%;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n margin-top: var(--spacing-0-5, 0.125rem);\n}\n\n.triggerCaret {\n flex-shrink: 0;\n margin-inline-start: auto;\n color: var(--text-tertiary, var(--text-secondary, #6b7280));\n}\n\n.triggerCompact .triggerCaret {\n margin-inline-start: var(--spacing-1, 0.25rem);\n}\n\n/* Menu content */\n.content {\n min-width: 14rem;\n}\n\n/* Menu item layout (composes onto DropdownMenuItem default styles) */\n.item {\n gap: var(--spacing-2, 0.5rem);\n}\n\n.itemAvatar {\n flex-shrink: 0;\n}\n\n.itemText {\n display: flex;\n flex-direction: column;\n flex: 1 1 auto;\n min-width: 0;\n line-height: 1.2;\n}\n\n.itemName {\n font-weight: var(--font-weight-medium, 500);\n font-size: var(--font-size-sm, 0.875rem);\n color: var(--text-primary, #111827);\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n.itemPlan {\n font-weight: var(--font-weight-regular, 400);\n font-size: var(--font-size-xs, 0.75rem);\n color: var(--text-tertiary, var(--text-secondary, #6b7280));\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n margin-top: var(--spacing-0-5, 0.125rem);\n}\n\n.itemCheck {\n flex-shrink: 0;\n margin-inline-start: auto;\n color: var(--text-secondary, #6b7280);\n}\n\n.emptyItem {\n font-size: var(--font-size-sm, 0.875rem);\n color: var(--text-tertiary, var(--text-secondary, #6b7280));\n}\n"
|
|
4261
4261
|
}
|
|
4262
4262
|
]
|
|
4263
4263
|
},
|
|
@@ -4284,7 +4284,7 @@
|
|
|
4284
4284
|
{
|
|
4285
4285
|
"path": "blocks/profile-menu/profile-menu.module.css",
|
|
4286
4286
|
"type": "registry:block",
|
|
4287
|
-
"content": "/* Trigger button */\n.trigger {\n display: flex;\n align-items: center;\n gap: var(--spacing-3, 0.75rem);\n width: 100%;\n padding: var(--spacing-2, 0.5rem) var(--spacing-3, 0.75rem);\n background: transparent;\n color: var(--text-primary, #111827);\n border: 1px solid transparent;\n border-radius: var(--radius-md, 0.375rem);\n font-
|
|
4287
|
+
"content": "/* Trigger button */\n.trigger {\n display: flex;\n align-items: center;\n gap: var(--spacing-3, 0.75rem);\n width: 100%;\n padding: var(--spacing-2, 0.5rem) var(--spacing-3, 0.75rem);\n background: transparent;\n color: var(--text-primary, #111827);\n border: 1px solid transparent;\n border-radius: var(--radius-md, 0.375rem);\n font-size: var(--font-size-sm, 0.875rem);\n text-align: start;\n cursor: pointer;\n min-width: 0;\n transition:\n background-color var(--motion-duration-fast, 150ms)\n var(--motion-easing-standard, ease),\n border-color var(--motion-duration-fast, 150ms)\n var(--motion-easing-standard, ease);\n}\n\n.trigger:hover {\n background: var(--surface-interactive-hover, var(--surface-hover, #f3f4f6));\n}\n\n.trigger:focus-visible {\n outline: var(--focus-ring-width, 2px) solid\n var(--focus-ring-color, var(--primary, #3b82f6));\n outline-offset: var(--focus-ring-offset, 2px);\n}\n\n.trigger[data-state=\"open\"] {\n background: var(--surface-interactive-hover, var(--surface-hover, #f3f4f6));\n}\n\n.triggerAvatarWrap {\n position: relative;\n flex-shrink: 0;\n display: inline-flex;\n}\n\n.triggerAvatar {\n flex-shrink: 0;\n}\n\n.statusDot {\n position: absolute;\n bottom: 0;\n right: 0;\n width: var(--spacing-2-5, 0.625rem);\n height: var(--spacing-2-5, 0.625rem);\n border-radius: 999px;\n border: var(--stroke-width-medium, 2px) solid\n var(--surface-card, #ffffff);\n background: var(--text-tertiary, #6b7280);\n}\n\n.statusDot[data-status=\"online\"] {\n background: var(--status-success, #10b981);\n}\n\n.statusDot[data-status=\"away\"] {\n background: var(--status-warning, #f59e0b);\n}\n\n.statusDot[data-status=\"busy\"] {\n background: var(--status-error, #ef4444);\n}\n\n.statusDot[data-status=\"offline\"] {\n background: var(--text-tertiary, #6b7280);\n}\n\n.triggerIdentity {\n display: flex;\n flex-direction: column;\n align-items: flex-start;\n flex: 1 1 auto;\n min-width: 0;\n line-height: 1.2;\n}\n\n.triggerName {\n font-weight: var(--font-weight-semibold, 600);\n font-size: var(--font-size-sm, 0.875rem);\n color: var(--text-primary, #111827);\n width: 100%;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n.triggerContext {\n display: inline-flex;\n align-items: center;\n gap: var(--spacing-1, 0.25rem);\n font-weight: var(--font-weight-regular, 400);\n font-size: var(--font-size-xs, 0.75rem);\n color: var(--text-tertiary, var(--text-secondary, #6b7280));\n width: 100%;\n min-width: 0;\n margin-top: var(--spacing-0-5, 0.125rem);\n}\n\n.triggerContextIcon {\n display: inline-flex;\n flex-shrink: 0;\n width: 0.875rem;\n height: 0.875rem;\n}\n\n.triggerContextLabel {\n min-width: 0;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n.triggerCaret {\n flex-shrink: 0;\n margin-inline-start: auto;\n color: var(--text-tertiary, var(--text-secondary, #6b7280));\n}\n\n/* Menu content */\n.content {\n min-width: 14rem;\n}\n\n.menuHeader {\n display: flex;\n flex-direction: column;\n gap: var(--spacing-0-5, 0.125rem);\n padding: var(--spacing-2, 0.5rem) var(--spacing-3, 0.75rem);\n}\n\n.menuHeaderHint {\n font-size: var(--font-size-xs, 0.75rem);\n color: var(--text-tertiary, var(--text-secondary, #6b7280));\n}\n\n.menuHeaderEmail {\n font-size: var(--font-size-sm, 0.875rem);\n font-weight: var(--font-weight-medium, 500);\n color: var(--text-primary, #111827);\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n/* Item rows */\n.item {\n gap: var(--spacing-2, 0.5rem);\n}\n\n.itemIcon {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 1rem;\n height: 1rem;\n flex-shrink: 0;\n color: var(--text-secondary, #6b7280);\n}\n\n.itemLabel {\n flex: 1 1 auto;\n min-width: 0;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n.itemBadge {\n margin-inline-start: auto;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n min-width: 1.25rem;\n padding: 0 var(--spacing-1-5, 0.375rem);\n border-radius: 999px;\n background: var(--accent-subtle, color-mix(in srgb, var(--primary, #3b82f6) 18%, transparent));\n color: var(--primary, #3b82f6);\n font-size: var(--font-size-xs, 0.75rem);\n font-weight: var(--font-weight-semibold, 600);\n line-height: 1.4;\n}\n\n/* When both badge and shortcut are present, keep shortcut after badge. */\n.itemBadge + .itemShortcut {\n margin-inline-start: var(--spacing-2, 0.5rem);\n}\n\n.itemShortcut {\n /* DropdownMenuShortcut already aligns to the end via margin-left: auto.\n When a badge precedes it, we override margin-left above to keep spacing. */\n}\n"
|
|
4288
4288
|
}
|
|
4289
4289
|
]
|
|
4290
4290
|
},
|
|
@@ -4810,7 +4810,7 @@
|
|
|
4810
4810
|
{
|
|
4811
4811
|
"path": "blocks/pricing-section/pricing-section.module.css",
|
|
4812
4812
|
"type": "registry:block",
|
|
4813
|
-
"content": ".root {\n width: 100%;\n padding: var(--spacing-16, 4rem) var(--spacing-6, 1.5rem);\n}\n\n.container {\n max-width: 72rem;\n margin: 0 auto;\n}\n\n.header {\n text-align: center;\n margin-bottom: var(--spacing-12, 3rem);\n}\n\n.headerDescription {\n margin-top: var(--spacing-4, 1rem);\n max-width: 36rem;\n margin-left: auto;\n margin-right: auto;\n}\n\n/* ── Grid ── */\n\n.grid {\n display: grid;\n gap: var(--spacing-6, 1.5rem);\n grid-template-columns: 1fr;\n align-items: start;\n}\n\n@media (min-width: 640px) {\n .grid {\n grid-template-columns: repeat(2, 1fr);\n }\n}\n\n@media (min-width: 1024px) {\n .grid {\n grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));\n }\n}\n\n/* ── Tier card ── */\n\n.tier {\n display: flex;\n flex-direction: column;\n height: 100%;\n transition:\n transform var(--motion-duration-normal, 200ms) cubic-bezier(0.4, 0, 0.2, 1),\n box-shadow var(--motion-duration-normal, 200ms) cubic-bezier(0.4, 0, 0.2, 1);\n}\n\n.tier:hover {\n transform: translateY(-4px);\n box-shadow:\n 0 0 0 1px color-mix(in srgb, var(--tier-color, var(--border-default, #e5e7eb)) 50%, transparent),\n 0 0 30px -10px color-mix(in srgb, var(--tier-color, var(--accent, #3b82f6)) 15%, transparent),\n 0 10px 30px -10px rgba(0, 0, 0, 0.15);\n}\n\n/* ── Highlighted tier ── */\n\n.tierHighlighted {\n box-shadow:\n 0 0 0 1px var(--tier-color, var(--accent, #3b82f6)),\n 0 0 0 4px color-mix(in srgb, var(--tier-color, var(--accent, #3b82f6)) 12%, transparent);\n background-color: color-mix(in srgb, var(--tier-color, var(--accent, #3b82f6)) 5%, var(--surface-card, #ffffff));\n position: relative;\n}\n\n.tierHighlighted:hover {\n box-shadow:\n 0 0 0 1px var(--tier-color, var(--accent, #3b82f6)),\n 0 0 0 4px color-mix(in srgb, var(--tier-color, var(--accent, #3b82f6)) 15%, transparent),\n 0 0 40px -10px color-mix(in srgb, var(--tier-color, var(--accent, #3b82f6)) 30%, transparent),\n 0 20px 40px -20px rgba(0, 0, 0, 0.25);\n transform: translateY(-6px);\n}\n\n/* ── Tier header ── */\n\n.tierHeader {\n display: flex;\n flex-direction: column;\n gap: var(--spacing-3, 0.75rem);\n}\n\n.tierBadge {\n align-self: flex-start;\n}\n\n.tierName {\n font-size: var(--font-size-sm, 0.875rem);\n font-weight: var(--font-weight-medium, 500);\n color: var(--tier-color, var(--text-tertiary, #9ca3af));\n text-transform: uppercase;\n letter-spacing: 0.05em;\n margin: 0;\n transition: color var(--motion-duration-fast, 100ms) cubic-bezier(0.4, 0, 0.2, 1);\n}\n\n/* ── Price ── */\n\n.priceRow {\n display: flex;\n align-items: baseline;\n gap: 0;\n}\n\n.price {\n font-size: var(--font-size-4xl, 2.25rem);\n font-family: var(--font-heading, var(--font-body,
|
|
4813
|
+
"content": ".root {\n width: 100%;\n padding: var(--spacing-16, 4rem) var(--spacing-6, 1.5rem);\n}\n\n.container {\n max-width: 72rem;\n margin: 0 auto;\n}\n\n.header {\n text-align: center;\n margin-bottom: var(--spacing-12, 3rem);\n}\n\n.headerDescription {\n margin-top: var(--spacing-4, 1rem);\n max-width: 36rem;\n margin-left: auto;\n margin-right: auto;\n}\n\n/* ── Grid ── */\n\n.grid {\n display: grid;\n gap: var(--spacing-6, 1.5rem);\n grid-template-columns: 1fr;\n align-items: start;\n}\n\n@media (min-width: 640px) {\n .grid {\n grid-template-columns: repeat(2, 1fr);\n }\n}\n\n@media (min-width: 1024px) {\n .grid {\n grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));\n }\n}\n\n/* ── Tier card ── */\n\n.tier {\n display: flex;\n flex-direction: column;\n height: 100%;\n transition:\n transform var(--motion-duration-normal, 200ms) cubic-bezier(0.4, 0, 0.2, 1),\n box-shadow var(--motion-duration-normal, 200ms) cubic-bezier(0.4, 0, 0.2, 1);\n}\n\n.tier:hover {\n transform: translateY(-4px);\n box-shadow:\n 0 0 0 1px color-mix(in srgb, var(--tier-color, var(--border-default, #e5e7eb)) 50%, transparent),\n 0 0 30px -10px color-mix(in srgb, var(--tier-color, var(--accent, #3b82f6)) 15%, transparent),\n 0 10px 30px -10px rgba(0, 0, 0, 0.15);\n}\n\n/* ── Highlighted tier ── */\n\n.tierHighlighted {\n box-shadow:\n 0 0 0 1px var(--tier-color, var(--accent, #3b82f6)),\n 0 0 0 4px color-mix(in srgb, var(--tier-color, var(--accent, #3b82f6)) 12%, transparent);\n background-color: color-mix(in srgb, var(--tier-color, var(--accent, #3b82f6)) 5%, var(--surface-card, #ffffff));\n position: relative;\n}\n\n.tierHighlighted:hover {\n box-shadow:\n 0 0 0 1px var(--tier-color, var(--accent, #3b82f6)),\n 0 0 0 4px color-mix(in srgb, var(--tier-color, var(--accent, #3b82f6)) 15%, transparent),\n 0 0 40px -10px color-mix(in srgb, var(--tier-color, var(--accent, #3b82f6)) 30%, transparent),\n 0 20px 40px -20px rgba(0, 0, 0, 0.25);\n transform: translateY(-6px);\n}\n\n/* ── Tier header ── */\n\n.tierHeader {\n display: flex;\n flex-direction: column;\n gap: var(--spacing-3, 0.75rem);\n}\n\n.tierBadge {\n align-self: flex-start;\n}\n\n.tierName {\n font-size: var(--font-size-sm, 0.875rem);\n font-weight: var(--font-weight-medium, 500);\n color: var(--tier-color, var(--text-tertiary, #9ca3af));\n text-transform: uppercase;\n letter-spacing: 0.05em;\n margin: 0;\n transition: color var(--motion-duration-fast, 100ms) cubic-bezier(0.4, 0, 0.2, 1);\n}\n\n/* ── Price ── */\n\n.priceRow {\n display: flex;\n align-items: baseline;\n gap: 0;\n}\n\n.price {\n font-size: var(--font-size-4xl, 2.25rem);\n font-family: var(--font-heading, var(--font-body, inherit));\n font-weight: var(--font-weight-medium, 500);\n color: var(--text-primary, #111827);\n line-height: 1;\n letter-spacing: -0.02em;\n}\n\n.period {\n font-size: var(--font-size-base, 1rem);\n color: var(--text-tertiary, #9ca3af);\n}\n\n.tierDescription {\n font-size: var(--font-size-sm, 0.875rem);\n font-style: italic;\n color: var(--text-tertiary, #9ca3af);\n margin: 0;\n}\n\n/* ── Feature list ── */\n\n.tierContent {\n flex: 1;\n}\n\n.featureList {\n list-style: none;\n padding: 0;\n margin: 0;\n display: flex;\n flex-direction: column;\n gap: var(--spacing-4, 1rem);\n}\n\n.featureItem {\n display: flex;\n align-items: flex-start;\n gap: var(--spacing-3, 0.75rem);\n font-size: var(--font-size-sm, 0.875rem);\n color: var(--text-secondary, #6b7280);\n}\n\n.featureIcon {\n color: var(--tier-color, var(--accent, #15803d));\n flex-shrink: 0;\n margin-top: 2px;\n}\n\n/* ── Footer ── */\n\n.tierFooter {\n margin-top: auto;\n padding-top: var(--spacing-8, 2rem);\n}\n\n.tierButton {\n width: 100%;\n}\n\n/* ── Reduced motion ── */\n\n@media (prefers-reduced-motion: reduce) {\n .tier,\n .tierName {\n transition: none;\n }\n\n .tier:hover,\n .tierHighlighted:hover {\n transform: none;\n }\n}\n"
|
|
4814
4814
|
}
|
|
4815
4815
|
]
|
|
4816
4816
|
},
|
|
@@ -4889,7 +4889,7 @@
|
|
|
4889
4889
|
{
|
|
4890
4890
|
"path": "blocks/prototype-review/prototype-review.module.css",
|
|
4891
4891
|
"type": "registry:block",
|
|
4892
|
-
"content": "/* ============================================================\n Prototype Review block\n Theme-agnostic. All colors come from Visor semantic tokens.\n The brand color is injected by the React block as\n --prototype-review-brand (per-instance override).\n ============================================================ */\n\n.root {\n display: flex;\n flex-direction: column;\n width: 100%;\n min-height: 100vh;\n background: var(--surface-page);\n color: var(--text-primary);\n font-family: var(\n --font-body,\n var(--font-family-body, ui-sans-serif, system-ui, sans-serif)\n );\n font-weight: 300;\n line-height: 1.5;\n -webkit-font-smoothing: antialiased;\n container-type: inline-size;\n}\n\n/* ─── Header ─────────────────────────────────────────────── */\n\n.chrome {\n position: sticky;\n top: 0;\n z-index: 100;\n background: var(--surface-card);\n border-bottom: var(--stroke-width-thin, 1px) solid var(--border-muted);\n}\n\n.chromeRow {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: var(--spacing-6);\n padding: var(--spacing-3) var(--spacing-7);\n flex-wrap: wrap;\n}\n\n.brand {\n display: flex;\n align-items: center;\n gap: var(--spacing-3);\n min-width: 0;\n}\n\n.brandMark {\n width: 1.75rem;\n height: 1.75rem;\n background: var(--prototype-review-brand, var(--interactive-primary-bg));\n display: grid;\n place-items: center;\n color: var(--prototype-review-brand-on, var(--interactive-primary-text));\n font-family: var(\n --font-display,\n var(--font-family-display, var(--font-family-heading, inherit))\n );\n font-weight: 700;\n font-size: var(--font-size-xs);\n letter-spacing: -0.02em;\n}\n\n.brandText {\n display: flex;\n flex-direction: column;\n line-height: 1.15;\n}\n\n.brandName {\n font-family: var(\n --font-display,\n var(--font-family-display, var(--font-family-heading, inherit))\n );\n font-weight: 600;\n font-size: var(--font-size-sm);\n letter-spacing: 0.12em;\n text-transform: uppercase;\n}\n\n.brandSub {\n font-family: var(--font-mono, var(--font-family-mono, monospace));\n font-size: var(--font-size-xs);\n color: var(--text-tertiary);\n letter-spacing: 0.05em;\n}\n\n.chromeActions {\n display: flex;\n gap: var(--spacing-2);\n align-items: center;\n flex-wrap: wrap;\n}\n\n.pill {\n font-family: var(--font-mono, var(--font-family-mono, monospace));\n font-size: var(--font-size-xs);\n text-transform: uppercase;\n letter-spacing: 0.12em;\n padding: var(--spacing-1) var(--spacing-2);\n border: var(--stroke-width-thin, 1px) solid var(--border-default);\n color: var(--text-tertiary);\n border-radius: var(--radius-full, 9999px);\n}\n\n.pillBrand {\n background: var(--prototype-review-brand-soft, var(--surface-subtle));\n border-color: var(--prototype-review-brand, var(--border-default));\n color: var(--prototype-review-brand, var(--text-primary));\n}\n\n/* ─── Controls ───────────────────────────────────────────── */\n\n.controls {\n border-bottom: var(--stroke-width-thin, 1px) solid var(--border-muted);\n background: var(--surface-muted, var(--surface-subtle));\n}\n\n.controlsRow {\n display: grid;\n grid-template-columns: minmax(0, 1fr) auto auto;\n gap: var(--spacing-6);\n align-items: center;\n padding: var(--spacing-3) var(--spacing-7);\n}\n\n@container (max-width: 64rem) {\n .controlsRow {\n grid-template-columns: 1fr;\n }\n}\n\n.controlGroup {\n display: flex;\n align-items: center;\n gap: var(--spacing-4);\n flex-wrap: wrap;\n}\n\n.controlLabel {\n font-family: var(--font-mono, var(--font-family-mono, monospace));\n font-size: var(--font-size-xs);\n letter-spacing: 0.12em;\n text-transform: uppercase;\n color: var(--text-tertiary);\n}\n\n/* Tabs */\n\n.tabs {\n display: flex;\n gap: 0;\n flex-wrap: wrap;\n align-items: stretch;\n border: var(--stroke-width-thin, 1px) solid var(--border-default);\n background: var(--surface-page);\n width: fit-content;\n border-radius: var(--radius-full, 9999px);\n overflow: hidden;\n}\n\n.tab {\n background: transparent;\n border: none;\n color: var(--text-tertiary);\n font-family: var(--font-mono, var(--font-family-mono, monospace));\n font-size: var(--font-size-xs);\n letter-spacing: 0.08em;\n text-transform: uppercase;\n padding: var(--spacing-2) var(--spacing-4);\n cursor: pointer;\n transition:\n color var(--motion-duration-fast, 150ms)\n var(--motion-easing-standard, ease),\n background var(--motion-duration-fast, 150ms)\n var(--motion-easing-standard, ease);\n}\n\n.tab:hover {\n color: var(--text-primary);\n}\n\n.tab[aria-selected=\"true\"] {\n background: var(--prototype-review-brand, var(--interactive-primary-bg));\n color: var(--prototype-review-brand-on, var(--interactive-primary-text));\n}\n\n.tab:focus-visible {\n outline: var(--focus-ring-width, 2px) solid\n var(--focus-ring-color, var(--prototype-review-brand, var(--primary)));\n outline-offset: calc(var(--focus-ring-offset, 2px) * -1);\n}\n\n.tabId {\n font-family: var(\n --font-display,\n var(--font-family-display, var(--font-family-heading, inherit))\n );\n font-weight: 600;\n letter-spacing: 0.02em;\n text-transform: none;\n font-size: var(--font-size-sm);\n margin-right: var(--spacing-2);\n}\n\n/* Theme select */\n\n.themeGroup {\n display: flex;\n align-items: center;\n gap: var(--spacing-2);\n}\n\n.themeSelect {\n background: var(--surface-page);\n border: var(--stroke-width-thin, 1px) solid var(--border-default);\n color: var(--text-primary);\n font-family: var(--font-mono, var(--font-family-mono, monospace));\n font-size: var(--font-size-xs);\n padding: var(--spacing-2) var(--spacing-3);\n border-radius: var(--radius-full, 9999px);\n cursor: pointer;\n letter-spacing: 0.05em;\n text-transform: uppercase;\n}\n\n.themeSelect:focus-visible {\n outline: var(--focus-ring-width, 2px) solid\n var(--focus-ring-color, var(--prototype-review-brand, var(--primary)));\n outline-offset: var(--focus-ring-offset, 2px);\n}\n\n/* Mode + viewport toggle buttons */\n\n.modeGroup,\n.vpGroup {\n display: flex;\n align-items: center;\n gap: var(--spacing-2);\n}\n\n.toggleButtons {\n display: flex;\n border: var(--stroke-width-thin, 1px) solid var(--border-default);\n background: var(--surface-page);\n border-radius: var(--radius-full, 9999px);\n overflow: hidden;\n}\n\n.toggleButton {\n background: transparent;\n border: none;\n color: var(--text-tertiary);\n font-family: var(--font-mono, var(--font-family-mono, monospace));\n font-size: var(--font-size-xs);\n letter-spacing: 0.05em;\n padding: var(--spacing-2) var(--spacing-3);\n cursor: pointer;\n text-transform: uppercase;\n transition:\n color var(--motion-duration-fast, 150ms)\n var(--motion-easing-standard, ease),\n background var(--motion-duration-fast, 150ms)\n var(--motion-easing-standard, ease);\n}\n\n.toggleButton:hover {\n color: var(--text-primary);\n}\n\n.toggleButton[aria-pressed=\"true\"] {\n background: var(--prototype-review-brand, var(--interactive-primary-bg));\n color: var(--prototype-review-brand-on, var(--interactive-primary-text));\n}\n\n.toggleButton:focus-visible {\n outline: var(--focus-ring-width, 2px) solid\n var(--focus-ring-color, var(--prototype-review-brand, var(--primary)));\n outline-offset: calc(var(--focus-ring-offset, 2px) * -1);\n}\n\n/* Brand picker */\n\n.picker {\n display: flex;\n align-items: center;\n gap: var(--spacing-3);\n flex-wrap: wrap;\n}\n\n.swatches {\n display: flex;\n gap: var(--spacing-1);\n align-items: center;\n}\n\n.swatch {\n width: 1.375rem;\n height: 1.375rem;\n border-radius: var(--radius-full, 9999px);\n border: var(--stroke-width-medium, 2px) solid transparent;\n cursor: pointer;\n padding: 0;\n transition:\n transform var(--motion-duration-fast, 150ms)\n var(--motion-easing-standard, ease),\n border-color var(--motion-duration-fast, 150ms)\n var(--motion-easing-standard, ease);\n}\n\n.swatch:hover {\n transform: scale(1.12);\n}\n\n.swatch[data-active=\"true\"] {\n border-color: var(--text-primary);\n box-shadow: 0 0 0 var(--stroke-width-medium, 2px) var(--surface-page);\n}\n\n.swatch:focus-visible {\n outline: var(--focus-ring-width, 2px) solid\n var(--focus-ring-color, var(--prototype-review-brand, var(--primary)));\n outline-offset: var(--focus-ring-offset, 2px);\n}\n\n.hexInput {\n background: var(--surface-page);\n border: var(--stroke-width-thin, 1px) solid var(--border-default);\n color: var(--text-primary);\n font-family: var(--font-mono, var(--font-family-mono, monospace));\n font-size: var(--font-size-xs);\n padding: var(--spacing-1) var(--spacing-3);\n width: 8.5rem;\n letter-spacing: 0.05em;\n text-transform: uppercase;\n border-radius: var(--radius-full, 9999px);\n}\n\n.hexInput:focus {\n outline: none;\n border-color: var(--prototype-review-brand, var(--border-default));\n}\n\n.hexInput:focus-visible {\n outline: var(--focus-ring-width, 2px) solid\n var(--focus-ring-color, var(--prototype-review-brand, var(--primary)));\n outline-offset: var(--focus-ring-offset, 2px);\n}\n\n.resetButton {\n background: transparent;\n border: var(--stroke-width-thin, 1px) solid var(--border-default);\n color: var(--text-tertiary);\n font-family: var(--font-mono, var(--font-family-mono, monospace));\n font-size: var(--font-size-xs);\n letter-spacing: 0.1em;\n text-transform: uppercase;\n padding: var(--spacing-1) var(--spacing-3);\n border-radius: var(--radius-full, 9999px);\n cursor: pointer;\n transition:\n color var(--motion-duration-fast, 150ms)\n var(--motion-easing-standard, ease),\n border-color var(--motion-duration-fast, 150ms)\n var(--motion-easing-standard, ease);\n}\n\n.resetButton:hover {\n color: var(--prototype-review-brand, var(--text-primary));\n border-color: var(--prototype-review-brand, var(--border-strong));\n}\n\n.resetButton:focus-visible {\n outline: var(--focus-ring-width, 2px) solid\n var(--focus-ring-color, var(--prototype-review-brand, var(--primary)));\n outline-offset: var(--focus-ring-offset, 2px);\n}\n\n/* ─── Stage ──────────────────────────────────────────────── */\n\n.stage {\n padding: var(--spacing-7);\n max-width: 100%;\n}\n\n.stageMeta {\n display: flex;\n gap: var(--spacing-6);\n align-items: flex-start;\n justify-content: space-between;\n margin-bottom: var(--spacing-5);\n flex-wrap: wrap;\n}\n\n.stageTitleBlock {\n min-width: 0;\n max-width: 56rem;\n}\n\n.stageTitle {\n font-family: var(\n --font-display,\n var(--font-family-display, var(--font-family-heading, inherit))\n );\n font-weight: 500;\n font-size: var(--font-size-2xl);\n letter-spacing: -0.01em;\n line-height: 1.2;\n margin-bottom: var(--spacing-1);\n}\n\n.stageTitle em {\n font-style: normal;\n color: var(--prototype-review-brand, var(--primary));\n}\n\n.stageSummary {\n color: var(--text-secondary);\n font-size: var(--font-size-base);\n line-height: 1.6;\n}\n\n.stageTagRow {\n display: flex;\n gap: var(--spacing-2);\n flex-wrap: wrap;\n}\n\n/* Viewport grid */\n\n.viewportGrid {\n display: grid;\n gap: var(--spacing-6);\n grid-template-columns: 375px 768px 1280px;\n overflow-x: auto;\n padding-bottom: var(--spacing-4);\n}\n\n.viewportGridSolo {\n grid-template-columns: 1fr;\n}\n\n.vpFrame {\n background: var(--surface-card);\n border: var(--stroke-width-thin, 1px) solid var(--border-default);\n border-radius: var(--radius-lg);\n overflow: hidden;\n display: flex;\n flex-direction: column;\n min-width: 0;\n}\n\n.vpFrameHead {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: var(--spacing-2) var(--spacing-3);\n border-bottom: var(--stroke-width-thin, 1px) solid var(--border-muted);\n background: var(--surface-muted, var(--surface-subtle));\n}\n\n.vpFrameName {\n font-family: var(--font-mono, var(--font-family-mono, monospace));\n font-size: var(--font-size-xs);\n letter-spacing: 0.12em;\n text-transform: uppercase;\n color: var(--text-tertiary);\n}\n\n.vpFrameDims {\n font-family: var(--font-mono, var(--font-family-mono, monospace));\n font-size: var(--font-size-xs);\n color: var(--text-disabled, var(--text-tertiary));\n}\n\n.vpIframeWrap {\n background: var(--surface-page);\n}\n\n.vpIframe {\n width: 100%;\n border: none;\n display: block;\n background: var(--surface-page);\n}\n\n/* ─── Landing ────────────────────────────────────────────── */\n\n.landing {\n max-width: 64rem;\n margin: 0 auto;\n padding: var(--spacing-12, 3.5rem) var(--spacing-7);\n}\n\n.landingEyebrow {\n font-family: var(--font-mono, var(--font-family-mono, monospace));\n font-size: var(--font-size-sm);\n letter-spacing: 0.18em;\n text-transform: uppercase;\n color: var(--prototype-review-brand, var(--primary));\n margin-bottom: var(--spacing-4);\n}\n\n.landingTitle {\n font-family: var(\n --font-display,\n var(--font-family-display, var(--font-family-heading, inherit))\n );\n font-weight: 500;\n font-size: clamp(2rem, 4.5vw, 3.25rem);\n line-height: 1.05;\n letter-spacing: -0.02em;\n margin-bottom: var(--spacing-5);\n}\n\n.landingTitle em {\n font-style: normal;\n color: var(--prototype-review-brand, var(--primary));\n}\n\n.landingLede {\n font-size: var(--font-size-lg);\n color: var(--text-secondary);\n line-height: 1.65;\n margin-bottom: var(--spacing-10, 2.5rem);\n max-width: 48rem;\n}\n\n.landingLede code {\n font-family: var(--font-mono, var(--font-family-mono, monospace));\n color: var(--prototype-review-brand, var(--primary));\n font-size: 0.95em;\n}\n\n.protoGrid {\n display: grid;\n grid-template-columns: repeat(auto-fit, minmax(15rem, 1fr));\n gap: var(--spacing-5);\n margin-bottom: var(--spacing-12, 3rem);\n}\n\n.protoCard {\n background: var(--surface-card);\n border: var(--stroke-width-thin, 1px) solid var(--border-default);\n border-radius: var(--radius-lg);\n padding: var(--spacing-6);\n cursor: pointer;\n text-align: left;\n font-family: inherit;\n color: inherit;\n display: flex;\n flex-direction: column;\n gap: var(--spacing-3);\n transition:\n border-color var(--motion-duration-fast, 150ms)\n var(--motion-easing-standard, ease),\n background var(--motion-duration-fast, 150ms)\n var(--motion-easing-standard, ease);\n}\n\n.protoCard:hover {\n border-color: var(--prototype-review-brand, var(--border-strong));\n background: var(--surface-interactive-hover, var(--surface-subtle));\n}\n\n.protoCard:focus-visible {\n outline: var(--focus-ring-width, 2px) solid\n var(--focus-ring-color, var(--prototype-review-brand, var(--primary)));\n outline-offset: var(--focus-ring-offset, 2px);\n}\n\n.protoCardId {\n font-family: var(--font-mono, var(--font-family-mono, monospace));\n font-size: var(--font-size-xs);\n letter-spacing: 0.18em;\n text-transform: uppercase;\n color: var(--prototype-review-brand, var(--primary));\n}\n\n.protoCardTitle {\n font-family: var(\n --font-display,\n var(--font-family-display, var(--font-family-heading, inherit))\n );\n font-weight: 500;\n font-size: var(--font-size-xl, 1.25rem);\n letter-spacing: -0.01em;\n}\n\n.protoCardDesc {\n color: var(--text-secondary);\n font-size: var(--font-size-sm);\n line-height: 1.55;\n}\n\n.protoCardMeta {\n margin-top: auto;\n font-family: var(--font-mono, var(--font-family-mono, monospace));\n font-size: var(--font-size-xs);\n color: var(--text-tertiary);\n letter-spacing: 0.05em;\n text-transform: uppercase;\n}\n\n.ctxGrid {\n display: grid;\n grid-template-columns: repeat(auto-fit, minmax(14rem, 1fr));\n gap: var(--spacing-5);\n margin-top: var(--spacing-10, 2.5rem);\n padding-top: var(--spacing-8);\n border-top: var(--stroke-width-thin, 1px) solid var(--border-muted);\n}\n\n.ctxCard h4 {\n font-family: var(--font-mono, var(--font-family-mono, monospace));\n font-size: var(--font-size-sm);\n text-transform: uppercase;\n letter-spacing: 0.12em;\n color: var(--prototype-review-brand, var(--primary));\n margin-bottom: var(--spacing-2);\n}\n\n.ctxCard p {\n color: var(--text-secondary);\n font-size: var(--font-size-sm);\n line-height: 1.6;\n}\n\n/* ─── Footer ─────────────────────────────────────────────── */\n\n.foot {\n border-top: var(--stroke-width-thin, 1px) solid var(--border-muted);\n padding: var(--spacing-6) var(--spacing-7);\n display: flex;\n justify-content: space-between;\n gap: var(--spacing-4);\n flex-wrap: wrap;\n font-family: var(--font-mono, var(--font-family-mono, monospace));\n font-size: var(--font-size-xs);\n color: var(--text-tertiary);\n letter-spacing: 0.06em;\n text-transform: uppercase;\n margin-top: auto;\n}\n"
|
|
4892
|
+
"content": "/* ============================================================\n Prototype Review block\n Theme-agnostic. All colors come from Visor semantic tokens.\n The brand color is injected by the React block as\n --prototype-review-brand (per-instance override).\n ============================================================ */\n\n.root {\n display: flex;\n flex-direction: column;\n width: 100%;\n min-height: 100vh;\n background: var(--surface-page);\n color: var(--text-primary);\n font-family: var(\n --font-body,\n var(--font-family-body, ui-sans-serif, system-ui, sans-serif)\n );\n font-weight: 300;\n line-height: 1.5;\n -webkit-font-smoothing: antialiased;\n container-type: inline-size;\n}\n\n/* ─── Header ─────────────────────────────────────────────── */\n\n.chrome {\n position: sticky;\n top: 0;\n z-index: 100;\n background: var(--surface-card);\n border-bottom: var(--stroke-width-thin, 1px) solid var(--border-muted);\n}\n\n.chromeRow {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: var(--spacing-6);\n padding: var(--spacing-3) var(--spacing-7);\n flex-wrap: wrap;\n}\n\n.brand {\n display: flex;\n align-items: center;\n gap: var(--spacing-3);\n min-width: 0;\n}\n\n.brandMark {\n width: 1.75rem;\n height: 1.75rem;\n background: var(--prototype-review-brand, var(--interactive-primary-bg));\n display: grid;\n place-items: center;\n color: var(--prototype-review-brand-on, var(--interactive-primary-text));\n font-family: var(\n --font-display,\n var(--font-family-display, var(--font-family-heading, inherit))\n );\n font-weight: 700;\n font-size: var(--font-size-xs);\n letter-spacing: -0.02em;\n}\n\n.brandText {\n display: flex;\n flex-direction: column;\n line-height: 1.15;\n}\n\n.brandName {\n font-family: var(\n --font-display,\n var(--font-family-display, var(--font-family-heading, inherit))\n );\n font-weight: 600;\n font-size: var(--font-size-sm);\n letter-spacing: 0.12em;\n text-transform: uppercase;\n}\n\n.brandSub {\n font-family: var(--font-mono, var(--font-family-mono, monospace));\n font-size: var(--font-size-xs);\n color: var(--text-tertiary);\n letter-spacing: 0.05em;\n}\n\n.chromeActions {\n display: flex;\n gap: var(--spacing-2);\n align-items: center;\n flex-wrap: wrap;\n}\n\n.pill {\n font-family: var(--font-mono, var(--font-family-mono, monospace));\n font-size: var(--font-size-xs);\n text-transform: uppercase;\n letter-spacing: 0.12em;\n padding: var(--spacing-1) var(--spacing-2);\n border: var(--stroke-width-thin, 1px) solid var(--border-default);\n color: var(--text-tertiary);\n border-radius: var(--radius-full, 9999px);\n}\n\n.pillBrand {\n background: var(--prototype-review-brand-soft, var(--surface-subtle));\n border-color: var(--prototype-review-brand, var(--border-default));\n color: var(--prototype-review-brand, var(--text-primary));\n}\n\n/* ─── Controls ───────────────────────────────────────────── */\n\n.controls {\n border-bottom: var(--stroke-width-thin, 1px) solid var(--border-muted);\n background: var(--surface-muted, var(--surface-subtle));\n}\n\n.controlsRow {\n display: grid;\n grid-template-columns: minmax(0, 1fr) auto auto;\n gap: var(--spacing-6);\n align-items: center;\n padding: var(--spacing-3) var(--spacing-7);\n}\n\n@container (max-width: 64rem) {\n .controlsRow {\n grid-template-columns: 1fr;\n }\n}\n\n.controlGroup {\n display: flex;\n align-items: center;\n gap: var(--spacing-4);\n flex-wrap: wrap;\n}\n\n.controlLabel {\n font-family: var(--font-mono, var(--font-family-mono, monospace));\n font-size: var(--font-size-xs);\n letter-spacing: 0.12em;\n text-transform: uppercase;\n color: var(--text-tertiary);\n}\n\n/* Tabs */\n\n.tabs {\n display: flex;\n gap: 0;\n flex-wrap: wrap;\n align-items: stretch;\n border: var(--stroke-width-thin, 1px) solid var(--border-default);\n background: var(--surface-page);\n width: fit-content;\n border-radius: var(--radius-full, 9999px);\n overflow: hidden;\n}\n\n.tab {\n background: transparent;\n border: none;\n color: var(--text-tertiary);\n font-family: var(--font-mono, var(--font-family-mono, monospace));\n font-size: var(--font-size-xs);\n letter-spacing: 0.08em;\n text-transform: uppercase;\n padding: var(--spacing-2) var(--spacing-4);\n cursor: pointer;\n transition:\n color var(--motion-duration-fast, 150ms)\n var(--motion-easing-standard, ease),\n background var(--motion-duration-fast, 150ms)\n var(--motion-easing-standard, ease);\n}\n\n.tab:hover {\n color: var(--text-primary);\n}\n\n.tab[aria-selected=\"true\"] {\n background: var(--prototype-review-brand, var(--interactive-primary-bg));\n color: var(--prototype-review-brand-on, var(--interactive-primary-text));\n}\n\n.tab:focus-visible {\n outline: var(--focus-ring-width, 2px) solid\n var(--focus-ring-color, var(--prototype-review-brand, var(--primary)));\n outline-offset: calc(var(--focus-ring-offset, 2px) * -1);\n}\n\n.tabId {\n font-family: var(\n --font-display,\n var(--font-family-display, var(--font-family-heading, inherit))\n );\n font-weight: 600;\n letter-spacing: 0.02em;\n text-transform: none;\n font-size: var(--font-size-sm);\n margin-right: var(--spacing-2);\n}\n\n/* Theme select */\n\n.themeGroup {\n display: flex;\n align-items: center;\n gap: var(--spacing-2);\n}\n\n.themeSelect {\n background: var(--surface-page);\n border: var(--stroke-width-thin, 1px) solid var(--border-default);\n color: var(--text-primary);\n font-family: var(--font-mono, var(--font-family-mono, monospace));\n font-size: var(--font-size-xs);\n padding: var(--spacing-2) var(--spacing-3);\n border-radius: var(--radius-full, 9999px);\n cursor: pointer;\n letter-spacing: 0.05em;\n text-transform: uppercase;\n}\n\n.themeSelect:focus-visible {\n outline: var(--focus-ring-width, 2px) solid\n var(--focus-ring-color, var(--prototype-review-brand, var(--primary)));\n outline-offset: var(--focus-ring-offset, 2px);\n}\n\n/* Mode + viewport toggle buttons */\n\n.modeGroup,\n.vpGroup {\n display: flex;\n align-items: center;\n gap: var(--spacing-2);\n}\n\n.toggleButtons {\n display: flex;\n border: var(--stroke-width-thin, 1px) solid var(--border-default);\n background: var(--surface-page);\n border-radius: var(--radius-full, 9999px);\n overflow: hidden;\n}\n\n.toggleButton {\n background: transparent;\n border: none;\n color: var(--text-tertiary);\n font-family: var(--font-mono, var(--font-family-mono, monospace));\n font-size: var(--font-size-xs);\n letter-spacing: 0.05em;\n padding: var(--spacing-2) var(--spacing-3);\n cursor: pointer;\n text-transform: uppercase;\n transition:\n color var(--motion-duration-fast, 150ms)\n var(--motion-easing-standard, ease),\n background var(--motion-duration-fast, 150ms)\n var(--motion-easing-standard, ease);\n}\n\n.toggleButton:hover {\n color: var(--text-primary);\n}\n\n.toggleButton[aria-pressed=\"true\"] {\n background: var(--prototype-review-brand, var(--interactive-primary-bg));\n color: var(--prototype-review-brand-on, var(--interactive-primary-text));\n}\n\n.toggleButton:focus-visible {\n outline: var(--focus-ring-width, 2px) solid\n var(--focus-ring-color, var(--prototype-review-brand, var(--primary)));\n outline-offset: calc(var(--focus-ring-offset, 2px) * -1);\n}\n\n/* Brand picker */\n\n.picker {\n display: flex;\n align-items: center;\n gap: var(--spacing-3);\n flex-wrap: wrap;\n}\n\n.swatches {\n display: flex;\n gap: var(--spacing-1);\n align-items: center;\n}\n\n.swatch {\n width: 1.375rem;\n height: 1.375rem;\n border-radius: var(--radius-full, 9999px);\n border: var(--stroke-width-medium, 2px) solid transparent;\n cursor: pointer;\n padding: 0;\n transition:\n transform var(--motion-duration-fast, 150ms)\n var(--motion-easing-standard, ease),\n border-color var(--motion-duration-fast, 150ms)\n var(--motion-easing-standard, ease);\n}\n\n.swatch:hover {\n transform: scale(1.12);\n}\n\n.swatch[data-active=\"true\"] {\n border-color: var(--text-primary);\n box-shadow: 0 0 0 var(--stroke-width-medium, 2px) var(--surface-page);\n}\n\n.swatch:focus-visible {\n outline: var(--focus-ring-width, 2px) solid\n var(--focus-ring-color, var(--prototype-review-brand, var(--primary)));\n outline-offset: var(--focus-ring-offset, 2px);\n}\n\n.hexInput {\n background: var(--surface-page);\n border: var(--stroke-width-thin, 1px) solid var(--border-default);\n color: var(--text-primary);\n font-family: var(--font-mono, var(--font-family-mono, monospace));\n font-size: var(--font-size-xs);\n padding: var(--spacing-1) var(--spacing-3);\n width: 8.5rem;\n letter-spacing: 0.05em;\n text-transform: uppercase;\n border-radius: var(--radius-full, 9999px);\n}\n\n.hexInput:focus {\n outline: none;\n border-color: var(--prototype-review-brand, var(--border-default));\n}\n\n.hexInput:focus-visible {\n outline: var(--focus-ring-width, 2px) solid\n var(--focus-ring-color, var(--prototype-review-brand, var(--primary)));\n outline-offset: var(--focus-ring-offset, 2px);\n}\n\n.resetButton {\n background: transparent;\n border: var(--stroke-width-thin, 1px) solid var(--border-default);\n color: var(--text-tertiary);\n font-family: var(--font-mono, var(--font-family-mono, monospace));\n font-size: var(--font-size-xs);\n letter-spacing: 0.1em;\n text-transform: uppercase;\n padding: var(--spacing-1) var(--spacing-3);\n border-radius: var(--radius-full, 9999px);\n cursor: pointer;\n transition:\n color var(--motion-duration-fast, 150ms)\n var(--motion-easing-standard, ease),\n border-color var(--motion-duration-fast, 150ms)\n var(--motion-easing-standard, ease);\n}\n\n.resetButton:hover {\n color: var(--prototype-review-brand, var(--text-primary));\n border-color: var(--prototype-review-brand, var(--border-strong));\n}\n\n.resetButton:focus-visible {\n outline: var(--focus-ring-width, 2px) solid\n var(--focus-ring-color, var(--prototype-review-brand, var(--primary)));\n outline-offset: var(--focus-ring-offset, 2px);\n}\n\n/* ─── Stage ──────────────────────────────────────────────── */\n\n.stage {\n padding: var(--spacing-7);\n max-width: 100%;\n}\n\n.stageMeta {\n display: flex;\n gap: var(--spacing-6);\n align-items: flex-start;\n justify-content: space-between;\n margin-bottom: var(--spacing-5);\n flex-wrap: wrap;\n}\n\n.stageTitleBlock {\n min-width: 0;\n max-width: 56rem;\n}\n\n.stageTitle {\n font-family: var(\n --font-display,\n var(--font-family-display, var(--font-family-heading, inherit))\n );\n font-weight: 500;\n font-size: var(--font-size-2xl);\n letter-spacing: -0.01em;\n line-height: 1.2;\n margin-bottom: var(--spacing-1);\n}\n\n.stageTitle em {\n font-style: normal;\n color: var(--prototype-review-brand, var(--primary));\n}\n\n.stageSummary {\n color: var(--text-secondary);\n font-size: var(--font-size-base);\n line-height: 1.6;\n}\n\n.stageTagRow {\n display: flex;\n gap: var(--spacing-2);\n flex-wrap: wrap;\n}\n\n/* Viewport grid */\n\n.viewportGrid {\n display: grid;\n gap: var(--spacing-6);\n grid-template-columns: 375px 768px 1280px;\n overflow-x: auto;\n padding-bottom: var(--spacing-4);\n}\n\n.viewportGridSolo {\n grid-template-columns: 1fr;\n}\n\n.vpFrame {\n background: var(--surface-card);\n border: var(--stroke-width-thin, 1px) solid var(--border-default);\n border-radius: var(--radius-lg);\n overflow: hidden;\n display: flex;\n flex-direction: column;\n min-width: 0;\n}\n\n.vpFrameHead {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: var(--spacing-2) var(--spacing-3);\n border-bottom: var(--stroke-width-thin, 1px) solid var(--border-muted);\n background: var(--surface-muted, var(--surface-subtle));\n}\n\n.vpFrameName {\n font-family: var(--font-mono, var(--font-family-mono, monospace));\n font-size: var(--font-size-xs);\n letter-spacing: 0.12em;\n text-transform: uppercase;\n color: var(--text-tertiary);\n}\n\n.vpFrameDims {\n font-family: var(--font-mono, var(--font-family-mono, monospace));\n font-size: var(--font-size-xs);\n color: var(--text-disabled, var(--text-tertiary));\n}\n\n.vpIframeWrap {\n background: var(--surface-page);\n}\n\n.vpIframe {\n width: 100%;\n border: none;\n display: block;\n background: var(--surface-page);\n}\n\n/* ─── Landing ────────────────────────────────────────────── */\n\n.landing {\n max-width: 64rem;\n margin: 0 auto;\n padding: var(--spacing-12, 3.5rem) var(--spacing-7);\n}\n\n.landingEyebrow {\n font-family: var(--font-mono, var(--font-family-mono, monospace));\n font-size: var(--font-size-sm);\n letter-spacing: 0.18em;\n text-transform: uppercase;\n color: var(--prototype-review-brand, var(--primary));\n margin-bottom: var(--spacing-4);\n}\n\n.landingTitle {\n font-family: var(\n --font-display,\n var(--font-family-display, var(--font-family-heading, inherit))\n );\n font-weight: 500;\n font-size: clamp(2rem, 4.5vw, 3.25rem);\n line-height: 1.05;\n letter-spacing: -0.02em;\n margin-bottom: var(--spacing-5);\n}\n\n.landingTitle em {\n font-style: normal;\n color: var(--prototype-review-brand, var(--primary));\n}\n\n.landingLede {\n font-size: var(--font-size-lg);\n color: var(--text-secondary);\n line-height: 1.65;\n margin-bottom: var(--spacing-10, 2.5rem);\n max-width: 48rem;\n}\n\n.landingLede code {\n font-family: var(--font-mono, var(--font-family-mono, monospace));\n color: var(--prototype-review-brand, var(--primary));\n font-size: 0.95em;\n}\n\n.protoGrid {\n display: grid;\n grid-template-columns: repeat(auto-fit, minmax(15rem, 1fr));\n gap: var(--spacing-5);\n margin-bottom: var(--spacing-12, 3rem);\n}\n\n.protoCard {\n background: var(--surface-card);\n border: var(--stroke-width-thin, 1px) solid var(--border-default);\n border-radius: var(--radius-lg);\n padding: var(--spacing-6);\n cursor: pointer;\n text-align: left;\n color: inherit;\n display: flex;\n flex-direction: column;\n gap: var(--spacing-3);\n transition:\n border-color var(--motion-duration-fast, 150ms)\n var(--motion-easing-standard, ease),\n background var(--motion-duration-fast, 150ms)\n var(--motion-easing-standard, ease);\n}\n\n.protoCard:hover {\n border-color: var(--prototype-review-brand, var(--border-strong));\n background: var(--surface-interactive-hover, var(--surface-subtle));\n}\n\n.protoCard:focus-visible {\n outline: var(--focus-ring-width, 2px) solid\n var(--focus-ring-color, var(--prototype-review-brand, var(--primary)));\n outline-offset: var(--focus-ring-offset, 2px);\n}\n\n.protoCardId {\n font-family: var(--font-mono, var(--font-family-mono, monospace));\n font-size: var(--font-size-xs);\n letter-spacing: 0.18em;\n text-transform: uppercase;\n color: var(--prototype-review-brand, var(--primary));\n}\n\n.protoCardTitle {\n font-family: var(\n --font-display,\n var(--font-family-display, var(--font-family-heading, inherit))\n );\n font-weight: 500;\n font-size: var(--font-size-xl, 1.25rem);\n letter-spacing: -0.01em;\n}\n\n.protoCardDesc {\n color: var(--text-secondary);\n font-size: var(--font-size-sm);\n line-height: 1.55;\n}\n\n.protoCardMeta {\n margin-top: auto;\n font-family: var(--font-mono, var(--font-family-mono, monospace));\n font-size: var(--font-size-xs);\n color: var(--text-tertiary);\n letter-spacing: 0.05em;\n text-transform: uppercase;\n}\n\n.ctxGrid {\n display: grid;\n grid-template-columns: repeat(auto-fit, minmax(14rem, 1fr));\n gap: var(--spacing-5);\n margin-top: var(--spacing-10, 2.5rem);\n padding-top: var(--spacing-8);\n border-top: var(--stroke-width-thin, 1px) solid var(--border-muted);\n}\n\n.ctxCard h4 {\n font-family: var(--font-mono, var(--font-family-mono, monospace));\n font-size: var(--font-size-sm);\n text-transform: uppercase;\n letter-spacing: 0.12em;\n color: var(--prototype-review-brand, var(--primary));\n margin-bottom: var(--spacing-2);\n}\n\n.ctxCard p {\n color: var(--text-secondary);\n font-size: var(--font-size-sm);\n line-height: 1.6;\n}\n\n/* ─── Footer ─────────────────────────────────────────────── */\n\n.foot {\n border-top: var(--stroke-width-thin, 1px) solid var(--border-muted);\n padding: var(--spacing-6) var(--spacing-7);\n display: flex;\n justify-content: space-between;\n gap: var(--spacing-4);\n flex-wrap: wrap;\n font-family: var(--font-mono, var(--font-family-mono, monospace));\n font-size: var(--font-size-xs);\n color: var(--text-tertiary);\n letter-spacing: 0.06em;\n text-transform: uppercase;\n margin-top: auto;\n}\n"
|
|
4893
4893
|
}
|
|
4894
4894
|
]
|
|
4895
4895
|
},
|