@pipelex/mthds-form 0.28.0 → 0.30.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/core/gate.js CHANGED
@@ -1,8 +1,8 @@
1
- export { apiInputsFromSchemaData, buildRunInputsSchema, gateRunInputs, prepareRunInputs, validateRunInputs } from '../chunk-4DPYGNJ3.js';
1
+ export { apiInputsFromSchemaData, buildRunInputsSchema, gateRunInputs, prepareRunInputs, validateRunInputs } from '../chunk-IBBAJXIO.js';
2
2
  import '../chunk-E6BIXJ6C.js';
3
+ import '../chunk-XO5OENNF.js';
3
4
  import '../chunk-Y2ND6W4W.js';
4
5
  import '../chunk-LBFZXYCY.js';
5
- import '../chunk-XO5OENNF.js';
6
6
  import '../chunk-OD3VYXUY.js';
7
7
  import '../chunk-WYH56SOZ.js';
8
8
  import '../chunk-V3OV2XQT.js';
@@ -0,0 +1,77 @@
1
+ /**
2
+ * What a person reads in place of an identifier: a field's name, and the value
3
+ * of a choice. Headless, so a host that draws its own choice control, a server
4
+ * that writes a summary and the package's own controls all word a value the
5
+ * same way.
6
+ *
7
+ * The descriptor carries an enum's values and nothing else: the standard has no
8
+ * display label for an option, and none is wanted. Its label is derived from
9
+ * the value here, by rule, and only what a person reads changes: the value a
10
+ * form stores, the JSON view, the copy control and the download all keep the
11
+ * code.
12
+ */
13
+ /**
14
+ * `full_name` → `Full name`. Only the first word is capitalised: these are
15
+ * labels, not titles, and Title Case on every word reads as a form from 2009.
16
+ * Takes IDENTIFIERS only - snake_case or kebab-case names, where a separator
17
+ * is structure. An authored `title` never goes through here: it is already
18
+ * human-facing, and its hyphens are spelling (`E-mail address`), not structure.
19
+ */
20
+ declare function humanizeFieldName(name: string): string;
21
+ /**
22
+ * An enum CODE as words: `keynote` → `Keynote`, `unit_price_differs_from_po`
23
+ * → `Unit price differs from po`, `HIGH_RISK` → `High risk`.
24
+ *
25
+ * It is `humanizeFieldName`, applied after an all-caps code of several words is
26
+ * lowercased. The capitals of `HIGH_RISK` are a convention of the code, not an
27
+ * emphasis its author meant, and "HIGH RISK" on a sentence-case page reads as
28
+ * an alarm.
29
+ *
30
+ * A single all-caps token is left exactly as written: `USD`, `EUR`, `OK` and
31
+ * `HIGH` hold no separator, and a lone capitalised word is far more often an
32
+ * acronym, a unit or a currency than a shouted word, so lowercasing it would
33
+ * misspell it ("Usd"). Only a code that is several words joined by `_` or `-`
34
+ * is taken to be capitalised by convention.
35
+ *
36
+ * Acronyms inside a longer code are not guessed: `po` stays `po` where a reader
37
+ * expects `PO`, just as a field name does. That is the price of deriving the
38
+ * label from the value rather than carrying one on the wire, and it is paid
39
+ * knowingly: a method's author who wants `PO` read writes the code so that it
40
+ * reads.
41
+ *
42
+ * Only a code is humanised. A value that is not an identifier is authored
43
+ * words already, and its separators are spelling rather than structure, so it
44
+ * is shown verbatim: `18-24`, `N/A` and `Very satisfied` do not start with a
45
+ * letter or hold something other than letters, digits, `_` and `-`. That is
46
+ * the line `humanizeFieldName` draws between an identifier and an authored
47
+ * title.
48
+ *
49
+ * This words ONE code, with no knowledge of the enum it belongs to. A choice
50
+ * control goes one step further: when two options of one enum would read the
51
+ * same, it shows that enum's codes instead (see `enumValueLabeler`).
52
+ */
53
+ declare function humanizeEnumValue(code: string): string;
54
+ /**
55
+ * How ONE enum's values read, as words: the labeler every choice control and
56
+ * every enum result goes through, so the options a form offers, the value a
57
+ * result shows and a host's own chips read alike. Built from the enum's
58
+ * options, it maps a value to what a person reads.
59
+ *
60
+ * A declared option reads as words (`humanizeEnumValue`), except in two cases,
61
+ * where the code is shown as written:
62
+ *
63
+ * - **Every option, when two of them would read the same.** `high_risk` and
64
+ * `HIGH_RISK`, or `foo-bar` and `foo_bar`, are distinct codes that humanise
65
+ * to one label, and a person offered two identical choices is choosing
66
+ * blind. Wording the others while showing those two as codes would make one
67
+ * enum read in two registers, so the whole enum falls back.
68
+ * - **A value the enum does not declare.** It is the payload disagreeing with
69
+ * its descriptor, and worded it could pass for an option it is not.
70
+ *
71
+ * This is the wording, not the decision to word: a builder-facing surface that
72
+ * must show the code the bundle spells (the control set's `studio`
73
+ * presentation) does not call it.
74
+ */
75
+ declare function enumValueLabeler(options: readonly string[]): (value: string) => string;
76
+
77
+ export { enumValueLabeler, humanizeEnumValue, humanizeFieldName };
@@ -0,0 +1,3 @@
1
+ export { enumValueLabeler, humanizeEnumValue, humanizeFieldName } from '../chunk-GHVVULHY.js';
2
+ //# sourceMappingURL=humanize.js.map
3
+ //# sourceMappingURL=humanize.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":[],"names":[],"mappings":"","file":"humanize.js"}
@@ -1,4 +1,5 @@
1
1
  export { BooleanRunField, ConceptCategory, DateRunField, EnumRunField, FileRunField, ListRunField, NumberRunField, ObjectRunField, ProseRunField, RunField, RunFieldCommon, RunFieldKind, TextConstraints, TextRunField, UnknownRunField, conceptCategory } from './descriptor.js';
2
+ export { enumValueLabeler, humanizeEnumValue, humanizeFieldName } from './humanize.js';
2
3
  export { IOMultiplicity, InputForm, InputFormTopLevelField, OutputForm, PipeIOContract, PipeIOContracts, PipeInputContract, PipeInputFormDescriptor, PipeOutputContract, PipeOutputFormDescriptor } from 'mthds/protocol';
3
4
  export { buildResultField, buildRunFields, getPipeInputForm } from './derive.js';
4
5
  export { getPipeOutputForm } from './output-form.js';
@@ -4,17 +4,18 @@ export { addChosenFiles, chosenFilesAdded, roomForChosenFiles, sourceFileValue }
4
4
  export { collectStuffFiles } from '../chunk-56WECFBD.js';
5
5
  export { describeValidationError, displayValue, valueAtProperty } from '../chunk-RPA7DNSK.js';
6
6
  export { apiInputsFromRunValues, fieldsForContract, inputDataFromWorkingMemory, outputsFromPipeOutput, rjsfDataFromRunValues, runValuesFromInputs, runValuesFromStore, sameRunValues, setValueAtPath, storeInputDataFromRunValues } from '../chunk-ZX52CQJ4.js';
7
+ export { enumValueLabeler, humanizeEnumValue, humanizeFieldName } from '../chunk-GHVVULHY.js';
7
8
  export { narrowFileFormats } from '../chunk-CAKQ5VFT.js';
8
9
  export { NATIVE_CHOICE_CONCEPT_REF, NATIVE_COMPOSITE_CONCEPT_REF, NATIVE_DATE_CONCEPT_REF, NATIVE_HTML_CONCEPT_REF, NATIVE_PAGE_CONCEPT_REF, NATIVE_RATING_CONCEPT_REF, NATIVE_SEARCH_RESULT_CONCEPT_REF, NATIVE_YES_NO_CONCEPT_REF, TYPED_SCALAR_MARKERS, citedSource, formatDateContent, hasTypedScalarMarkers, isNativeCompositeNode, isNativeDateNode, isNativeHtmlNode, isNativePageNode, isNativeSearchResultNode, isViewableUrl, nativeVerdictOf, readChoiceContent, readCompositeContent, readDataUrl, readDateContent, readDocumentContent, readHtmlContent, readImageContent, readPageContent, readRatingContent, readSearchResultContent, readYesNoContent, splitCitations, viewableUrl } from '../chunk-QQK6Y55E.js';
9
10
  export { getPipeOutputForm } from '../chunk-JIGRWJTV.js';
10
11
  export { buildResultField, buildRunFields, getPipeInputForm } from '../chunk-ZB4RYUKV.js';
11
12
  export { conceptCategory } from '../chunk-FABY3DEY.js';
12
13
  export { DOCUMENT_FORMATS, IMAGE_FORMATS, acceptLabel, acceptMap, formatsForKind, isAcceptedFile } from '../chunk-XCO6GTEC.js';
13
- export { apiInputsFromSchemaData, buildRunInputsSchema, gateRunInputs, prepareRunInputs, validateRunInputs } from '../chunk-4DPYGNJ3.js';
14
+ export { apiInputsFromSchemaData, buildRunInputsSchema, gateRunInputs, prepareRunInputs, validateRunInputs } from '../chunk-IBBAJXIO.js';
14
15
  export { deflateAllInputs, deflateInput, healStringWrappers, inflateAllInputs, inflateInput, pruneEmptyOptionals, resolveConceptCode } from '../chunk-E6BIXJ6C.js';
16
+ export { anyOptionalStructureOpen, computeReadiness, fieldFilled, foldsBehindOptionalDisclosure, isFilled, isFoldedOptional, isOptionalStructure, mustBeFilled, optionalStructureOpen, shownAsOptional } from '../chunk-XO5OENNF.js';
15
17
  import '../chunk-Y2ND6W4W.js';
16
18
  export { normalizeSchemaForRjsf, prepareSchemaForRjsf } from '../chunk-LBFZXYCY.js';
17
- export { anyOptionalStructureOpen, computeReadiness, fieldFilled, foldsBehindOptionalDisclosure, isFilled, isFoldedOptional, isOptionalStructure, mustBeFilled, optionalStructureOpen, shownAsOptional } from '../chunk-XO5OENNF.js';
18
19
  export { collapseNullable, collectSchemaDefs, derefSchema, flattenAnyOf, hoistDefsToRoot, resolveSchemaIndirection, schemaTypeOf } from '../chunk-OD3VYXUY.js';
19
20
  export { buildPipeRef, getPipeIOContract, inputMustBeFilled, isFixedCountInput, isOptionalInput, isPluralInput } from '../chunk-WYH56SOZ.js';
20
21
  import '../chunk-V3OV2XQT.js';
@@ -1,10 +1,11 @@
1
1
  "use client";
2
- import { cn, checkedAccentClass, focusOutlineClass, linkTextClass, selectedBorderClass, selectedFillClass, fieldControlClass, ResultRoot, ResultField, FieldRenderer, ToggleGroup, ToggleGroupItem, selectedFillStrongClass, Switch, Select, SelectTrigger, SelectValue, SelectContent, SelectItem } from '../chunk-II5TOORN.js';
2
+ import { cn, headingClass, checkedAccentClass, focusOutlineClass, actionShadowClass, panelSurfaceClass, panelRaisedShadowClass, linkTextClass, selectedBorderClass, selectedFillClass, fieldControlClass, ResultRoot, ResultField, FieldRenderer, enumLabeler, useFieldPresentation, ToggleGroup, ToggleGroupItem, selectedFillStrongClass, Switch, Select, SelectTrigger, SelectValue, SelectContent, SelectItem, panelFlatShadowClass } from '../chunk-JCFALTTY.js';
3
3
  import '../chunk-4VAO6BDE.js';
4
4
  export { seedInputs } from '../chunk-VH5CDQDR.js';
5
5
  import '../chunk-L23R3JNQ.js';
6
6
  import '../chunk-56WECFBD.js';
7
7
  import '../chunk-ZX52CQJ4.js';
8
+ import '../chunk-GHVVULHY.js';
8
9
  import { isNativeValueNode, readDateContent, formatDateContent, isNativeHtmlNode, isNativeDateNode, isNativeCompositeNode } from '../chunk-QQK6Y55E.js';
9
10
  export { brandManifestSchema } from '../chunk-QFX332LE.js';
10
11
  import '../chunk-ZB4RYUKV.js';
@@ -1842,13 +1843,24 @@ function Card({
1842
1843
  props,
1843
1844
  children
1844
1845
  }) {
1845
- return /* @__PURE__ */ jsxs("div", { className: "rounded-lg border border-border bg-card p-6 text-card-foreground", children: [
1846
- props.title || props.description ? /* @__PURE__ */ jsxs("div", { className: "mb-4 space-y-1.5", children: [
1847
- props.title ? /* @__PURE__ */ jsx("h3", { className: "text-lg leading-none font-semibold", children: props.title }) : null,
1848
- props.description ? /* @__PURE__ */ jsx("p", { className: "text-sm text-muted-foreground", children: props.description }) : null
1849
- ] }) : null,
1850
- children
1851
- ] });
1846
+ return (
1847
+ // A style's panel: a host writes the style's field fill onto `--input`
1848
+ // here, as on its own panel, so the fields inside do not sink into it.
1849
+ /* @__PURE__ */ jsxs(
1850
+ "div",
1851
+ {
1852
+ "data-style-panel": "",
1853
+ className: cn("rounded-lg p-6 text-card-foreground", panelSurfaceClass, panelFlatShadowClass),
1854
+ children: [
1855
+ props.title || props.description ? /* @__PURE__ */ jsxs("div", { className: "mb-4 space-y-1.5", children: [
1856
+ props.title ? /* @__PURE__ */ jsx("h3", { className: cn("text-lg leading-none", headingClass(600)), children: props.title }) : null,
1857
+ props.description ? /* @__PURE__ */ jsx("p", { className: "text-sm text-muted-foreground", children: props.description }) : null
1858
+ ] }) : null,
1859
+ children
1860
+ ]
1861
+ }
1862
+ )
1863
+ );
1852
1864
  }
1853
1865
  var GAP = {
1854
1866
  none: "gap-0",
@@ -1935,10 +1947,10 @@ function Collapsible({
1935
1947
  );
1936
1948
  }
1937
1949
  var HEADING = {
1938
- h1: "text-3xl font-bold tracking-tight",
1939
- h2: "text-2xl font-semibold tracking-tight",
1940
- h3: "text-lg font-semibold",
1941
- h4: "text-base font-semibold"
1950
+ h1: cn("text-3xl", headingClass(700, true)),
1951
+ h2: cn("text-2xl", headingClass(600, true)),
1952
+ h3: cn("text-lg", headingClass(600)),
1953
+ h4: cn("text-base", headingClass(600))
1942
1954
  };
1943
1955
  function Heading({
1944
1956
  props
@@ -2115,7 +2127,8 @@ function Textarea({
2115
2127
  /* @__PURE__ */ jsx(FieldError, { message: field.error })
2116
2128
  ] });
2117
2129
  }
2118
- var NATIVE_CHECK = cn("size-4", checkedAccentClass, focusOutlineClass);
2130
+ var NATIVE_CHECK = cn("size-4 shrink-0", checkedAccentClass, focusOutlineClass);
2131
+ var NATIVE_CHECK_ROW = "flex items-center gap-2 text-sm max-sm:min-h-11";
2119
2132
  function Radio({
2120
2133
  props,
2121
2134
  bindings,
@@ -2123,9 +2136,10 @@ function Radio({
2123
2136
  }) {
2124
2137
  const id = useControlId(props.name);
2125
2138
  const field = useBoundField(props.value, bindings?.value, "", props);
2139
+ const labelOf = enumLabeler(props.options ?? [], useFieldPresentation());
2126
2140
  return /* @__PURE__ */ jsxs("fieldset", { className: "space-y-2", "aria-invalid": field.error ? true : void 0, children: [
2127
2141
  /* @__PURE__ */ jsx("legend", { className: LABEL, children: props.label }),
2128
- /* @__PURE__ */ jsx("div", { className: "space-y-2", children: (props.options ?? []).map((option, index) => /* @__PURE__ */ jsxs("label", { className: "flex items-center gap-2 text-sm", children: [
2142
+ /* @__PURE__ */ jsx("div", { className: "space-y-2 max-sm:space-y-0", children: (props.options ?? []).map((option, index) => /* @__PURE__ */ jsxs("label", { className: NATIVE_CHECK_ROW, children: [
2129
2143
  /* @__PURE__ */ jsx(
2130
2144
  "input",
2131
2145
  {
@@ -2141,7 +2155,7 @@ function Radio({
2141
2155
  }
2142
2156
  }
2143
2157
  ),
2144
- /* @__PURE__ */ jsx("span", { children: option })
2158
+ /* @__PURE__ */ jsx("span", { children: labelOf(option) })
2145
2159
  ] }, `${index}-${option}`)) }),
2146
2160
  /* @__PURE__ */ jsx(FieldError, { message: field.error })
2147
2161
  ] });
@@ -2154,7 +2168,7 @@ function Checkbox({
2154
2168
  const id = useControlId(props.name);
2155
2169
  const field = useBoundField(props.checked, bindings?.checked, false, props);
2156
2170
  return /* @__PURE__ */ jsxs("div", { className: "space-y-2", children: [
2157
- /* @__PURE__ */ jsxs("label", { htmlFor: id, className: "flex items-center gap-2 text-sm", children: [
2171
+ /* @__PURE__ */ jsxs("label", { htmlFor: id, className: NATIVE_CHECK_ROW, children: [
2158
2172
  /* @__PURE__ */ jsx(
2159
2173
  "input",
2160
2174
  {
@@ -2322,6 +2336,7 @@ function AccessibleSelect({ props, bindings, emit }) {
2322
2336
  hasValidation ? { checks: props.checks ?? [], validateOn } : void 0
2323
2337
  );
2324
2338
  const id = useControlId(props.name);
2339
+ const labelOf = enumLabeler(props.options ?? [], useFieldPresentation());
2325
2340
  return /* @__PURE__ */ jsxs("div", { className: "space-y-2", children: [
2326
2341
  /* @__PURE__ */ jsx("label", { htmlFor: id, className: "block text-sm leading-none font-medium", children: props.label }),
2327
2342
  /* @__PURE__ */ jsxs(
@@ -2334,8 +2349,8 @@ function AccessibleSelect({ props, bindings, emit }) {
2334
2349
  emit("change");
2335
2350
  },
2336
2351
  children: [
2337
- /* @__PURE__ */ jsx(SelectTrigger, { id, className: "w-full", children: /* @__PURE__ */ jsx(SelectValue, { placeholder: props.placeholder ?? "Select..." }) }),
2338
- /* @__PURE__ */ jsx(SelectContent, { children: (props.options ?? []).map((option, index) => /* @__PURE__ */ jsx(SelectItem, { value: option, children: option }, `${index}-${option}`)) })
2352
+ /* @__PURE__ */ jsx(SelectTrigger, { id, className: "h-11 w-full", children: /* @__PURE__ */ jsx(SelectValue, { placeholder: props.placeholder ?? "Select..." }) }),
2353
+ /* @__PURE__ */ jsx(SelectContent, { children: (props.options ?? []).map((option, index) => /* @__PURE__ */ jsx(SelectItem, { value: option, children: labelOf(option) }, `${index}-${option}`)) })
2339
2354
  ]
2340
2355
  }
2341
2356
  ),
@@ -2428,11 +2443,11 @@ function Tabs({ props, children }) {
2428
2443
  const panels = React3.Children.toArray(children);
2429
2444
  const [value, setValue] = React3.useState(tabs[0]?.value ?? "");
2430
2445
  return /* @__PURE__ */ jsxs(TabsPrimitive.Root, { value, onValueChange: setValue, className: "w-full", children: [
2431
- /* @__PURE__ */ jsx(TabsPrimitive.List, { className: "inline-flex h-10 items-center justify-start rounded-md bg-muted p-1 text-muted-foreground", children: tabs.map((tab) => /* @__PURE__ */ jsx(
2446
+ /* @__PURE__ */ jsx(TabsPrimitive.List, { className: "inline-flex h-10 items-center justify-start rounded-md bg-muted p-1 text-muted-foreground max-sm:h-auto max-sm:flex-wrap", children: tabs.map((tab) => /* @__PURE__ */ jsx(
2432
2447
  TabsPrimitive.Trigger,
2433
2448
  {
2434
2449
  value: tab.value,
2435
- className: "inline-flex items-center justify-center rounded-sm px-3 py-1.5 text-sm font-medium whitespace-nowrap transition-all focus-visible:ring-2 focus-visible:ring-ring focus-visible:outline-hidden data-[state=active]:bg-background data-[state=active]:text-foreground data-[state=active]:shadow-sm",
2450
+ className: "inline-flex items-center justify-center rounded-sm px-3 py-1.5 text-sm font-medium whitespace-nowrap transition-all focus-visible:ring-2 focus-visible:ring-ring focus-visible:outline-hidden data-[state=active]:bg-background data-[state=active]:text-foreground data-[state=active]:shadow-sm max-sm:min-h-11 max-sm:min-w-11",
2436
2451
  children: tab.label
2437
2452
  },
2438
2453
  tab.value
@@ -2448,7 +2463,7 @@ function Tabs({ props, children }) {
2448
2463
  ))
2449
2464
  ] });
2450
2465
  }
2451
- var BUTTON_BASE = "inline-flex h-10 items-center justify-center rounded-md px-4 text-sm font-medium transition-colors focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:outline-hidden disabled:pointer-events-none disabled:opacity-50";
2466
+ var BUTTON_BASE = "inline-flex min-h-11 items-center justify-center rounded-md px-4 text-sm font-medium transition-colors focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:outline-hidden disabled:pointer-events-none disabled:opacity-50";
2452
2467
  var PRIMARY_BUTTON = cn(BUTTON_BASE, "bg-primary text-primary-foreground hover:bg-primary/90");
2453
2468
  var SECONDARY_BUTTON = cn(
2454
2469
  BUTTON_BASE,
@@ -2591,6 +2606,7 @@ function Segmented({ props, bindings, emit }) {
2591
2606
  const value = isBound ? boundValue ?? "" : localValue;
2592
2607
  const setValue = isBound ? setBoundValue : setLocalValue;
2593
2608
  const labelId = useControlId(props.name);
2609
+ const labelOf = enumLabeler(props.options ?? [], useFieldPresentation());
2594
2610
  return /* @__PURE__ */ jsxs("div", { className: "space-y-2", children: [
2595
2611
  /* @__PURE__ */ jsx("span", { id: labelId, className: "block text-sm leading-none font-medium", children: props.label }),
2596
2612
  /* @__PURE__ */ jsx(
@@ -2611,8 +2627,8 @@ function Segmented({ props, bindings, emit }) {
2611
2627
  value: option,
2612
2628
  variant: "outline",
2613
2629
  size: "sm",
2614
- className: "rounded-full px-3.5 data-[state=on]:border-primary data-[state=on]:bg-primary data-[state=on]:text-primary-foreground",
2615
- children: option
2630
+ className: "rounded-full px-3.5 data-[state=on]:border-primary data-[state=on]:bg-primary data-[state=on]:text-primary-foreground max-sm:h-11 max-sm:min-w-11",
2631
+ children: labelOf(option)
2616
2632
  },
2617
2633
  option
2618
2634
  ))
@@ -2651,7 +2667,7 @@ function NumberInput({ props, bindings, emit }) {
2651
2667
  },
2652
2668
  className: cn(
2653
2669
  fieldControlClass,
2654
- "h-10 px-3 tabular-nums [appearance:textfield] [&::-webkit-inner-spin-button]:appearance-none"
2670
+ "h-11 px-3 tabular-nums [appearance:textfield] [&::-webkit-inner-spin-button]:appearance-none"
2655
2671
  )
2656
2672
  }
2657
2673
  ),
@@ -2769,7 +2785,16 @@ function Hero({ props }) {
2769
2785
  children: props.eyebrow
2770
2786
  }
2771
2787
  ) : null,
2772
- /* @__PURE__ */ jsx("h1", { className: "max-w-2xl text-4xl font-bold tracking-tight text-foreground sm:text-[44px] sm:leading-[1.15]", children: props.headline }),
2788
+ /* @__PURE__ */ jsx(
2789
+ "h1",
2790
+ {
2791
+ className: cn(
2792
+ "max-w-2xl text-4xl text-foreground sm:text-[44px] sm:leading-[1.15]",
2793
+ headingClass(700, true)
2794
+ ),
2795
+ children: props.headline
2796
+ }
2797
+ ),
2773
2798
  props.lede ? /* @__PURE__ */ jsx("p", { className: "mt-4 max-w-2xl text-[17px] leading-relaxed text-muted-foreground", children: props.lede }) : null
2774
2799
  ] });
2775
2800
  }
@@ -2807,7 +2832,7 @@ function ResultPanel() {
2807
2832
  const slot = useResultSlot();
2808
2833
  if (!slot?.content) return null;
2809
2834
  return /* @__PURE__ */ jsxs("section", { className: "border-t border-border py-9", "data-testid": "result-panel", "aria-live": "polite", children: [
2810
- /* @__PURE__ */ jsx("h2", { className: "mb-6 text-xl font-semibold tracking-tight text-foreground", children: slot.title ?? "Result" }),
2835
+ /* @__PURE__ */ jsx("h2", { className: cn("mb-6 text-xl text-foreground", headingClass(600, true)), children: slot.title ?? "Result" }),
2811
2836
  slot.content
2812
2837
  ] });
2813
2838
  }
@@ -2816,7 +2841,7 @@ function Section({ props, children }) {
2816
2841
  /* @__PURE__ */ jsxs("div", { className: "mb-6", children: [
2817
2842
  /* @__PURE__ */ jsxs("div", { className: "flex items-baseline gap-3", children: [
2818
2843
  props.number ? /* @__PURE__ */ jsx("span", { className: cn("font-mono text-[12px]", linkTextClass), children: props.number }) : null,
2819
- /* @__PURE__ */ jsx("h2", { className: "text-xl font-semibold tracking-tight text-foreground", children: props.title })
2844
+ /* @__PURE__ */ jsx("h2", { className: cn("text-xl text-foreground", headingClass(600, true)), children: props.title })
2820
2845
  ] }),
2821
2846
  props.lede ? /* @__PURE__ */ jsx("p", { className: "mt-1.5 text-sm text-muted-foreground", children: props.lede }) : null
2822
2847
  ] }),
@@ -2829,10 +2854,21 @@ function Rail({ props, children }) {
2829
2854
  // the `@theme inline` mapping and does not inherit its fallback - it has to
2830
2855
  // carry its own, or a host that defines no tokens loses the declaration
2831
2856
  // outright. See src/styles/tailwind-entry.css.
2832
- /* @__PURE__ */ jsxs("div", { className: "rounded-[calc(var(--radius,0.5rem)*1.5)] border border-border bg-card p-7 text-card-foreground shadow-xl", children: [
2833
- /* @__PURE__ */ jsx("h2", { className: "text-[11px] font-semibold tracking-[0.15em] text-muted-foreground uppercase", children: props.title }),
2834
- /* @__PURE__ */ jsx("div", { className: "mt-4 flex flex-col", children })
2835
- ] })
2857
+ /* @__PURE__ */ jsxs(
2858
+ "div",
2859
+ {
2860
+ "data-style-panel": "",
2861
+ className: cn(
2862
+ "rounded-[calc(var(--radius,0.5rem)*1.5)] p-7 text-card-foreground",
2863
+ panelSurfaceClass,
2864
+ panelRaisedShadowClass
2865
+ ),
2866
+ children: [
2867
+ /* @__PURE__ */ jsx("h2", { className: "text-[11px] font-semibold tracking-[0.15em] text-muted-foreground uppercase", children: props.title }),
2868
+ /* @__PURE__ */ jsx("div", { className: "mt-4 flex flex-col", children })
2869
+ ]
2870
+ }
2871
+ )
2836
2872
  );
2837
2873
  }
2838
2874
  function present(value) {
@@ -2853,10 +2889,12 @@ function Cta({ props, emit }) {
2853
2889
  type: "button",
2854
2890
  onClick: () => emit("press"),
2855
2891
  className: cn(
2856
- "inline-flex h-12 w-full items-center justify-center rounded-lg bg-primary px-6 text-sm font-semibold text-primary-foreground",
2857
- // The fallback is not decoration here either - see Rail above.
2858
- "shadow-[0_0_28px_color-mix(in_oklab,var(--primary,hsl(240_5.9%_10%))_35%,transparent)] transition-all hover:bg-primary/90 hover:shadow-[0_0_44px_color-mix(in_oklab,var(--primary,hsl(240_5.9%_10%))_50%,transparent)]",
2859
- "focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background focus-visible:outline-hidden"
2892
+ "inline-flex h-12 w-full items-center justify-center rounded-lg bg-primary px-6 text-sm font-semibold text-primary-foreground transition-all hover:bg-primary/90",
2893
+ // The page's call-to-action shadow, or the glow in the button colour
2894
+ // it had. Focus is an outline, which no shadow a style sets can
2895
+ // replace or hide.
2896
+ actionShadowClass,
2897
+ focusOutlineClass
2860
2898
  ),
2861
2899
  children: props.label
2862
2900
  }