@0001-labs/design-system-1 0.3.0-alpha.21 → 0.3.0-alpha.23

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (36) hide show
  1. package/DS1/0-face/bento.ts +13 -4
  2. package/DS1/0-face/calendar.ts +23 -0
  3. package/DS1/1-root/bento.css +25 -12
  4. package/DS1/1-root/cjk.css +1 -1
  5. package/DS1/1-root/controls.css +22 -32
  6. package/DS1/1-root/fonts.css +1 -1
  7. package/DS1/1-root/one.css +1 -1
  8. package/DS1/1-root/one.semantic.css +1 -1
  9. package/DS1/2-core/ds-switch.ts +2 -2
  10. package/DS1/2-core/styles/ds-checkbox.css +11 -7
  11. package/DS1/2-core/styles/ds-radio.css +5 -2
  12. package/DS1/2-core/styles/ds-switch.css +7 -23
  13. package/DS1/3-unit/ds-bento.ts +8 -1
  14. package/DS1/3-unit/ds-calendar.ts +21 -4
  15. package/DS1/3-unit/styles/ds-bento.css +16 -10
  16. package/DS1/3-unit/styles/ds-calendar.css +30 -8
  17. package/dist/0-face/bento.d.ts +6 -2
  18. package/dist/0-face/bento.d.ts.map +1 -1
  19. package/dist/0-face/bento.js +12 -4
  20. package/dist/0-face/calendar.d.ts +11 -0
  21. package/dist/0-face/calendar.d.ts.map +1 -1
  22. package/dist/0-face/calendar.js +19 -0
  23. package/dist/2-core/ds-switch.d.ts +2 -2
  24. package/dist/2-core/ds-switch.d.ts.map +1 -1
  25. package/dist/2-core/ds-switch.js +2 -2
  26. package/dist/3-unit/ds-bento.d.ts +12 -0
  27. package/dist/3-unit/ds-bento.d.ts.map +1 -1
  28. package/dist/3-unit/ds-bento.js +4 -1
  29. package/dist/3-unit/ds-calendar.d.ts +17 -0
  30. package/dist/3-unit/ds-calendar.d.ts.map +1 -1
  31. package/dist/3-unit/ds-calendar.js +18 -5
  32. package/dist/design-system-1.bundle.js +66 -15
  33. package/dist/design-system-1.bundle.js.map +1 -1
  34. package/dist/design-system-1.bundle.min.js +903 -872
  35. package/dist/design-system-1.bundle.min.js.map +1 -1
  36. package/package.json +1 -1
@@ -5370,7 +5370,7 @@ define("ds-button", Button);
5370
5370
  var check_default = "<svg width=\"16\" height=\"16\" viewBox=\"0 0 16 16\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n<path d=\"M6.68649 11.884L12.443 6.13601L11.736 5.42715L6.68835 10.4827L4.26399 8.0501L3.55696 8.74525L6.68649 11.884Z\" fill=\"currentColor\"/>\n</svg>\n";
5371
5371
  //#endregion
5372
5372
  //#region DS1/2-core/styles/ds-checkbox.css?inline
5373
- var ds_checkbox_default = "/* Shape is a surface preference. Keep these base lengths unscaled: each\n * component resolves them with its own --ds-sf in component-metrics.css. */\n[data-ds-shape=\"square\"],\n:host([data-ds-shape=\"square\"]) {\n --ds-corner-size: 0px;\n --ds-corner-shape: round;\n --ds-button-inset: 0.5px;\n}\n\n[data-ds-shape=\"rounded\"],\n:host([data-ds-shape=\"rounded\"]) {\n --ds-corner-size: 4px;\n --ds-corner-shape: round;\n --ds-button-inset: 2.5px;\n}\n\n[data-ds-shape=\"circular\"],\n:host([data-ds-shape=\"circular\"]) {\n --ds-corner-size: 999px;\n --ds-corner-shape: round;\n --ds-button-inset: 5px;\n}\n\n/* A squircle needs twice an arc's radius for the same apparent corner.\n * Circular controls keep true semicircles even in a squircle browser. */\n@supports (corner-shape: squircle) {\n [data-ds-shape=\"rounded\"],\n :host([data-ds-shape=\"rounded\"]) {\n --ds-corner-size: 8px;\n --ds-corner-shape: squircle;\n }\n}\n\n/* Resolve dimensions where a component is drawn. Inherited calc() values have\n * already used their ancestor's scale. Base tokens stay unscaled and inherit;\n * resolved tokens can still be overridden directly on a component.\n * data-ds-surface gives ordinary layout elements the same scaled measures.\n */\n:root,\n:host,\n:where([data-ds-surface]) {\n --ds-unit: calc(var(--ds-1, 20px) * var(--ds-sf, 1));\n --ds-control-height: calc(var(--ds-control-size, var(--ds-08, 16px)) * var(--ds-sf, 1));\n --ds-row-height: calc(var(--ds-row-size, var(--ds-1, 20px)) * var(--ds-sf, 1));\n --ds-type-size-default: calc(var(--ds-text-size, 14px) * var(--ds-sf, 1));\n --ds-type-size-small: calc(var(--ds-small-text-size, 10px) * var(--ds-sf, 1));\n --ds-type-size-heading: calc(var(--ds-heading-text-size, 13px) * var(--ds-sf, 1));\n --ds-type-size-display: calc(var(--ds-display-text-size, 20px) * var(--ds-sf, 1));\n --ds-type-lineheight-default: calc(var(--ds-text-leading, 16px) * var(--ds-sf, 1));\n --ds-type-letterspacing-default: calc(var(--ds-text-tracking, -0.3px) * var(--ds-sf, 1));\n --ds-radius: calc(var(--ds-corner-size, 4px) * var(--ds-sf, 1));\n --ds-radius-card: calc(var(--ds-card-corner-size, 4px) * var(--ds-sf, 1));\n}\n\n:host {\n --ds-choice-unit: calc(var(--ds-1) * var(--ds-sf));\n display: inline-flex;\n flex: 0 0 auto;\n vertical-align: middle;\n width: var(--ds-choice-unit);\n height: var(--ds-choice-unit);\n}\n:host([hidden]) { display: none !important; }\n::slotted(input[type=\"checkbox\"]) {\n appearance: none !important;\n box-sizing: border-box !important;\n display: grid !important;\n place-items: center !important;\n width: 100% !important;\n min-width: 0 !important;\n height: 100% !important;\n min-height: 0 !important;\n margin: 0 !important;\n padding: 0 !important;\n border: 1px solid var(--ds-border-color) !important;\n border-radius: var(--ds-radius) !important;\n corner-shape: var(--ds-corner-shape, round) !important;\n background: var(--ds-input-background) !important;\n color: var(--ds-button-text-color-on-accent) !important;\n box-shadow: none !important;\n cursor: pointer !important;\n}\n::slotted(input:checked), ::slotted(input:indeterminate) { background: var(--ds-accent-color) !important; }\n::slotted(input)::before {\n content: \"\";\n width: calc(.8 * var(--ds-choice-unit));\n height: calc(.8 * var(--ds-choice-unit));\n background: currentColor;\n mask: var(--ds-checkbox-mark) center / contain no-repeat;\n opacity: 0;\n}\n::slotted(input:checked)::before { opacity: 1; }\n::slotted(input:indeterminate)::before {\n width: calc(var(--ds-choice-unit) / 2);\n height: calc(2px * var(--ds-sf));\n mask: none;\n opacity: 1;\n}\n::slotted(input:focus-visible) { outline: 2px solid var(--ds-focus-ring) !important; outline-offset: 1px !important; }\n::slotted(input:disabled) { cursor: default !important; opacity: .5 !important; }\n";
5373
+ var ds_checkbox_default = "/* Shape is a surface preference. Keep these base lengths unscaled: each\n * component resolves them with its own --ds-sf in component-metrics.css. */\n[data-ds-shape=\"square\"],\n:host([data-ds-shape=\"square\"]) {\n --ds-corner-size: 0px;\n --ds-corner-shape: round;\n --ds-button-inset: 0.5px;\n}\n\n[data-ds-shape=\"rounded\"],\n:host([data-ds-shape=\"rounded\"]) {\n --ds-corner-size: 4px;\n --ds-corner-shape: round;\n --ds-button-inset: 2.5px;\n}\n\n[data-ds-shape=\"circular\"],\n:host([data-ds-shape=\"circular\"]) {\n --ds-corner-size: 999px;\n --ds-corner-shape: round;\n --ds-button-inset: 5px;\n}\n\n/* A squircle needs twice an arc's radius for the same apparent corner.\n * Circular controls keep true semicircles even in a squircle browser. */\n@supports (corner-shape: squircle) {\n [data-ds-shape=\"rounded\"],\n :host([data-ds-shape=\"rounded\"]) {\n --ds-corner-size: 8px;\n --ds-corner-shape: squircle;\n }\n}\n\n/* Resolve dimensions where a component is drawn. Inherited calc() values have\n * already used their ancestor's scale. Base tokens stay unscaled and inherit;\n * resolved tokens can still be overridden directly on a component.\n * data-ds-surface gives ordinary layout elements the same scaled measures.\n */\n:root,\n:host,\n:where([data-ds-surface]) {\n --ds-unit: calc(var(--ds-1, 20px) * var(--ds-sf, 1));\n --ds-control-height: calc(var(--ds-control-size, var(--ds-08, 16px)) * var(--ds-sf, 1));\n --ds-row-height: calc(var(--ds-row-size, var(--ds-1, 20px)) * var(--ds-sf, 1));\n --ds-type-size-default: calc(var(--ds-text-size, 14px) * var(--ds-sf, 1));\n --ds-type-size-small: calc(var(--ds-small-text-size, 10px) * var(--ds-sf, 1));\n --ds-type-size-heading: calc(var(--ds-heading-text-size, 13px) * var(--ds-sf, 1));\n --ds-type-size-display: calc(var(--ds-display-text-size, 20px) * var(--ds-sf, 1));\n --ds-type-lineheight-default: calc(var(--ds-text-leading, 16px) * var(--ds-sf, 1));\n --ds-type-letterspacing-default: calc(var(--ds-text-tracking, -0.3px) * var(--ds-sf, 1));\n --ds-radius: calc(var(--ds-corner-size, 4px) * var(--ds-sf, 1));\n --ds-radius-card: calc(var(--ds-card-corner-size, 4px) * var(--ds-sf, 1));\n}\n\n/* One square, the box one control (16px) square on its lower sixteen at its start, as an icon\n stands, so the words begin on the next square (Joachim, 19 October 2026). */\n:host {\n --ds-choice-unit: calc(var(--ds-1) * var(--ds-sf));\n display: inline-grid;\n align-items: end;\n justify-items: start;\n flex: 0 0 auto;\n vertical-align: top;\n width: var(--ds-choice-unit);\n height: var(--ds-choice-unit);\n}\n:host([hidden]) { display: none !important; }\n::slotted(input[type=\"checkbox\"]) {\n appearance: none !important;\n box-sizing: border-box !important;\n display: grid !important;\n place-items: center !important;\n width: var(--ds-control-height) !important;\n min-width: 0 !important;\n height: var(--ds-control-height) !important;\n min-height: 0 !important;\n margin: 0 !important;\n padding: 0 !important;\n border: 1px solid var(--ds-border-color) !important;\n border-radius: var(--ds-radius) !important;\n corner-shape: var(--ds-corner-shape, round) !important;\n background: var(--ds-input-background) !important;\n color: var(--ds-button-text-color-on-accent) !important;\n box-shadow: none !important;\n cursor: pointer !important;\n}\n::slotted(input:checked), ::slotted(input:indeterminate) { background: var(--ds-accent-color) !important; }\n::slotted(input)::before {\n content: \"\";\n width: var(--ds-control-height);\n height: var(--ds-control-height);\n background: currentColor;\n mask: var(--ds-checkbox-mark) center / contain no-repeat;\n opacity: 0;\n}\n::slotted(input:checked)::before { opacity: 1; }\n::slotted(input:indeterminate)::before {\n width: calc(var(--ds-control-height) / 2);\n height: calc(2px * var(--ds-sf));\n mask: none;\n opacity: 1;\n}\n::slotted(input:focus-visible) { outline: 2px solid var(--ds-focus-ring) !important; outline-offset: 1px !important; }\n::slotted(input:disabled) { cursor: default !important; opacity: .5 !important; }\n";
5374
5374
  //#endregion
5375
5375
  //#region DS1/2-core/ds-checkbox.ts
5376
5376
  var _Checkbox;
@@ -5388,7 +5388,7 @@ _Checkbox.styles = [r$3(ds_checkbox_default), r$3(`:host { --ds-checkbox-mark: u
5388
5388
  define("ds-checkbox", Checkbox);
5389
5389
  //#endregion
5390
5390
  //#region DS1/2-core/styles/ds-radio.css?inline
5391
- var ds_radio_default = "/* Shape is a surface preference. Keep these base lengths unscaled: each\n * component resolves them with its own --ds-sf in component-metrics.css. */\n[data-ds-shape=\"square\"],\n:host([data-ds-shape=\"square\"]) {\n --ds-corner-size: 0px;\n --ds-corner-shape: round;\n --ds-button-inset: 0.5px;\n}\n\n[data-ds-shape=\"rounded\"],\n:host([data-ds-shape=\"rounded\"]) {\n --ds-corner-size: 4px;\n --ds-corner-shape: round;\n --ds-button-inset: 2.5px;\n}\n\n[data-ds-shape=\"circular\"],\n:host([data-ds-shape=\"circular\"]) {\n --ds-corner-size: 999px;\n --ds-corner-shape: round;\n --ds-button-inset: 5px;\n}\n\n/* A squircle needs twice an arc's radius for the same apparent corner.\n * Circular controls keep true semicircles even in a squircle browser. */\n@supports (corner-shape: squircle) {\n [data-ds-shape=\"rounded\"],\n :host([data-ds-shape=\"rounded\"]) {\n --ds-corner-size: 8px;\n --ds-corner-shape: squircle;\n }\n}\n\n/* Resolve dimensions where a component is drawn. Inherited calc() values have\n * already used their ancestor's scale. Base tokens stay unscaled and inherit;\n * resolved tokens can still be overridden directly on a component.\n * data-ds-surface gives ordinary layout elements the same scaled measures.\n */\n:root,\n:host,\n:where([data-ds-surface]) {\n --ds-unit: calc(var(--ds-1, 20px) * var(--ds-sf, 1));\n --ds-control-height: calc(var(--ds-control-size, var(--ds-08, 16px)) * var(--ds-sf, 1));\n --ds-row-height: calc(var(--ds-row-size, var(--ds-1, 20px)) * var(--ds-sf, 1));\n --ds-type-size-default: calc(var(--ds-text-size, 14px) * var(--ds-sf, 1));\n --ds-type-size-small: calc(var(--ds-small-text-size, 10px) * var(--ds-sf, 1));\n --ds-type-size-heading: calc(var(--ds-heading-text-size, 13px) * var(--ds-sf, 1));\n --ds-type-size-display: calc(var(--ds-display-text-size, 20px) * var(--ds-sf, 1));\n --ds-type-lineheight-default: calc(var(--ds-text-leading, 16px) * var(--ds-sf, 1));\n --ds-type-letterspacing-default: calc(var(--ds-text-tracking, -0.3px) * var(--ds-sf, 1));\n --ds-radius: calc(var(--ds-corner-size, 4px) * var(--ds-sf, 1));\n --ds-radius-card: calc(var(--ds-card-corner-size, 4px) * var(--ds-sf, 1));\n}\n\n:host {\n display: inline-flex;\n position: relative;\n flex: 0 0 auto;\n vertical-align: middle;\n width: var(--ds-unit);\n height: var(--ds-unit);\n}\n:host([hidden]) { display: none !important; }\n::slotted(input[type=\"radio\"]) {\n appearance: none !important;\n box-sizing: border-box !important;\n display: grid !important;\n place-items: center !important;\n width: 100% !important;\n min-width: 0 !important;\n height: 100% !important;\n min-height: 0 !important;\n margin: 0 !important;\n padding: 0 !important;\n border: 1px solid var(--ds-border-color) !important;\n border-radius: 50% !important;\n background: var(--ds-input-background) !important;\n color: var(--ds-text-color) !important;\n box-shadow: none !important;\n cursor: pointer !important;\n}\n::slotted(input[hidden]) { display: none !important; }\n::slotted(input)::before {\n content: \"\";\n width: calc(var(--ds-unit) / 2);\n height: calc(var(--ds-unit) / 2);\n border-radius: 50%;\n background: currentColor;\n opacity: 0;\n}\n::slotted(input:checked)::before { opacity: 1; }\n::slotted(input:focus-visible) { outline: 2px solid var(--ds-focus-ring) !important; outline-offset: 1px !important; }\n::slotted(input:disabled) { cursor: default !important; opacity: .5 !important; }\n\n:host([choice]) { width: calc(4 * var(--ds-unit)); }\n:host([choice][compact]) { width: var(--ds-unit); }\n:host([choice][preview]) { height: calc(3 * var(--ds-unit)); }\n:host([choice]) ::slotted(input) {\n position: absolute !important;\n inset: 0 !important;\n opacity: 1 !important;\n border-radius: var(--ds-radius) !important;\n background: transparent !important;\n z-index: 1;\n}\n:host([choice]) ::slotted(input)::before { display: none; }\n:host([choice]) ::slotted(input:checked) { border-color: var(--ds-text-color) !important; }\n:host([choice]) ::slotted(input:disabled) { background: color-mix(in srgb, var(--ds-paper) 60%, transparent) !important; }\n.face {\n display: grid;\n grid-template-rows: minmax(0, 1fr);\n box-sizing: border-box;\n width: 100%;\n height: 100%;\n overflow: hidden;\n border: 1px solid transparent;\n border-radius: var(--ds-radius);\n background: var(--ds-input-background);\n color: var(--ds-text-color);\n pointer-events: none;\n}\n:host([preview]) .face { grid-template-rows: minmax(0, 1fr) calc(var(--ds-unit) - 1px); }\n.preview { display: grid; min-height: 0; overflow: hidden; }\n::slotted([slot=\"preview\"]) { display: block; width: 100%; height: 100%; min-width: 0; min-height: 0; }\n.label {\n align-self: center;\n overflow: hidden;\n padding-inline: calc(4px * var(--ds-sf));\n font: 400 var(--ds-type-size-default) / var(--ds-type-lineheight-default) var(--ds-typeface-regular);\n letter-spacing: var(--ds-type-letterspacing-default);\n white-space: nowrap;\n text-align: center;\n text-overflow: ellipsis;\n}\n:host([compact]) .label { padding-inline: 0; }\n";
5391
+ var ds_radio_default = "/* Shape is a surface preference. Keep these base lengths unscaled: each\n * component resolves them with its own --ds-sf in component-metrics.css. */\n[data-ds-shape=\"square\"],\n:host([data-ds-shape=\"square\"]) {\n --ds-corner-size: 0px;\n --ds-corner-shape: round;\n --ds-button-inset: 0.5px;\n}\n\n[data-ds-shape=\"rounded\"],\n:host([data-ds-shape=\"rounded\"]) {\n --ds-corner-size: 4px;\n --ds-corner-shape: round;\n --ds-button-inset: 2.5px;\n}\n\n[data-ds-shape=\"circular\"],\n:host([data-ds-shape=\"circular\"]) {\n --ds-corner-size: 999px;\n --ds-corner-shape: round;\n --ds-button-inset: 5px;\n}\n\n/* A squircle needs twice an arc's radius for the same apparent corner.\n * Circular controls keep true semicircles even in a squircle browser. */\n@supports (corner-shape: squircle) {\n [data-ds-shape=\"rounded\"],\n :host([data-ds-shape=\"rounded\"]) {\n --ds-corner-size: 8px;\n --ds-corner-shape: squircle;\n }\n}\n\n/* Resolve dimensions where a component is drawn. Inherited calc() values have\n * already used their ancestor's scale. Base tokens stay unscaled and inherit;\n * resolved tokens can still be overridden directly on a component.\n * data-ds-surface gives ordinary layout elements the same scaled measures.\n */\n:root,\n:host,\n:where([data-ds-surface]) {\n --ds-unit: calc(var(--ds-1, 20px) * var(--ds-sf, 1));\n --ds-control-height: calc(var(--ds-control-size, var(--ds-08, 16px)) * var(--ds-sf, 1));\n --ds-row-height: calc(var(--ds-row-size, var(--ds-1, 20px)) * var(--ds-sf, 1));\n --ds-type-size-default: calc(var(--ds-text-size, 14px) * var(--ds-sf, 1));\n --ds-type-size-small: calc(var(--ds-small-text-size, 10px) * var(--ds-sf, 1));\n --ds-type-size-heading: calc(var(--ds-heading-text-size, 13px) * var(--ds-sf, 1));\n --ds-type-size-display: calc(var(--ds-display-text-size, 20px) * var(--ds-sf, 1));\n --ds-type-lineheight-default: calc(var(--ds-text-leading, 16px) * var(--ds-sf, 1));\n --ds-type-letterspacing-default: calc(var(--ds-text-tracking, -0.3px) * var(--ds-sf, 1));\n --ds-radius: calc(var(--ds-corner-size, 4px) * var(--ds-sf, 1));\n --ds-radius-card: calc(var(--ds-card-corner-size, 4px) * var(--ds-sf, 1));\n}\n\n:host {\n display: inline-flex;\n position: relative;\n flex: 0 0 auto;\n vertical-align: middle;\n width: var(--ds-unit);\n height: var(--ds-unit);\n}\n:host([hidden]) { display: none !important; }\n/* A plain radio as the checkbox: a 16px circle on its square's lower sixteen, at its start. */\n:host(:not([choice])) { display: inline-grid; align-items: end; justify-items: start; vertical-align: top; }\n:host(:not([choice])) ::slotted(input[type=\"radio\"]) { width: var(--ds-control-height) !important; height: var(--ds-control-height) !important; }\n::slotted(input[type=\"radio\"]) {\n appearance: none !important;\n box-sizing: border-box !important;\n display: grid !important;\n place-items: center !important;\n width: 100% !important;\n min-width: 0 !important;\n height: 100% !important;\n min-height: 0 !important;\n margin: 0 !important;\n padding: 0 !important;\n border: 1px solid var(--ds-border-color) !important;\n border-radius: 50% !important;\n background: var(--ds-input-background) !important;\n color: var(--ds-text-color) !important;\n box-shadow: none !important;\n cursor: pointer !important;\n}\n::slotted(input[hidden]) { display: none !important; }\n::slotted(input)::before {\n content: \"\";\n width: calc(var(--ds-control-height) / 2);\n height: calc(var(--ds-control-height) / 2);\n border-radius: 50%;\n background: currentColor;\n opacity: 0;\n}\n::slotted(input:checked)::before { opacity: 1; }\n::slotted(input:focus-visible) { outline: 2px solid var(--ds-focus-ring) !important; outline-offset: 1px !important; }\n::slotted(input:disabled) { cursor: default !important; opacity: .5 !important; }\n\n:host([choice]) { width: calc(4 * var(--ds-unit)); }\n:host([choice][compact]) { width: var(--ds-unit); }\n:host([choice][preview]) { height: calc(3 * var(--ds-unit)); }\n:host([choice]) ::slotted(input) {\n position: absolute !important;\n inset: 0 !important;\n opacity: 1 !important;\n border-radius: var(--ds-radius) !important;\n background: transparent !important;\n z-index: 1;\n}\n:host([choice]) ::slotted(input)::before { display: none; }\n:host([choice]) ::slotted(input:checked) { border-color: var(--ds-text-color) !important; }\n:host([choice]) ::slotted(input:disabled) { background: color-mix(in srgb, var(--ds-paper) 60%, transparent) !important; }\n.face {\n display: grid;\n grid-template-rows: minmax(0, 1fr);\n box-sizing: border-box;\n width: 100%;\n height: 100%;\n overflow: hidden;\n border: 1px solid transparent;\n border-radius: var(--ds-radius);\n background: var(--ds-input-background);\n color: var(--ds-text-color);\n pointer-events: none;\n}\n:host([preview]) .face { grid-template-rows: minmax(0, 1fr) calc(var(--ds-unit) - 1px); }\n.preview { display: grid; min-height: 0; overflow: hidden; }\n::slotted([slot=\"preview\"]) { display: block; width: 100%; height: 100%; min-width: 0; min-height: 0; }\n.label {\n align-self: center;\n overflow: hidden;\n padding-inline: calc(4px * var(--ds-sf));\n font: 400 var(--ds-type-size-default) / var(--ds-type-lineheight-default) var(--ds-typeface-regular);\n letter-spacing: var(--ds-type-letterspacing-default);\n white-space: nowrap;\n text-align: center;\n text-overflow: ellipsis;\n}\n:host([compact]) .label { padding-inline: 0; }\n";
5392
5392
  //#endregion
5393
5393
  //#region DS1/2-core/ds-radio.ts
5394
5394
  var _Radio;
@@ -5428,12 +5428,12 @@ _Radio.styles = r$3(ds_radio_default);
5428
5428
  define("ds-radio", Radio);
5429
5429
  //#endregion
5430
5430
  //#region DS1/2-core/styles/ds-switch.css?inline
5431
- var ds_switch_default = "/* Shape is a surface preference. Keep these base lengths unscaled: each\n * component resolves them with its own --ds-sf in component-metrics.css. */\n[data-ds-shape=\"square\"],\n:host([data-ds-shape=\"square\"]) {\n --ds-corner-size: 0px;\n --ds-corner-shape: round;\n --ds-button-inset: 0.5px;\n}\n\n[data-ds-shape=\"rounded\"],\n:host([data-ds-shape=\"rounded\"]) {\n --ds-corner-size: 4px;\n --ds-corner-shape: round;\n --ds-button-inset: 2.5px;\n}\n\n[data-ds-shape=\"circular\"],\n:host([data-ds-shape=\"circular\"]) {\n --ds-corner-size: 999px;\n --ds-corner-shape: round;\n --ds-button-inset: 5px;\n}\n\n/* A squircle needs twice an arc's radius for the same apparent corner.\n * Circular controls keep true semicircles even in a squircle browser. */\n@supports (corner-shape: squircle) {\n [data-ds-shape=\"rounded\"],\n :host([data-ds-shape=\"rounded\"]) {\n --ds-corner-size: 8px;\n --ds-corner-shape: squircle;\n }\n}\n\n/* Resolve dimensions where a component is drawn. Inherited calc() values have\n * already used their ancestor's scale. Base tokens stay unscaled and inherit;\n * resolved tokens can still be overridden directly on a component.\n * data-ds-surface gives ordinary layout elements the same scaled measures.\n */\n:root,\n:host,\n:where([data-ds-surface]) {\n --ds-unit: calc(var(--ds-1, 20px) * var(--ds-sf, 1));\n --ds-control-height: calc(var(--ds-control-size, var(--ds-08, 16px)) * var(--ds-sf, 1));\n --ds-row-height: calc(var(--ds-row-size, var(--ds-1, 20px)) * var(--ds-sf, 1));\n --ds-type-size-default: calc(var(--ds-text-size, 14px) * var(--ds-sf, 1));\n --ds-type-size-small: calc(var(--ds-small-text-size, 10px) * var(--ds-sf, 1));\n --ds-type-size-heading: calc(var(--ds-heading-text-size, 13px) * var(--ds-sf, 1));\n --ds-type-size-display: calc(var(--ds-display-text-size, 20px) * var(--ds-sf, 1));\n --ds-type-lineheight-default: calc(var(--ds-text-leading, 16px) * var(--ds-sf, 1));\n --ds-type-letterspacing-default: calc(var(--ds-text-tracking, -0.3px) * var(--ds-sf, 1));\n --ds-radius: calc(var(--ds-corner-size, 4px) * var(--ds-sf, 1));\n --ds-radius-card: calc(var(--ds-card-corner-size, 4px) * var(--ds-sf, 1));\n}\n\n:host {\n --ds-choice-unit: var(--ds-control-height);\n display: inline-flex;\n flex: 0 0 auto;\n vertical-align: middle;\n width: calc(2 * var(--ds-choice-unit));\n height: var(--ds-choice-unit);\n}\n:host([hidden]) { display: none !important; }\n::slotted(button) {\n appearance: none !important;\n box-sizing: border-box !important;\n position: relative !important;\n display: block !important;\n width: 100% !important;\n min-width: 0 !important;\n height: 100% !important;\n min-height: 0 !important;\n padding: calc(2px * var(--ds-sf)) !important;\n margin: 0 !important;\n border: 0 !important;\n border-radius: var(--ds-radius) !important;\n corner-shape: var(--ds-corner-shape, round) !important;\n background: var(--ds-fill) !important;\n color: var(--ds-text-color-muted) !important;\n box-shadow: none !important;\n cursor: pointer !important;\n touch-action: manipulation;\n}\n::slotted(button)::after {\n content: \"\";\n display: block;\n width: calc(var(--ds-choice-unit) - 4px * var(--ds-sf));\n height: 100%;\n border-radius: var(--ds-radius);\n corner-shape: var(--ds-corner-shape, round);\n background: currentColor;\n transform: translateX(0);\n transition: transform 140ms ease;\n}\n::slotted(button[aria-checked=\"true\"]) {\n background: var(--ds-accent-color) !important;\n color: var(--ds-button-text-color-on-accent) !important;\n}\n::slotted(button[aria-checked=\"true\"])::after { transform: translateX(var(--ds-choice-unit)); }\n::slotted(button:focus-visible) { outline: 2px solid var(--ds-focus-ring) !important; outline-offset: 1px !important; }\n::slotted(button:disabled) { cursor: default !important; opacity: .5 !important; }\n@media (prefers-reduced-motion: reduce) { ::slotted(button)::after { transition: none; } }\n\n/* Rounded switches keep their shape and white thumb independently of page accents. */\n:host([rounded]) ::slotted(button) {\n border-radius: var(--ds-choice-unit) !important;\n corner-shape: round !important;\n color: var(--ds-white) !important;\n}\n:host([rounded]) ::slotted(button)::after {\n border-radius: 50%;\n corner-shape: round;\n background: var(--ds-white);\n}\n:host([rounded]) ::slotted(button[aria-checked=\"true\"]) {\n background: var(--ds-switch-track-on) !important;\n}\n";
5431
+ var ds_switch_default = "/* Shape is a surface preference. Keep these base lengths unscaled: each\n * component resolves them with its own --ds-sf in component-metrics.css. */\n[data-ds-shape=\"square\"],\n:host([data-ds-shape=\"square\"]) {\n --ds-corner-size: 0px;\n --ds-corner-shape: round;\n --ds-button-inset: 0.5px;\n}\n\n[data-ds-shape=\"rounded\"],\n:host([data-ds-shape=\"rounded\"]) {\n --ds-corner-size: 4px;\n --ds-corner-shape: round;\n --ds-button-inset: 2.5px;\n}\n\n[data-ds-shape=\"circular\"],\n:host([data-ds-shape=\"circular\"]) {\n --ds-corner-size: 999px;\n --ds-corner-shape: round;\n --ds-button-inset: 5px;\n}\n\n/* A squircle needs twice an arc's radius for the same apparent corner.\n * Circular controls keep true semicircles even in a squircle browser. */\n@supports (corner-shape: squircle) {\n [data-ds-shape=\"rounded\"],\n :host([data-ds-shape=\"rounded\"]) {\n --ds-corner-size: 8px;\n --ds-corner-shape: squircle;\n }\n}\n\n/* Resolve dimensions where a component is drawn. Inherited calc() values have\n * already used their ancestor's scale. Base tokens stay unscaled and inherit;\n * resolved tokens can still be overridden directly on a component.\n * data-ds-surface gives ordinary layout elements the same scaled measures.\n */\n:root,\n:host,\n:where([data-ds-surface]) {\n --ds-unit: calc(var(--ds-1, 20px) * var(--ds-sf, 1));\n --ds-control-height: calc(var(--ds-control-size, var(--ds-08, 16px)) * var(--ds-sf, 1));\n --ds-row-height: calc(var(--ds-row-size, var(--ds-1, 20px)) * var(--ds-sf, 1));\n --ds-type-size-default: calc(var(--ds-text-size, 14px) * var(--ds-sf, 1));\n --ds-type-size-small: calc(var(--ds-small-text-size, 10px) * var(--ds-sf, 1));\n --ds-type-size-heading: calc(var(--ds-heading-text-size, 13px) * var(--ds-sf, 1));\n --ds-type-size-display: calc(var(--ds-display-text-size, 20px) * var(--ds-sf, 1));\n --ds-type-lineheight-default: calc(var(--ds-text-leading, 16px) * var(--ds-sf, 1));\n --ds-type-letterspacing-default: calc(var(--ds-text-tracking, -0.3px) * var(--ds-sf, 1));\n --ds-radius: calc(var(--ds-corner-size, 4px) * var(--ds-sf, 1));\n --ds-radius-card: calc(var(--ds-card-corner-size, 4px) * var(--ds-sf, 1));\n}\n\n:host {\n --ds-choice-unit: var(--ds-control-height);\n display: inline-flex;\n flex: 0 0 auto;\n vertical-align: middle;\n width: calc(2 * var(--ds-choice-unit));\n height: var(--ds-choice-unit);\n}\n:host([hidden]) { display: none !important; }\n::slotted(button) {\n appearance: none !important;\n box-sizing: border-box !important;\n position: relative !important;\n display: block !important;\n width: 100% !important;\n min-width: 0 !important;\n height: 100% !important;\n min-height: 0 !important;\n padding: calc(2px * var(--ds-sf)) !important;\n margin: 0 !important;\n border: 0 !important;\n border-radius: var(--ds-choice-unit) !important;\n corner-shape: round !important;\n background: var(--ds-fill) !important;\n color: var(--ds-white) !important;\n box-shadow: none !important;\n cursor: pointer !important;\n touch-action: manipulation;\n}\n::slotted(button)::after {\n content: \"\";\n display: block;\n width: calc(var(--ds-choice-unit) - 4px * var(--ds-sf));\n height: 100%;\n border-radius: 50%;\n corner-shape: round;\n background: var(--ds-white);\n transform: translateX(0);\n transition: transform 140ms ease;\n}\n::slotted(button[aria-checked=\"true\"]) {\n background: var(--ds-switch-track-on) !important;\n}\n::slotted(button[aria-checked=\"true\"])::after { transform: translateX(var(--ds-choice-unit)); }\n::slotted(button:focus-visible) { outline: 2px solid var(--ds-focus-ring) !important; outline-offset: 1px !important; }\n::slotted(button:disabled) { cursor: default !important; opacity: .5 !important; }\n@media (prefers-reduced-motion: reduce) { ::slotted(button)::after { transition: none; } }\n";
5432
5432
  //#endregion
5433
5433
  //#region DS1/2-core/ds-switch.ts
5434
5434
  var _Switch;
5435
- /** The shared switch face. The slotted button retains native activation and refs. */
5436
- /** rounded selects a pill track, white circular thumb and darker-green on state. */
5435
+ /** The switch: a pill with a white round thumb, grey when off and the darker green when on,
5436
+ whatever the page's accent. The slotted button retains native activation and refs. */
5437
5437
  var Switch = class extends i$2 {
5438
5438
  focus(options) {
5439
5439
  this.querySelector(":scope > button")?.focus(options);
@@ -8828,7 +8828,7 @@ function openApp(options, wait = 1500) {
8828
8828
  }
8829
8829
  //#endregion
8830
8830
  //#region DS1/1-root/controls.css?inline
8831
- var controls_default = "/* Shape is a surface preference. Keep these base lengths unscaled: each\n * component resolves them with its own --ds-sf in component-metrics.css. */\n[data-ds-shape=\"square\"],\n:host([data-ds-shape=\"square\"]) {\n --ds-corner-size: 0px;\n --ds-corner-shape: round;\n --ds-button-inset: 0.5px;\n}\n\n[data-ds-shape=\"rounded\"],\n:host([data-ds-shape=\"rounded\"]) {\n --ds-corner-size: 4px;\n --ds-corner-shape: round;\n --ds-button-inset: 2.5px;\n}\n\n[data-ds-shape=\"circular\"],\n:host([data-ds-shape=\"circular\"]) {\n --ds-corner-size: 999px;\n --ds-corner-shape: round;\n --ds-button-inset: 5px;\n}\n\n/* A squircle needs twice an arc's radius for the same apparent corner.\n * Circular controls keep true semicircles even in a squircle browser. */\n@supports (corner-shape: squircle) {\n [data-ds-shape=\"rounded\"],\n :host([data-ds-shape=\"rounded\"]) {\n --ds-corner-size: 8px;\n --ds-corner-shape: squircle;\n }\n}\n\n/* Resolve dimensions where a component is drawn. Inherited calc() values have\n * already used their ancestor's scale. Base tokens stay unscaled and inherit;\n * resolved tokens can still be overridden directly on a component.\n * data-ds-surface gives ordinary layout elements the same scaled measures.\n */\n:root,\n:host,\n:where([data-ds-surface]) {\n --ds-unit: calc(var(--ds-1, 20px) * var(--ds-sf, 1));\n --ds-control-height: calc(var(--ds-control-size, var(--ds-08, 16px)) * var(--ds-sf, 1));\n --ds-row-height: calc(var(--ds-row-size, var(--ds-1, 20px)) * var(--ds-sf, 1));\n --ds-type-size-default: calc(var(--ds-text-size, 14px) * var(--ds-sf, 1));\n --ds-type-size-small: calc(var(--ds-small-text-size, 10px) * var(--ds-sf, 1));\n --ds-type-size-heading: calc(var(--ds-heading-text-size, 13px) * var(--ds-sf, 1));\n --ds-type-size-display: calc(var(--ds-display-text-size, 20px) * var(--ds-sf, 1));\n --ds-type-lineheight-default: calc(var(--ds-text-leading, 16px) * var(--ds-sf, 1));\n --ds-type-letterspacing-default: calc(var(--ds-text-tracking, -0.3px) * var(--ds-sf, 1));\n --ds-radius: calc(var(--ds-corner-size, 4px) * var(--ds-sf, 1));\n --ds-radius-card: calc(var(--ds-card-corner-size, 4px) * var(--ds-sf, 1));\n}\n/*\n * A table: words straight on the paper, one square a row. No box and no\n * column lines: each row stands on a hairline at its foot, its words set on\n * that line like a caption: the sixteen of words against the 1px line, three\n * spare above, a 20px pitch, as Ezo sets every row.\n * Column headers keep the text's weight in the title grey; the first column\n * of a body row is a row header in the text colour. Nothing is filled with\n * the accent except a cell someone has selected.\n *\n * `.ds-table` dresses a native <table>; `<ds-table>` draws the same table\n * from data. Put a wide table in `.ds-table-scroll` to scroll it sideways,\n * and give the table `data-sticky` to keep its first column in place.\n *\n * <th data-numeric>, <td data-numeric> numbers, set to the column's end\n * <tfoot> totals, under a line of their own\n * <th colspan=\"2\"> a column group, in a header row\n * <th scope=\"rowgroup\"> a row group, a heading row in grey\n * <td aria-selected=\"true\"> a selected cell\n *\n * `data-sheet` makes it a spreadsheet: every cell four squares by one (80 by\n * 20), its 1px lines at its end and foot so the words have 79 by 19, set 4px\n * in on the sixteen, as an Ezo item's are. Column letters and the row numbers\n * (`.ds-table__letters`, `.ds-table__number`, two squares wide) stay in place\n * while the sheet scrolls both ways inside `.ds-table-scroll`; give the table\n * `--ds-table-columns` (the number of data columns) and the scroll a height\n * with `--ds-table-height`.\n */\n\n.ds-table {\n --ds-table-row: var(--ds-row-height, calc(20px * var(--ds-sf, 1)));\n --ds-table-gap: calc(var(--ds-table-row) / 2);\n --ds-table-rule: var(--ds-border-color, light-dark(#d8d8d8, #3d3d3d));\n --ds-table-paper: var(--ds-background, Canvas);\n width: 100%;\n border-collapse: collapse;\n border-spacing: 0;\n color: var(--ds-text-color, inherit);\n font-family: var(--ds-typeface-regular, inherit);\n font-feature-settings: var(--ds-font-features, normal);\n font-size: var(--ds-type-size-default, 14px);\n letter-spacing: var(--ds-type-letterspacing-default, normal);\n}\n\n.ds-table :is(th, td) {\n box-sizing: border-box;\n height: var(--ds-table-row);\n padding: 0 var(--ds-table-gap) 0 0;\n border: 0;\n border-bottom: 1px solid var(--ds-table-rule);\n background: transparent;\n line-height: var(--ds-type-lineheight-default);\n text-align: start;\n vertical-align: bottom;\n font-weight: inherit;\n white-space: nowrap;\n}\n\n.ds-table :is(th, td):last-child {\n padding-inline-end: 0;\n}\n\n.ds-table thead th,\n.ds-table th[scope=\"rowgroup\"] {\n color: var(--ds-title-color, light-dark(#797979, #9a9a9a));\n}\n\n.ds-table tbody th:not([scope=\"rowgroup\"]) {\n color: inherit;\n}\n\n.ds-table [data-numeric] {\n text-align: end;\n font-variant-numeric: tabular-nums;\n}\n\n/* Totals: the rule above them is the last body row's; theirs closes the table. */\n.ds-table tfoot :is(th, td) {\n color: inherit;\n}\n\n.ds-table [aria-selected=\"true\"] {\n background: var(--ds-accent-color, Highlight);\n color: var(--ds-button-text-color-on-accent, inherit);\n}\n\n.ds-table :is(th, td):has(> :is(a, button):only-child) {\n cursor: pointer;\n}\n\n.ds-table caption {\n box-sizing: border-box;\n height: var(--ds-table-row);\n padding-top: calc(var(--ds-table-row) - var(--ds-type-lineheight-default));\n line-height: var(--ds-type-lineheight-default);\n text-align: start;\n color: var(--ds-title-color, light-dark(#797979, #9a9a9a));\n}\n\n.ds-table-scroll {\n max-width: 100%;\n overflow-x: auto;\n overscroll-behavior-x: contain;\n}\n\n.ds-table-scroll > .ds-table {\n width: max-content;\n min-width: 100%;\n}\n\n.ds-table[data-sticky] :is(th, td):first-child {\n position: sticky;\n inset-inline-start: 0;\n z-index: 1;\n background: var(--ds-table-paper);\n}\n\n.ds-table[data-sticky] [aria-selected=\"true\"]:first-child {\n background: var(--ds-accent-color, Highlight);\n}\n\n/* Keep the row whose details are open visible, including its sticky first cell.\n Cell selection remains independent and keeps its accent. */\n.ds-table tbody > tr[data-open]:not([data-open=\"false\"]) > :is(th, td):not([aria-selected=\"true\"]) {\n background: var(--ds-row-fill-current, var(--ds-fill-hover));\n}\n@media (forced-colors: active) {\n .ds-table tbody > tr[data-open]:not([data-open=\"false\"]) > :is(th, td):not([aria-selected=\"true\"]) {\n background: Highlight;\n color: HighlightText;\n }\n}\n\n/* A spreadsheet: cells four squares by one, on lines, lettered and numbered. */\n.ds-table[data-sheet] {\n --ds-table-cell: calc(4 * var(--ds-table-row));\n --ds-table-index: calc(2 * var(--ds-table-row));\n --ds-table-text: calc(4px * var(--ds-sf, 1));\n table-layout: fixed;\n width: calc(var(--ds-table-index) + var(--ds-table-columns, 8) * var(--ds-table-cell));\n min-width: 0;\n border-collapse: separate;\n border-spacing: 0;\n}\n.ds-table-scroll > .ds-table[data-sheet] {\n width: calc(var(--ds-table-index) + var(--ds-table-columns, 8) * var(--ds-table-cell));\n min-width: 0;\n}\n.ds-table[data-sheet] :is(th, td) {\n width: var(--ds-table-cell);\n max-width: var(--ds-table-cell);\n height: var(--ds-table-row);\n padding: 0 var(--ds-table-text);\n border-bottom: 1px solid var(--ds-table-rule);\n border-inline-end: 1px solid var(--ds-table-rule);\n overflow: hidden;\n text-overflow: ellipsis;\n}\n.ds-table[data-sheet] :is(th, td):last-child {\n padding-inline-end: var(--ds-table-text);\n}\n.ds-table[data-sheet] .ds-table__number {\n width: var(--ds-table-index);\n max-width: var(--ds-table-index);\n position: sticky;\n inset-inline-start: 0;\n z-index: 1;\n background: var(--ds-table-paper);\n color: var(--ds-title-color, light-dark(#797979, #9a9a9a));\n text-align: center;\n font-variant-numeric: tabular-nums;\n}\n.ds-table[data-sheet] thead :is(th, td) {\n position: sticky;\n top: 0;\n z-index: 2;\n background: var(--ds-table-paper);\n}\n.ds-table[data-sheet] thead tr + tr :is(th, td) {\n top: var(--ds-table-row);\n}\n.ds-table[data-sheet] thead .ds-table__number {\n z-index: 3;\n}\n.ds-table[data-sheet] .ds-table__letters td {\n color: var(--ds-title-color, light-dark(#797979, #9a9a9a));\n text-align: center;\n}\n.ds-table[data-sheet] tbody td:not([data-numeric]) {\n color: inherit;\n}\n.ds-table[data-sheet] [aria-selected=\"true\"] {\n background: transparent;\n color: inherit;\n box-shadow: inset 0 0 0 2px var(--ds-focus-ring, Highlight);\n}\n.ds-table-scroll:has(> .ds-table[data-sheet]) {\n max-height: var(--ds-table-height, none);\n overflow: auto;\n overscroll-behavior: contain;\n}\n/*\n * Text on the grid, as plain classes on native text.\n *\n * Interface copy on a page without Lit: a label, a message, a title. Each line\n * is one square (`--ds-unit`), so a paragraph of any length stands on whole\n * squares, and a display title takes two. The `ds-text` element draws the same\n * words when they come from a translation key.\n *\n * one.css and controls.css both import this file, so a page that loads either\n * of them, or both, has one definition of these classes.\n *\n * ds-text 14 on a one-square line, the text colour\n * ds-text--small 10\n * ds-text--heading 13, medium\n * ds-text--display 20 on two squares, medium\n * ds-text--strong medium\n * ds-text--muted, --title, --danger tones\n */\n\n.ds-text {\n margin: 0;\n color: var(--ds-text-color);\n font-family: var(--ds-typeface-regular);\n font-feature-settings: var(--ds-font-features);\n font-size: var(--ds-type-size-default);\n font-weight: var(--ds-type-weight-default);\n line-height: var(--ds-unit);\n letter-spacing: var(--ds-type-letterspacing-default);\n}\n\n.ds-text--small {\n font-size: var(--ds-type-size-small);\n}\n\n.ds-text--heading {\n font-family: var(--ds-typeface-medium);\n font-size: var(--ds-type-size-heading);\n font-weight: var(--ds-type-weight-bold);\n}\n\n.ds-text--display {\n font-family: var(--ds-typeface-medium);\n font-size: var(--ds-type-size-display);\n font-weight: var(--ds-type-weight-bold);\n line-height: calc(2 * var(--ds-unit));\n letter-spacing: calc(var(--ds-display-text-tracking, -0.4px) * var(--ds-sf, 1));\n}\n\n.ds-text--strong {\n font-family: var(--ds-typeface-medium);\n font-weight: var(--ds-type-weight-bold);\n}\n\n.ds-text--muted {\n color: var(--ds-text-color-muted);\n}\n\n.ds-text--title {\n color: var(--ds-title-color);\n}\n\n.ds-text--danger {\n color: var(--ds-danger-color);\n}\n\n.ds-text--warning {\n color: var(--ds-warning-color);\n}\n/*\n * An empty state, as plain classes on native elements.\n *\n * It says that a place has nothing in it yet and what to do about it: a title,\n * a line of text and, when there is one, the action that fills it. The words\n * sit on the paper with no box, no illustration and no colour; every line is\n * one square, so the whole stands on whole squares. The `ds-empty` element\n * draws the same parts from a translation key, with the shared words' \"Nothing\n * here yet\" as its title when none is given.\n *\n * ds-empty the block, at most sixteen squares wide\n * ds-empty__icon an icon from the library, on its own square, muted\n * ds-empty__title one line in the medium face\n * ds-empty__text lines of one square, muted\n * ds-empty__actions buttons or links on one row, one square below\n * ds-empty--centered centred in the space it stands in\n * ds-empty--done all done: the check on a mark in the success\n * green, the title in that green\n *\n * Tokens: `--ds-empty-measure` (the widest it grows, sixteen squares) and\n * `--ds-empty-padding` (the room above and below, none by default).\n */\n\n.ds-empty {\n box-sizing: border-box;\n display: flex;\n flex-direction: column;\n align-items: flex-start;\n width: 100%;\n max-width: var(--ds-empty-measure, calc(16 * var(--ds-unit)));\n margin: 0;\n padding-block: var(--ds-empty-padding, 0);\n color: var(--ds-text-color);\n font-family: var(--ds-typeface-regular);\n font-feature-settings: var(--ds-font-features);\n font-size: var(--ds-type-size-default);\n font-weight: var(--ds-type-weight-default);\n line-height: var(--ds-unit);\n letter-spacing: var(--ds-type-letterspacing-default);\n text-transform: none;\n}\n\n.ds-empty__icon {\n display: flex;\n align-items: center;\n height: var(--ds-unit);\n color: var(--ds-text-color-muted);\n}\n\n.ds-empty__title,\n.ds-empty__text {\n margin: 0;\n font: inherit;\n letter-spacing: inherit;\n}\n\n.ds-empty__title {\n font-family: var(--ds-typeface-medium);\n font-weight: var(--ds-type-weight-bold);\n}\n\n.ds-empty__text {\n color: var(--ds-text-color-muted);\n}\n\n.ds-empty__actions {\n display: flex;\n flex-wrap: wrap;\n align-items: center;\n gap: 0 calc(var(--ds-unit) / 2);\n min-height: var(--ds-row-height);\n margin-top: var(--ds-unit);\n}\n\n.ds-empty--centered {\n align-items: center;\n margin-inline: auto;\n text-align: center;\n}\n\n.ds-empty--centered .ds-empty__actions {\n justify-content: center;\n}\n\n/* Done: a place empty because everything in it is finished (every receipt\n found, nothing left to review). The icon, the check by default, stands on a\n round mark one control high in the success green, on the sixteen, and the\n title takes the same green; the line under it stays muted. */\n.ds-empty--done .ds-empty__icon {\n box-sizing: border-box;\n justify-content: center;\n width: var(--ds-control-height);\n height: var(--ds-control-height);\n margin-top: calc(var(--ds-unit) - var(--ds-control-height));\n border-radius: 50%;\n background: var(--ds-success-color);\n color: light-dark(var(--ds-white), var(--ds-black));\n --ds-icon-color: currentColor;\n}\n\n.ds-empty--done .ds-empty__title {\n color: var(--ds-success-color);\n}\n/*\n * An inline notice, as plain classes on native elements.\n *\n * A notice stands in the flow of the page, where its words apply: a failure\n * beside the form that failed, a warning above the list it is about. It is not\n * positioned and takes no box or shadow. A square mark, one control high and\n * filled in the tone's colour, carries the tone; the words sit on the paper\n * beside it, each line one square, with the actions on the row below and the\n * dismiss button at the end of the first line. Danger turns the words into\n * the danger colour. The `ds-notice` element draws the same parts.\n *\n * ds-notice the block: mark, words, dismiss\n * ds-notice__mark the square mark; holds an icon in its ink\n * ds-notice__title one line in the medium face\n * ds-notice__text lines of one square\n * ds-notice__actions buttons or links on one row\n * ds-notice__dismiss an icon button at the end of the first line\n * ds-notice--success, --warning, --danger tones; neutral without one\n * ds-notice--banner a strip across the top of its positioning\n * context instead: one square high, filled in\n * the tone's colour, everything on one line\n * ds-notice--app a row at the top of the page leading to the\n * site's iPhone app: its picture\n * (ds-notice__picture, two squares), its name\n * and one line about it, Open\n * (a.ds-notice__open) and the close; three\n * squares high with a hairline at its foot.\n * startAppBanners() from 0-face/app-banner.ts\n * shows it only where it belongs\n *\n * Give the block role=\"status\", or role=\"alert\" for danger, so assistive\n * technology reads it when it appears.\n *\n * Tokens: `--ds-notice-mark`, `--ds-notice-mark-ink` and `--ds-notice-ink`,\n * which the tones set.\n */\n\n.ds-notice {\n --ds-notice-mark: var(--ds-fill);\n --ds-notice-mark-ink: var(--ds-text-color);\n --ds-notice-ink: var(--ds-text-color);\n box-sizing: border-box;\n display: grid;\n grid-template-columns: var(--ds-unit) minmax(0, 1fr) auto;\n align-items: start;\n margin: 0;\n color: var(--ds-notice-ink);\n font-family: var(--ds-typeface-regular);\n font-feature-settings: var(--ds-font-features);\n font-size: var(--ds-type-size-default);\n font-weight: var(--ds-type-weight-default);\n line-height: var(--ds-unit);\n letter-spacing: var(--ds-type-letterspacing-default);\n text-transform: none;\n}\n\n.ds-notice--success {\n --ds-notice-mark: var(--ds-apple-green);\n --ds-notice-mark-ink: var(--ds-black);\n}\n\n.ds-notice--warning {\n --ds-notice-mark: var(--ds-orange);\n --ds-notice-mark-ink: var(--ds-black);\n}\n\n.ds-notice--danger {\n --ds-notice-mark: var(--ds-danger-color);\n --ds-notice-mark-ink: light-dark(var(--ds-white), var(--ds-black));\n --ds-notice-ink: var(--ds-danger-color);\n}\n\n/* The mark stands on the first line, one control high in a one-square cell. */\n.ds-notice__mark {\n box-sizing: border-box;\n grid-column: 1;\n grid-row: 1;\n display: flex;\n align-items: center;\n justify-content: center;\n width: var(--ds-control-height);\n height: var(--ds-control-height);\n margin-block: calc((var(--ds-unit) - var(--ds-control-height)) / 2);\n overflow: hidden;\n background: var(--ds-notice-mark);\n color: var(--ds-notice-mark-ink);\n --ds-icon-color: var(--ds-notice-mark-ink);\n}\n\n.ds-notice__title,\n.ds-notice__text,\n.ds-notice__actions {\n grid-column: 2;\n min-width: 0;\n margin: 0;\n}\n\n.ds-notice__title,\n.ds-notice__text {\n font: inherit;\n letter-spacing: inherit;\n overflow-wrap: anywhere;\n}\n\n.ds-notice__title {\n font-family: var(--ds-typeface-medium);\n font-weight: var(--ds-type-weight-bold);\n}\n\n.ds-notice__actions {\n display: flex;\n flex-wrap: wrap;\n align-items: center;\n gap: 0 calc(var(--ds-unit) / 2);\n min-height: var(--ds-row-height);\n}\n\n/* The dismiss button closes the first line: a one-square cell at the end.\n Two classes, so the button's own reset of its margin does not undo it. */\n.ds-notice .ds-notice__dismiss {\n grid-column: 3;\n grid-row: 1;\n margin-block: calc((var(--ds-unit) - var(--ds-control-height)) / 2);\n margin-inline-start: calc(var(--ds-unit) - var(--ds-control-height));\n}\n\n/* A banner: the same parts on one line, one square high, across the top of\n the nearest positioned ancestor (or the page), on a fill of the tone's\n colour. It takes no room in the flow; leave a square for it where words\n stand under it. The actions stand at the end of the line, half a square\n apart; danger words keep the text colour on the danger fill. */\n.ds-notice--banner {\n position: absolute;\n top: 0;\n inset-inline: 0;\n z-index: 9999;\n display: flex;\n align-items: center;\n gap: calc(var(--ds-unit) / 2);\n height: var(--ds-unit);\n padding-inline: var(--ds-unit);\n background: color-mix(in srgb, var(--ds-notice-mark) 40%, transparent);\n --ds-notice-ink: var(--ds-text-color);\n}\n\n.ds-notice--banner .ds-notice__mark {\n flex: none;\n margin-block: 0;\n}\n\n.ds-notice--banner .ds-notice__title,\n.ds-notice--banner .ds-notice__text {\n min-width: 0;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n.ds-notice--banner .ds-notice__text {\n flex: 1;\n}\n\n.ds-notice--banner .ds-notice__actions {\n flex: none;\n min-height: 0;\n}\n\n.ds-notice--banner .ds-notice__dismiss {\n margin-block: 0;\n margin-inline-start: 0;\n}\n\n/* The app banner: a row at the top of the page, in the flow, three squares\n high: half a square above and below two squares of content, a hairline at\n its foot. The app's picture fills two squares with a picture's corners; the\n name and the line about it take a square each, on the sixteen; Open and the\n close stand on the sixteen of the square in the middle of the two. */\n.ds-notice--app {\n grid-template-columns: calc(2 * var(--ds-unit)) minmax(0, 1fr) auto var(--ds-unit);\n grid-template-rows: var(--ds-unit) var(--ds-unit);\n column-gap: calc(var(--ds-unit) / 2);\n align-items: end;\n padding: calc(var(--ds-unit) / 2) var(--ds-unit);\n background: var(--ds-paper);\n box-shadow: inset 0 -1px 0 var(--ds-border-color);\n line-height: var(--ds-type-lineheight-default);\n}\n\n.ds-notice--app[hidden] {\n display: none;\n}\n\n.ds-notice__picture {\n box-sizing: border-box;\n grid-column: 1;\n grid-row: 1 / 3;\n align-self: stretch;\n overflow: hidden;\n border-radius: var(--ds-radius);\n background: var(--ds-fill);\n outline: 1px solid var(--ds-border-color);\n outline-offset: -1px;\n}\n\n.ds-notice__picture img {\n display: block;\n width: 100%;\n height: 100%;\n object-fit: cover;\n}\n\n.ds-notice--app .ds-notice__title,\n.ds-notice--app .ds-notice__text {\n grid-column: 2;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n.ds-notice--app .ds-notice__title { grid-row: 1; }\n\n.ds-notice--app .ds-notice__text {\n grid-row: 2;\n color: var(--ds-text-color-muted);\n}\n\n/* Open and the close: their square starts half a square into the two, its\n control on the lower sixteen of it. */\n.ds-notice--app .ds-notice__open,\n.ds-notice--app .ds-notice__dismiss {\n grid-row: 1 / 3;\n align-self: start;\n margin: calc(1.5 * var(--ds-unit) - var(--ds-control-height)) 0 0;\n}\n\n.ds-notice--app .ds-notice__open {\n grid-column: 3;\n text-decoration: none;\n}\n\n.ds-notice--app .ds-notice__dismiss {\n grid-column: 4;\n justify-self: end;\n}\n/*\n * Overlay: everything that stands over the page, one component with a type.\n * A `modal` stands in the centre (controls.css and the element's frame); this\n * sheet draws the others, for the `ds-overlay` element (`type=\"sheet\"`,\n * `\"drawer\"` with `side`, `\"screen\"`, which mark its native dialog\n * `data-ds-type` and `data-ds-edge`) and the native frame\n * (`dialog.ds-overlay.ds-overlay--sheet`, `--drawer` with `--start`,\n * `--screen`); controls.css imports it. A popover is placed by the element.\n *\n * - A sheet is as wide as the screen up to 32 squares and centred beyond\n * that, as high as its content up to two squares below the top, with no\n * line at its foot; its one line, at the top, is drawn inside its first\n * square (`--ds-overlay-line`), so it stands on whole squares. A handle two squares wide stands in the middle of its\n * first square and stays there while the content scrolls.\n * - A drawer is the screen's height and 16 squares wide (`--ds-overlay-width`),\n * leaving at least two squares of the page beside it; its one line is on\n * the side that faces the page. `end` is the right in a left-to-right page.\n * - Each keeps the square of padding inside the screen's safe area\n * (`env(safe-area-inset-*)`, with `viewport-fit=cover` on the page).\n * - Each slides in from its edge and back out to it, in transform alone,\n * while the backdrop fades; with reduced motion it fades in place. Dragging\n * it towards its edge (0-face/overlay-swipe.ts) moves it with the finger and\n * fades the backdrop as it goes.\n * - The page behind a modal native sheet or drawer does not scroll.\n */\n\n:is(ds-overlay > dialog[data-ds-edge=\"bottom\"], dialog.ds-overlay.ds-overlay--sheet),\n:is(ds-overlay > dialog[data-ds-edge=\"end\"], dialog.ds-overlay.ds-overlay--drawer:not(.ds-overlay--start)),\n:is(ds-overlay > dialog[data-ds-edge=\"start\"], dialog.ds-overlay.ds-overlay--drawer.ds-overlay--start) {\n --ds-overlay-gap: var(--ds-unit);\n --ds-overlay-inner: var(--ds-overlay-padding, var(--ds-unit));\n /* The line it faces the page with is drawn inside its first square. */\n --ds-overlay-within: max(0px, var(--ds-overlay-inner) - var(--ds-overlay-line, 1px));\n --ds-overlay-motion: var(--ds-overlay-enter, 380ms);\n --ds-overlay-curve: var(--ds-overlay-easing, cubic-bezier(0.32, 0.72, 0, 1));\n margin: 0;\n gap: var(--ds-overlay-gap);\n transform: var(--ds-overlay-held);\n transition:\n transform var(--ds-overlay-motion) var(--ds-overlay-curve),\n opacity var(--ds-overlay-motion) var(--ds-overlay-curve),\n overlay var(--ds-overlay-motion) allow-discrete,\n display var(--ds-overlay-motion) allow-discrete;\n}\n\n/* Content that supplies its own room. */\n:is(ds-overlay > dialog[data-ds-edge], dialog.ds-overlay:is(.ds-overlay--sheet, .ds-overlay--drawer))[data-ds-overlay-flush] {\n --ds-overlay-inner: 0px;\n --ds-overlay-gap: 0px;\n}\n\n:is(ds-overlay > dialog[data-ds-edge=\"bottom\"], dialog.ds-overlay.ds-overlay--sheet) {\n --ds-overlay-held: translateY(var(--ds-overlay-drag, 0px));\n --ds-overlay-away: translateY(100%);\n inset: auto 0 0;\n width: var(--ds-overlay-width, 100%);\n max-width: min(100%, var(--ds-overlay-sheet-width, calc(32 * var(--ds-unit))));\n height: var(--ds-overlay-height, fit-content);\n max-height: calc(100dvh - var(--ds-overlay-sheet-gap, calc(2 * var(--ds-unit))) - env(safe-area-inset-top, 0px));\n margin: 0 auto;\n padding:\n var(--ds-overlay-within)\n calc(var(--ds-overlay-inner) + env(safe-area-inset-right, 0px))\n calc(var(--ds-overlay-inner) + env(safe-area-inset-bottom, 0px))\n calc(var(--ds-overlay-inner) + env(safe-area-inset-left, 0px));\n border-bottom: 0;\n}\n\n/* The handle: two squares wide, in the middle of the first square, above the\n * content as it scrolls. It takes no room: the content starts where it would. */\n:is(ds-overlay > dialog[data-ds-edge=\"bottom\"], dialog.ds-overlay.ds-overlay--sheet)::before {\n --ds-overlay-handle-height: calc(4px * var(--ds-sf, 1));\n content: \"\";\n display: var(--ds-overlay-handle, block);\n position: sticky;\n z-index: 1;\n /* A sticky offset counts from the content edge, under the sheet's top padding: take that\n padding off, so the handle is held where it already stands, in the first square. */\n top: calc((var(--ds-unit) - var(--ds-overlay-handle-height)) / 2 - var(--ds-overlay-line, 1px) - var(--ds-overlay-within));\n flex: 0 0 auto;\n align-self: center;\n width: calc(2 * var(--ds-unit));\n height: var(--ds-overlay-handle-height);\n margin-top: calc(var(--ds-overlay-inner) * -1 + (var(--ds-unit) - var(--ds-overlay-handle-height)) / 2);\n margin-bottom: calc(var(--ds-overlay-inner) - var(--ds-overlay-gap) - var(--ds-overlay-handle-height) - (var(--ds-unit) - var(--ds-overlay-handle-height)) / 2);\n border-radius: calc(var(--ds-overlay-handle-height) / 2);\n background: var(--ds-overlay-handle-color, var(--ds-border-color));\n pointer-events: none;\n}\n\n:is(ds-overlay > dialog[data-ds-edge=\"end\"], dialog.ds-overlay.ds-overlay--drawer:not(.ds-overlay--start)),\n:is(ds-overlay > dialog[data-ds-edge=\"start\"], dialog.ds-overlay.ds-overlay--drawer.ds-overlay--start) {\n --ds-overlay-held: translateX(var(--ds-overlay-drag, 0px));\n width: calc(var(--ds-overlay-width, calc(16 * var(--ds-unit))) + var(--ds-overlay-safe-side, 0px));\n max-width: calc(100vw - 2 * var(--ds-unit));\n height: 100dvh;\n max-height: none;\n border-top: 0;\n border-bottom: 0;\n}\n\n/* At the right: the end of a left-to-right page, the start of a right-to-left one. */\n:is(ds-overlay > dialog[data-ds-edge=\"end\"], dialog.ds-overlay.ds-overlay--drawer:not(.ds-overlay--start)):not(:dir(rtl)),\n:is(ds-overlay > dialog[data-ds-edge=\"start\"], dialog.ds-overlay.ds-overlay--drawer.ds-overlay--start):dir(rtl) {\n --ds-overlay-away: translateX(100%);\n --ds-overlay-safe-side: env(safe-area-inset-right, 0px);\n inset: 0 0 0 auto;\n padding:\n calc(var(--ds-overlay-inner) + env(safe-area-inset-top, 0px))\n calc(var(--ds-overlay-inner) + env(safe-area-inset-right, 0px))\n calc(var(--ds-overlay-inner) + env(safe-area-inset-bottom, 0px))\n var(--ds-overlay-within);\n border-right: 0;\n}\n\n:is(ds-overlay > dialog[data-ds-edge=\"start\"], dialog.ds-overlay.ds-overlay--drawer.ds-overlay--start):not(:dir(rtl)),\n:is(ds-overlay > dialog[data-ds-edge=\"end\"], dialog.ds-overlay.ds-overlay--drawer:not(.ds-overlay--start)):dir(rtl) {\n --ds-overlay-away: translateX(-100%);\n --ds-overlay-safe-side: env(safe-area-inset-left, 0px);\n inset: 0 auto 0 0;\n padding:\n calc(var(--ds-overlay-inner) + env(safe-area-inset-top, 0px))\n var(--ds-overlay-within)\n calc(var(--ds-overlay-inner) + env(safe-area-inset-bottom, 0px))\n calc(var(--ds-overlay-inner) + env(safe-area-inset-left, 0px));\n border-left: 0;\n}\n\n/* The page behind a native sheet or drawer holds still while it is open, as\n * the element holds it (the element saves and restores the scroll itself). */\n:root:has(dialog.ds-overlay:is(.ds-overlay--sheet, .ds-overlay--drawer):modal) {\n overflow: hidden;\n overscroll-behavior: none;\n}\n\n/* Out to its edge, a little quicker than it came; and in from it. */\n:is(ds-overlay > dialog[data-ds-edge], dialog.ds-overlay:is(.ds-overlay--sheet, .ds-overlay--drawer)):not([open]) {\n --ds-overlay-motion: var(--ds-overlay-exit, 260ms);\n transform: var(--ds-overlay-away);\n}\n\n@starting-style {\n :is(ds-overlay > dialog[data-ds-edge], dialog.ds-overlay:is(.ds-overlay--sheet, .ds-overlay--drawer))[open] {\n transform: var(--ds-overlay-away);\n }\n}\n\n:is(ds-overlay > dialog[data-ds-edge], dialog.ds-overlay:is(.ds-overlay--sheet, .ds-overlay--drawer))::backdrop {\n opacity: calc(1 - var(--ds-overlay-progress, 0));\n transition:\n opacity var(--ds-overlay-motion, 380ms) ease,\n overlay var(--ds-overlay-motion, 380ms) allow-discrete,\n display var(--ds-overlay-motion, 380ms) allow-discrete;\n}\n\n:is(ds-overlay > dialog[data-ds-edge], dialog.ds-overlay:is(.ds-overlay--sheet, .ds-overlay--drawer)):not([open])::backdrop {\n opacity: 0;\n}\n\n@starting-style {\n :is(ds-overlay > dialog[data-ds-edge], dialog.ds-overlay:is(.ds-overlay--sheet, .ds-overlay--drawer))[open]::backdrop {\n opacity: 0;\n }\n}\n\n/* While a finger holds it, it follows the finger alone. */\n:is(ds-overlay > dialog[data-ds-edge], dialog.ds-overlay:is(.ds-overlay--sheet, .ds-overlay--drawer))[data-ds-overlay-dragging],\n:is(ds-overlay > dialog[data-ds-edge], dialog.ds-overlay:is(.ds-overlay--sheet, .ds-overlay--drawer))[data-ds-overlay-dragging]::backdrop {\n transition: none;\n}\n\n/* Reduced motion: no slide. It fades where it stands, a dragged one too. */\n@media (prefers-reduced-motion: reduce) {\n :is(ds-overlay > dialog[data-ds-edge], dialog.ds-overlay:is(.ds-overlay--sheet, .ds-overlay--drawer)) {\n --ds-overlay-motion: 150ms;\n transition:\n opacity var(--ds-overlay-motion) ease,\n overlay var(--ds-overlay-motion) allow-discrete,\n display var(--ds-overlay-motion) allow-discrete;\n }\n\n :is(ds-overlay > dialog[data-ds-edge], dialog.ds-overlay:is(.ds-overlay--sheet, .ds-overlay--drawer)):not([open]) {\n --ds-overlay-motion: 150ms;\n transform: var(--ds-overlay-held);\n opacity: 0;\n }\n\n @starting-style {\n :is(ds-overlay > dialog[data-ds-edge], dialog.ds-overlay:is(.ds-overlay--sheet, .ds-overlay--drawer))[open] {\n transform: var(--ds-overlay-held);\n opacity: 0;\n }\n }\n}\n\n/*\n * The screen: an overlay over the whole screen, for navigation folded away on\n * a narrow screen (`ds-header`, `ds-page drawer`, `attachOverlay()`).\n *\n * The panel is the dialog frame (`dialog.ds-overlay`) laid over the whole\n * screen, on the page's own paper, a square of room on every side. Its first\n * row holds the close button where the menu button stood; what the page\n * folded away (its navigation and actions) follows, every link one square\n * high. The page script `0-face/attach-overlay.ts` opens it: it moves the folded parts\n * into the panel and back, keeps focus inside, closes on Escape, on a link and\n * when the screen widens, and holds the page's scroll while it is open.\n * `ds-header` and `ds-page drawer` use the same script and these rules.\n *\n * ds-overlay--screen on a <dialog class=\"ds-overlay\">, the panel\n * ds-overlay__bar the first row: the close button at its end\n * ds-overlay__close the close button, an icon button\n * ds-overlay__toggle the button that opens it: it carries\n * two icons, the first shown while closed and the\n * second (close) while open\n *\n * Tokens: `--ds-overlay-paper` (the page's paper by default).\n */\n\n:is(ds-overlay > dialog[data-ds-type=\"screen\"], dialog.ds-overlay.ds-overlay--screen) {\n --ds-overlay-width: 100vw;\n width: 100vw;\n max-width: none;\n height: 100dvh;\n max-height: none;\n margin: 0;\n padding: var(--ds-unit);\n gap: 0;\n border: 0;\n background: var(--ds-overlay-paper, var(--background, Canvas));\n overflow-y: auto;\n}\n\n:is(ds-overlay > dialog[data-ds-type=\"screen\"], dialog.ds-overlay.ds-overlay--screen)[open] {\n display: flex;\n flex-direction: column;\n align-items: stretch;\n gap: var(--ds-unit);\n}\n\n/* Content that supplies its own room, as the documentation's navigation does. */\n:is(ds-overlay > dialog[data-ds-type=\"screen\"], dialog.ds-overlay.ds-overlay--screen)[data-ds-overlay-flush] {\n padding: 0;\n gap: 0;\n}\n\n:is(ds-overlay > dialog[data-ds-type=\"screen\"], dialog.ds-overlay.ds-overlay--screen)::backdrop {\n background: transparent;\n}\n\n/* It arrives by fading in and settling half a square, and leaves at once. */\n@media (prefers-reduced-motion: no-preference) {\n :is(ds-overlay > dialog[data-ds-type=\"screen\"], dialog.ds-overlay.ds-overlay--screen)[open] {\n transition: opacity 160ms ease-out, transform 160ms ease-out;\n }\n\n @starting-style {\n :is(ds-overlay > dialog[data-ds-type=\"screen\"], dialog.ds-overlay.ds-overlay--screen)[open] {\n opacity: 0;\n transform: translateY(calc(var(--ds-unit) / -2));\n }\n }\n}\n\n.ds-overlay__bar {\n display: flex;\n align-items: center;\n justify-content: flex-end;\n min-height: var(--ds-row-height);\n}\n\n/* Centred in the last square of the row, as the menu button is. Two classes,\n so the button's own margin does not undo it. */\n.ds-overlay__bar > .ds-overlay__close {\n margin-inline-end: calc((var(--ds-unit) - var(--ds-control-height)) / 2);\n}\n\n/* The toggle shows its first icon while closed and its second while open; the\n close button, a copy of it, shows the second. */\n.ds-overlay__toggle:not([aria-expanded=\"true\"]) > :nth-child(2),\n.ds-overlay__toggle[aria-expanded=\"true\"] > :first-child:not(:only-child),\n.ds-overlay__close > :first-child:not(:only-child) {\n display: none;\n}\n/*\n * A site header, as plain classes on native elements.\n *\n * One row of one square, a square of room around it: the brand at the start\n * in twelve squares (as a page's navigation column is, so the links stand\n * over the work), the navigation two squares after it, the actions at the end. Every link is\n * one square high, a square apart, in the text's ink; the page you are on\n * (`aria-current=\"page\"`) stands on a hairline of the full ink, the others\n * show a faint one under the pointer. Below thirty squares of width the\n * navigation and the actions fold into a drawer: the menu button takes their\n * place at the end of the row, and `0-face/header.ts` opens them over the page.\n * The `ds-header` element draws the same parts.\n *\n * ds-header the row, a <header>\n * ds-header__brand the mark or name, a link home; a picture in it is one square high\n * ds-header__nav the links, a <nav>\n * ds-header__actions buttons or links at the end\n * ds-header__toggle the menu button: `.ds-button.ds-button--icon.ds-overlay__toggle`\n * with a menu icon and a close icon, shown only on a narrow screen\n * ds-header--sticky stays at the top of the page as it scrolls, on the paper\n *\n * Tokens: `--ds-header-brand` (the brand's width, at least twelve squares),\n * `--ds-header-paper` (the sticky header's paper) and `--ds-header-line` (the\n * hairline under a sticky header, none by default).\n */\n\n.ds-header {\n box-sizing: border-box;\n container-type: inline-size;\n display: flex;\n align-items: center;\n gap: calc(2 * var(--ds-unit));\n min-width: 0;\n margin: 0;\n padding: var(--ds-unit);\n color: var(--ds-text-color);\n font-family: var(--ds-typeface-regular);\n font-feature-settings: var(--ds-font-features);\n font-size: var(--ds-type-size-default);\n font-weight: var(--ds-type-weight-default);\n line-height: var(--ds-unit);\n letter-spacing: var(--ds-type-letterspacing-default);\n text-transform: none;\n}\n\n.ds-header--sticky {\n position: sticky;\n top: 0;\n z-index: 1;\n background: var(--ds-header-paper, var(--background, Canvas));\n box-shadow: inset 0 -1px var(--ds-header-line, transparent);\n}\n\n.ds-header__brand {\n box-sizing: border-box;\n display: inline-flex;\n flex: 0 0 auto;\n min-width: var(--ds-header-brand, calc(12 * var(--ds-unit)));\n align-items: center;\n gap: calc(var(--ds-unit) / 2);\n height: var(--ds-unit);\n color: inherit;\n font-family: var(--ds-typeface-medium);\n font-weight: var(--ds-type-weight-bold);\n text-decoration: none;\n white-space: nowrap;\n}\n\n.ds-header__brand :is(img, svg) {\n display: block;\n width: auto;\n height: var(--ds-unit);\n}\n\n.ds-header__nav,\n.ds-header__actions {\n display: flex;\n align-items: center;\n gap: var(--ds-unit);\n min-width: 0;\n margin: 0;\n padding: 0;\n}\n\n.ds-header__nav {\n flex: 1 1 auto;\n flex-wrap: wrap;\n row-gap: 0;\n}\n\n.ds-header__actions {\n flex: 0 0 auto;\n justify-content: flex-end;\n gap: calc(var(--ds-unit) / 2);\n margin-inline-start: auto;\n}\n\n/* A link in the navigation: the text's ink on a one-square line. */\n.ds-header__nav a {\n display: block;\n height: var(--ds-unit);\n color: inherit;\n text-decoration-line: underline;\n text-decoration-thickness: 1px;\n text-decoration-color: transparent;\n text-underline-offset: calc(2px * var(--ds-sf));\n white-space: nowrap;\n}\n\n.ds-header__nav a:hover {\n text-decoration-color: color-mix(in srgb, currentColor 40%, transparent);\n}\n\n.ds-header__nav a[aria-current]:not([aria-current=\"false\"]) {\n text-decoration-color: currentColor;\n}\n\n.ds-header__nav a:focus-visible,\n.ds-header__brand:focus-visible {\n outline: 2px solid var(--ds-focus-ring);\n outline-offset: 1px;\n}\n\n/* The menu button stands at the end of the row, and only on a narrow screen.\n Two classes, so the button's own display and margin do not undo it. */\n.ds-header > .ds-header__toggle {\n display: none;\n margin-inline-start: auto;\n /* Centred in the last square of the row, where the close button stands too. */\n margin-inline-end: calc((var(--ds-unit) - var(--ds-control-height)) / 2);\n}\n\n@container (max-width: 599px) {\n .ds-header > :is(.ds-header__nav, .ds-header__actions) {\n display: none;\n }\n\n .ds-header > .ds-header__toggle {\n display: inline-flex;\n }\n\n .ds-header > .ds-header__brand {\n min-width: 0;\n }\n}\n\n/* In the drawer the navigation is a column of one-square links, and the\n actions a row one square below it. */\n.ds-overlay--screen :is(.ds-header__nav, .ds-header__actions) {\n flex: 0 0 auto;\n flex-direction: column;\n align-items: flex-start;\n flex-wrap: nowrap;\n gap: 0;\n margin: 0;\n}\n\n.ds-overlay--screen .ds-header__actions {\n flex-direction: row;\n flex-wrap: wrap;\n gap: calc(var(--ds-unit) / 2);\n}\n/*\n * A site footer, as plain classes on native elements.\n *\n * The brand and its line at the start, twelve squares wide; the columns of\n * links beside it, eight squares each, two squares apart; then, two squares\n * below, the legal line at the start and the preferences (language and theme,\n * as `ds-cycle` or native buttons) at the end. Every line is one square, the\n * column headings in the title grey, the links in the text's ink with a faint\n * hairline under the pointer. A hairline runs along its top. Columns that do\n * not fit beside the brand go below it, and on a narrow screen everything\n * stands in one column. The `ds-footer` element draws the same parts from data.\n *\n * ds-footer the block, a <footer>\n * ds-footer__brand the mark and its line\n * ds-footer__mark the mark or name, a link home; a picture in it is one square high\n * ds-footer__tagline a line about the site, muted\n * ds-footer__columns the columns, a <nav> or <div>\n * ds-footer__column one column: a heading and its links\n * ds-footer__heading the column's heading, one line in the title grey\n * ds-footer__links the links, a <ul> with one link per <li>\n * ds-footer__base the last row, two squares below\n * ds-footer__legal in it, the copyright and legal line, muted\n * ds-footer__preferences in it, the language and theme controls, at its end\n *\n * Tokens: `--ds-footer-line` (the hairline along the top).\n */\n\n.ds-footer {\n box-sizing: border-box;\n container-type: inline-size;\n display: flex;\n flex-wrap: wrap;\n align-items: flex-start;\n gap: calc(2 * var(--ds-unit));\n min-width: 0;\n margin: 0;\n padding: calc(2 * var(--ds-unit)) var(--ds-unit) var(--ds-unit);\n box-shadow: inset 0 1px var(--ds-footer-line, var(--ds-border-color));\n color: var(--ds-text-color);\n font-family: var(--ds-typeface-regular);\n font-feature-settings: var(--ds-font-features);\n font-size: var(--ds-type-size-default);\n font-weight: var(--ds-type-weight-default);\n line-height: var(--ds-unit);\n letter-spacing: var(--ds-type-letterspacing-default);\n text-transform: none;\n}\n\n.ds-footer :is(p, h2, h3, h4, ul) {\n margin: 0;\n font: inherit;\n letter-spacing: inherit;\n}\n\n.ds-footer__brand {\n display: flex;\n flex: 0 0 calc(12 * var(--ds-unit));\n flex-direction: column;\n max-width: 100%;\n min-width: 0;\n}\n\n.ds-footer__mark {\n display: inline-flex;\n align-items: center;\n gap: calc(var(--ds-unit) / 2);\n align-self: flex-start;\n height: var(--ds-unit);\n color: inherit;\n font-family: var(--ds-typeface-medium);\n font-weight: var(--ds-type-weight-bold);\n text-decoration: none;\n}\n\n.ds-footer__mark :is(img, svg) {\n display: block;\n width: auto;\n height: var(--ds-unit);\n}\n\n.ds-footer__tagline,\n.ds-footer__legal {\n color: var(--ds-text-color-muted);\n}\n\n.ds-footer__columns {\n display: flex;\n /* Never narrower than one column: below that the columns go under the brand. */\n flex: 1 1 calc(8 * var(--ds-unit));\n flex-wrap: wrap;\n gap: var(--ds-unit) calc(2 * var(--ds-unit));\n min-width: min(100%, calc(8 * var(--ds-unit)));\n}\n\n.ds-footer__column {\n display: flex;\n flex: 0 0 calc(8 * var(--ds-unit));\n flex-direction: column;\n max-width: 100%;\n min-width: 0;\n}\n\n.ds-footer .ds-footer__heading {\n color: var(--ds-title-color);\n}\n\n.ds-footer .ds-footer__links {\n padding: 0;\n list-style: none;\n}\n\n.ds-footer__links li {\n margin: 0;\n padding: 0;\n}\n\n.ds-footer__links a {\n display: inline-block;\n max-width: 100%;\n overflow: hidden;\n color: inherit;\n text-decoration-line: underline;\n text-decoration-thickness: 1px;\n text-decoration-color: transparent;\n text-overflow: ellipsis;\n text-underline-offset: calc(2px * var(--ds-sf));\n vertical-align: top;\n white-space: nowrap;\n}\n\n.ds-footer__links a:hover {\n text-decoration-color: color-mix(in srgb, currentColor 40%, transparent);\n}\n\n.ds-footer__links a[aria-current]:not([aria-current=\"false\"]) {\n text-decoration-color: currentColor;\n}\n\n:is(.ds-footer__links a, .ds-footer__mark):focus-visible {\n outline: 2px solid var(--ds-focus-ring);\n outline-offset: 1px;\n}\n\n/* The last row, two squares below: the legal line at the start, the\n preferences at the end; on a narrow screen the preferences go first. */\n.ds-footer__base {\n display: flex;\n flex: 0 0 100%;\n flex-wrap: wrap;\n align-items: flex-start;\n gap: var(--ds-unit) calc(2 * var(--ds-unit));\n min-width: 0;\n}\n\n.ds-footer__legal {\n flex: 1 1 auto;\n min-width: 0;\n}\n\n.ds-footer__preferences {\n display: flex;\n flex: 0 0 auto;\n flex-wrap: wrap;\n align-items: center;\n gap: 0 calc(var(--ds-unit) / 2);\n min-height: var(--ds-unit);\n margin-inline-start: auto;\n}\n\n@container (max-width: 599px) {\n .ds-footer__brand,\n .ds-footer__columns {\n flex-basis: 100%;\n }\n\n .ds-footer__base {\n flex-direction: column;\n }\n\n .ds-footer__preferences {\n order: -1;\n margin-inline-start: 0;\n }\n}\n/*\n * A document page: terms, a privacy policy, a legal notice, a help article.\n *\n * The contents stand at the start, twelve squares wide, and stay in view as\n * the writing scrolls past; the writing, two squares after them, is a reading\n * column of at most thirty-two squares, native headings and paragraphs marked\n * `data-ds-prose` (prose.css draws them). Where the two do not fit side by\n * side the contents stand above the writing. Every line is one square; the\n * contents' links are in the text's ink, the section in view (`aria-current`)\n * on a hairline of the full ink, a third level half a square in. The\n * `ds-document` element builds the contents from the headings and marks the\n * one in view.\n *\n * ds-document the page's two columns\n * ds-document__toc the contents, a <nav>, as tall as the writing\n * ds-document__contents inside it, what stays in view: the title and the list\n * ds-document__toc-title \"Contents\", one line in the title grey\n * ds-document__toc-list the links, an <ol> with one link per <li>\n * ds-document__toc-sub an <li> for a third-level heading\n * ds-document__body the writing, marked data-ds-prose\n *\n * A definition table (`ds-definitions` on a <dl>) sets terms beside what they\n * mean, as a legal notice such as 特定商取引法に基づく表記 does: the term eight\n * squares wide in the muted ink, its definition beside it, each pair on a\n * hairline at its foot with half a square above and below, as a prose table's\n * rows are. Pairs may stand in a <div> each. Below twenty-four squares the\n * definition goes under its term. It works inside or outside prose.\n *\n * Tokens: `--ds-document-top` (where the contents stop below the top of the\n * view, one square; add a sticky header's height), `--ds-definitions-term`\n * (the term column, eight squares).\n */\n\n.ds-document {\n box-sizing: border-box;\n display: flex;\n flex-wrap: wrap;\n align-items: stretch;\n gap: var(--ds-unit) calc(2 * var(--ds-unit));\n min-width: 0;\n color: var(--ds-text-color);\n font-family: var(--ds-typeface-regular);\n font-feature-settings: var(--ds-font-features);\n font-size: var(--ds-type-size-default);\n font-weight: var(--ds-type-weight-default);\n line-height: var(--ds-unit);\n letter-spacing: var(--ds-type-letterspacing-default);\n}\n\n/* The contents column stretches to the writing's height when the two stand\n side by side, so what is inside it can stay in view; standing above the\n writing it is only as tall as itself, and nothing sticks. */\n.ds-document__toc {\n flex: 0 0 calc(12 * var(--ds-unit));\n max-width: 100%;\n min-width: 0;\n}\n\n.ds-document__contents {\n position: sticky;\n top: var(--ds-document-top, var(--ds-unit));\n}\n\n.ds-document__toc-title {\n margin: 0;\n color: var(--ds-title-color);\n font: inherit;\n letter-spacing: inherit;\n}\n\n.ds-document__toc-list,\n.ds-document__toc-list ol {\n margin: 0;\n padding: 0;\n list-style: none;\n}\n\n.ds-document__toc-list li {\n margin: 0;\n padding: 0;\n}\n\n.ds-document__toc-list .ds-document__toc-sub {\n padding-inline-start: calc(var(--ds-unit) / 2);\n}\n\n.ds-document__toc-list a {\n display: block;\n overflow: hidden;\n color: inherit;\n text-decoration-line: underline;\n text-decoration-thickness: 1px;\n text-decoration-color: transparent;\n text-overflow: ellipsis;\n text-underline-offset: calc(2px * var(--ds-sf));\n white-space: nowrap;\n}\n\n.ds-document__toc-list a:hover {\n text-decoration-color: color-mix(in srgb, currentColor 40%, transparent);\n}\n\n.ds-document__toc-list a[aria-current]:not([aria-current=\"false\"]) {\n text-decoration-color: currentColor;\n}\n\n.ds-document__toc-list a:focus-visible {\n outline: 2px solid var(--ds-focus-ring);\n outline-offset: -1px;\n}\n\n/* The writing: at least twenty squares beside the contents, else below them. */\n.ds-document__body {\n flex: 1 1 0;\n min-width: min(100%, calc(20 * var(--ds-unit)));\n max-width: calc(32 * var(--ds-unit));\n}\n\n/* A heading the contents jump to stops where the contents do. */\n.ds-document__body :is(h1, h2, h3, h4, h5, h6) {\n scroll-margin-top: var(--ds-document-top, var(--ds-unit));\n}\n\n/* A definition table. */\n\n.ds-definitions {\n box-sizing: border-box;\n container-type: inline-size;\n display: grid;\n grid-template-columns: minmax(0, var(--ds-definitions-term, calc(8 * var(--ds-unit)))) minmax(0, 1fr);\n margin: 0;\n padding: 0;\n color: var(--ds-text-color);\n font-family: var(--ds-typeface-regular);\n font-size: var(--ds-type-size-default);\n line-height: var(--ds-unit);\n letter-spacing: var(--ds-type-letterspacing-default);\n}\n\n.ds-definitions > div {\n display: contents;\n}\n\n.ds-definitions :is(dt, dd) {\n box-sizing: border-box;\n min-width: 0;\n margin: 0;\n padding-block: calc(var(--ds-unit) / 2);\n box-shadow: inset 0 -1px var(--ds-border-color);\n font: inherit;\n letter-spacing: inherit;\n line-height: var(--ds-unit);\n overflow-wrap: anywhere;\n}\n\n.ds-definitions dt {\n grid-column: 1;\n padding-inline-end: calc(var(--ds-unit) / 2);\n color: var(--ds-text-color-muted);\n}\n\n.ds-definitions dd {\n grid-column: 2;\n}\n\n@container (max-width: 479px) {\n .ds-definitions dt,\n .ds-definitions dd {\n grid-column: 1 / -1;\n }\n\n .ds-definitions dt {\n padding-block-end: 0;\n padding-inline-end: 0;\n box-shadow: none;\n }\n\n .ds-definitions dd {\n padding-block-start: 0;\n }\n}\n/*\n * A bento, as plain classes on native elements: tiles of different sizes\n * standing half a square (10px) apart, each a card (`.ds-card`, or any box)\n * that holds one thing. The `ds-bento` element draws the same.\n *\n * Flow (the default): columns that share the width (`--ds-bento-columns`,\n * three), a tile one column wide or more (`data-span`, or\n * `--ds-bento-span`) and one row high or more (`data-rows`, or\n * `--ds-bento-rows`); a row is as high as its tallest tile, at least\n * `--ds-bento-row` (ten squares by default). Below thirty squares of width\n * the bento is one column.\n *\n * Squares (`data-squares`): the bento is exactly `--ds-bento-columns` squares wide\n * and every tile is placed on whole squares (`data-place=\"x y w h\"`,\n * counted from 0). Tiles are placed a square apart, and a tile's surface\n * reaches a quarter square towards each tile beside it, so they stand half a\n * square apart while what they hold stays on the squares, and the bento's\n * own edges stay on the page's. `placeBento()` (0-face/bento.ts) reads the\n * places and sets the reach; the element does it itself.\n *\n * data-span=\"2\" a tile two columns wide (to 6)\n * data-rows=\"2\" a tile two rows high (to 6)\n * data-place=\"0 0 15 7\" a tile's square, width and height in squares\n *\n * Tokens: `--ds-bento-gap` (half a square), `--ds-bento-columns`,\n * `--ds-bento-row`, and on a tile `--ds-bento-span`, `--ds-bento-rows`.\n */\n\n.ds-bento {\n --ds-bento-gap: calc(var(--ds-unit) / 2);\n box-sizing: border-box;\n display: grid;\n grid-template-columns: repeat(var(--ds-bento-columns, 3), minmax(0, 1fr));\n grid-auto-rows: minmax(var(--ds-bento-row, calc(10 * var(--ds-unit))), auto);\n grid-auto-flow: row dense;\n gap: var(--ds-bento-gap);\n margin: 0;\n padding: 0;\n list-style: none;\n}\n.ds-bento[hidden] { display: none; }\n\n.ds-bento > * {\n --ds-card-width: auto;\n --ds-card-height: auto;\n box-sizing: border-box;\n min-width: 0;\n min-height: 0;\n grid-column: span var(--ds-bento-span, 1);\n grid-row: span var(--ds-bento-rows, 1);\n}\n.ds-bento > [data-span=\"2\"] { --ds-bento-span: 2; }\n.ds-bento > [data-span=\"3\"] { --ds-bento-span: 3; }\n.ds-bento > [data-span=\"4\"] { --ds-bento-span: 4; }\n.ds-bento > [data-span=\"5\"] { --ds-bento-span: 5; }\n.ds-bento > [data-span=\"6\"] { --ds-bento-span: 6; }\n.ds-bento > [data-rows=\"2\"] { --ds-bento-rows: 2; }\n.ds-bento > [data-rows=\"3\"] { --ds-bento-rows: 3; }\n.ds-bento > [data-rows=\"4\"] { --ds-bento-rows: 4; }\n.ds-bento > [data-rows=\"5\"] { --ds-bento-rows: 5; }\n.ds-bento > [data-rows=\"6\"] { --ds-bento-rows: 6; }\n\n@media (max-width: 600px) {\n .ds-bento:not([data-squares]) { grid-template-columns: minmax(0, 1fr); }\n .ds-bento:not([data-squares]) > * { grid-column: auto; }\n}\n\n/* Squares: every tile on whole squares, a square apart, its surface a quarter square nearer each neighbour. */\n.ds-bento[data-squares] {\n --ds-bento-reach: calc(var(--ds-unit) / 4);\n /* Exactly its squares wide: each column one square. */\n width: calc(var(--ds-bento-columns, 48) * var(--ds-unit));\n max-width: none;\n grid-template-columns: repeat(var(--ds-bento-columns, 48), var(--ds-unit));\n grid-auto-rows: var(--ds-unit);\n grid-auto-flow: row;\n gap: 0;\n}\n.ds-bento[data-squares] > * {\n --ds-bento-inset-top: calc(var(--ds-bento-reach) * var(--ds-bento-top, 0));\n --ds-bento-inset-end: calc(var(--ds-bento-reach) * var(--ds-bento-end, 0));\n --ds-bento-inset-bottom: calc(var(--ds-bento-reach) * var(--ds-bento-bottom, 0));\n --ds-bento-inset-start: calc(var(--ds-bento-reach) * var(--ds-bento-start, 0));\n grid-column: calc(var(--ds-bento-x, 0) + 1) / span var(--ds-bento-w, 4);\n grid-row: calc(var(--ds-bento-y, 0) + 1) / span var(--ds-bento-h, 4);\n margin: calc(-1 * var(--ds-bento-inset-top)) calc(-1 * var(--ds-bento-inset-end)) calc(-1 * var(--ds-bento-inset-bottom)) calc(-1 * var(--ds-bento-inset-start));\n}\n/* A card grows its own padding by the reach (card.css); any other tile is padded here, a square inside. */\n.ds-bento[data-squares] > :not(.ds-card, ds-card) {\n padding:\n calc(var(--ds-unit) + var(--ds-bento-inset-top))\n calc(var(--ds-unit) + var(--ds-bento-inset-end))\n calc(var(--ds-unit) + var(--ds-bento-inset-bottom))\n calc(var(--ds-unit) + var(--ds-bento-inset-start));\n}\n/*\n * A carousel, as plain classes on native elements.\n *\n * A carousel is a row of slides that snaps sideways, one slide to a stop,\n * with a row of controls one square high under it: optional previous and\n * next buttons and a dot for each slide. Slides are the track's width, or\n * whole squares wide, a whole number of squares apart (one by default). The\n * controls stand one square below the track, on the grid from its start.\n * The `ds-carousel` element draws the same parts, and\n * `0-face/carousel.ts` gives the native markup its behaviour.\n *\n * ds-carousel the region: track, controls, status;\n * `data-slides=\"auto\"` for slides of their\n * own width, `data-bleed` `end` or `both`,\n * `data-snap=\"none\"` to slide freely\n * ds-carousel__track the scroller; every child is a slide\n * ds-carousel__controls the row of buttons and dots\n * ds-carousel__previous, __next, icon buttons, on `.ds-button.ds-button--icon`\n * __pause\n * ds-carousel__status the polite announcement, kept out of sight\n *\n * The dots are `ds-progress--dots` from progress.css.\n *\n * A strip of slides of their own width can run on past its box to the\n * window's end edge, or to both edges, while its first slide keeps to the\n * box's start, so it lines up with the page's column; `--ds-carousel-before`\n * and `--ds-carousel-after` are the room to the edges, which the script\n * measures.\n *\n * Tokens: `--ds-carousel-slide` (a slide's width, the track's by default)\n * and `--ds-carousel-gap` (between slides, one square by default).\n */\n\n.ds-carousel {\n box-sizing: border-box;\n display: grid;\n grid-template-columns: minmax(0, 1fr);\n row-gap: var(--ds-unit);\n position: relative;\n min-width: 0;\n margin: 0;\n}\n\n.ds-carousel__track {\n box-sizing: border-box;\n display: grid;\n grid-auto-flow: column;\n grid-auto-columns: var(--ds-carousel-slide, 100%);\n column-gap: var(--ds-carousel-gap, var(--ds-unit));\n min-width: 0;\n margin: 0;\n padding: 0;\n list-style: none;\n overflow-x: auto;\n overflow-y: hidden;\n overscroll-behavior-x: contain;\n scroll-snap-type: x mandatory;\n scrollbar-width: none;\n}\n\n.ds-carousel__track::-webkit-scrollbar {\n display: none;\n}\n\n/* Slides of their own width, several in view. */\n.ds-carousel[data-slides=\"auto\"] > .ds-carousel__track {\n grid-auto-columns: max-content;\n}\n\n.ds-carousel[data-snap=\"none\"] > .ds-carousel__track {\n scroll-snap-type: none;\n}\n\n/* To the window's end edge: the track reaches out over the room after the\n box and keeps a gap at its end, so the last slide stops short of the edge. */\n.ds-carousel[data-bleed=\"end\"] > .ds-carousel__track {\n margin-inline-end: calc(-1 * var(--ds-carousel-after, 0px));\n padding-inline-end: var(--ds-carousel-gap, var(--ds-unit));\n}\n\n/* To both edges: the track reaches out both ways, and the first slide, and\n each one it stops at, still stands on the box's start. */\n.ds-carousel[data-bleed=\"both\"] > .ds-carousel__track {\n margin-inline: calc(-1 * var(--ds-carousel-before, 0px)) calc(-1 * var(--ds-carousel-after, 0px));\n padding-inline: var(--ds-carousel-before, 0px) var(--ds-carousel-gap, var(--ds-unit));\n scroll-padding-inline-start: var(--ds-carousel-before, 0px);\n}\n\n.ds-carousel__track:focus-visible {\n outline: 2px solid var(--ds-focus-ring);\n outline-offset: 1px;\n}\n\n.ds-carousel__track > * {\n box-sizing: border-box;\n min-width: 0;\n margin: 0;\n scroll-snap-align: start;\n}\n\n/* One slide to a stop; a strip of several in view may pass a few. */\n.ds-carousel:not([data-slides=\"auto\"]) > .ds-carousel__track > * {\n scroll-snap-stop: always;\n}\n\n.ds-carousel__controls {\n display: flex;\n align-items: center;\n height: var(--ds-row-height);\n min-width: 0;\n}\n\n/* The buttons take a one-square cell each, as the dots do. Two classes, so\n the button's own reset of its margin does not undo it. */\n.ds-carousel .ds-carousel__previous,\n.ds-carousel .ds-carousel__next,\n.ds-carousel .ds-carousel__pause {\n flex: none;\n margin: calc((var(--ds-unit) - var(--ds-control-height)) / 2);\n}\n\n/* Previous points back along the reading direction. */\n.ds-carousel:dir(rtl) :is(.ds-carousel__previous, .ds-carousel__next) > * {\n transform: scaleX(-1);\n}\n\n.ds-carousel__status {\n position: absolute;\n width: 1px;\n height: 1px;\n overflow: hidden;\n clip-path: inset(50%);\n white-space: nowrap;\n}\n/*\n * A card, as plain classes on native elements.\n *\n * A card holds one thing on a fill of its own: its name in the muted ink on\n * one square, a title in the display size on lines of a square and a half, writing,\n * and a picture of it (`ds-card__media`) a square below, which can run off\n * the card's foot and end edge and be cut there, never framed. Its size is\n * given in whole squares, its padding one square, its corners a card's\n * (`--ds-radius-card`). A card that opens something is one press target, an\n * `<a class=\"ds-card\" href>`: the pointer tints it, keyboard focus rings it\n * 2px inside and its picture rises a little. Ordinary writing still sits\n * straight on the paper; a card is for a thing shown among others, as in a\n * slide. The `ds-card` element draws the same parts.\n *\n * ds-card the card; `data-tone` names a palette colour\n * for its fill (the colour's pastel, dim in dark\n * mode, from palette.css, which one.css imports),\n * `ink` for the ink with the paper's words\n * ds-card--outlined a 1px line and no fill\n * ds-card__label its name, muted, on one square\n * ds-card__title the title, display size, a square and a half a line\n * ds-card__body writing, one square a line\n * ds-card__media the picture, a square below the words\n * ds-card__media--center standing in the card's middle\n * ds-card__media--bleed running on past the padding to the end edge\n *\n * Tokens: `--ds-card-width` and `--ds-card-height` (whole squares; the\n * content's size by default), `--ds-card-padding` (one square), and\n * `--ds-card-fill`, `--ds-card-ink` and `--ds-card-muted`.\n */\n\n.ds-card {\n --ds-card-fill: var(--ds-fill);\n --ds-card-ink: var(--ds-text-color);\n --ds-card-muted: var(--ds-text-color-muted);\n --ds-card-padding: var(--ds-unit);\n position: relative;\n box-sizing: border-box;\n display: flex;\n flex-direction: column;\n align-items: stretch;\n width: var(--ds-card-width, auto);\n height: var(--ds-card-height, auto);\n min-width: 0;\n margin: 0;\n /* In a squares bento the surface reaches a quarter square towards its neighbours (`--ds-bento-inset-*`, 0 elsewhere), and the padding grows by as much so what it holds stays on the squares. */\n padding:\n calc(var(--ds-card-padding) + var(--ds-bento-inset-top, 0px))\n calc(var(--ds-card-padding) + var(--ds-bento-inset-end, 0px))\n var(--ds-bento-inset-bottom, 0px)\n calc(var(--ds-card-padding) + var(--ds-bento-inset-start, 0px));\n overflow: hidden;\n border-radius: var(--ds-radius-card);\n background: var(--ds-card-fill);\n color: var(--ds-card-ink);\n font-family: var(--ds-typeface-regular);\n font-size: var(--ds-type-size-default);\n text-decoration: none;\n -webkit-tap-highlight-color: transparent;\n}\n\n.ds-card[hidden] {\n display: none;\n}\n\n.ds-card--outlined {\n --ds-card-fill: transparent;\n box-shadow: inset 0 0 0 1px var(--ds-border-color);\n}\n\n.ds-card[data-tone=\"apple-green\"] { --ds-card-fill: var(--one-apple-green-pastel); }\n.ds-card[data-tone=\"chartreuse\"] { --ds-card-fill: var(--one-chartreuse-pastel); }\n.ds-card[data-tone=\"every-green\"] { --ds-card-fill: var(--one-every-green-pastel); }\n.ds-card[data-tone=\"yellow\"] { --ds-card-fill: var(--one-yellow-pastel); }\n.ds-card[data-tone=\"orange\"] { --ds-card-fill: var(--one-orange-pastel); }\n.ds-card[data-tone=\"tuned-red\"] { --ds-card-fill: var(--one-tuned-red-pastel); }\n.ds-card[data-tone=\"pink\"] { --ds-card-fill: var(--one-pink-pastel); }\n.ds-card[data-tone=\"sharp-blue\"] { --ds-card-fill: var(--one-sharp-blue-pastel); }\n.ds-card[data-tone=\"winning-blue\"] { --ds-card-fill: var(--one-winning-blue-pastel); }\n.ds-card[data-tone=\"hysteric-blue\"] { --ds-card-fill: var(--one-hysteric-blue-pastel); }\n.ds-card[data-tone=\"purple\"] { --ds-card-fill: var(--one-purple-pastel); }\n.ds-card[data-tone=\"metal-green\"] { --ds-card-fill: var(--one-metal-green-pastel); }\n.ds-card[data-tone=\"drip-yellow\"] { --ds-card-fill: var(--one-drip-yellow-pastel); }\n.ds-card[data-tone=\"sand\"] { --ds-card-fill: var(--one-sand-pastel); }\n.ds-card[data-tone=\"old-gold\"] { --ds-card-fill: var(--one-old-gold-pastel); }\n.ds-card[data-tone=\"red-for-blood\"] { --ds-card-fill: var(--one-red-for-blood-pastel); }\n.ds-card[data-tone=\"dark-red-variant\"] { --ds-card-fill: var(--one-dark-red-variant-pastel); }\n.ds-card[data-tone=\"signal-red\"] { --ds-card-fill: var(--one-signal-red-pastel); }\n.ds-card[data-tone=\"ink\"] {\n --ds-card-fill: var(--ds-black);\n --ds-card-ink: var(--ds-white);\n --ds-card-muted: color-mix(in srgb, var(--ds-white) 60%, transparent);\n box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--ds-white) 8%, transparent);\n}\n\n/* Words: each line on the lower sixteen of its square. They keep their room\n in a card of a set height; only the picture is cut at the foot. */\n.ds-card__label,\n.ds-card__title,\n.ds-card__body {\n flex: none;\n}\n\n.ds-card__label {\n margin: 0;\n padding-top: calc(4px * var(--ds-sf, 1));\n color: var(--ds-card-muted);\n font: inherit;\n line-height: var(--ds-type-lineheight-default, calc(16px * var(--ds-sf, 1)));\n}\n\n.ds-card__title {\n margin: 0;\n color: var(--ds-card-ink);\n font-family: var(--ds-typeface-medium);\n font-size: var(--ds-type-size-display);\n font-weight: var(--ds-type-weight-bold);\n /* A title that wraps keeps its lines together: a square and a half each. */\n line-height: calc(1.5 * var(--ds-unit));\n letter-spacing: calc(var(--ds-display-text-tracking, -0.4px) * var(--ds-sf, 1));\n text-wrap: balance;\n}\n\n.ds-card__body {\n margin: 0;\n line-height: var(--ds-unit);\n}\n\n.ds-card__media {\n display: flex;\n flex: none;\n align-items: flex-start;\n justify-content: flex-start;\n min-width: 0;\n margin-top: var(--ds-unit);\n}\n\n.ds-card__media--center {\n justify-content: center;\n margin-inline: calc(-1 * var(--ds-card-padding));\n}\n\n.ds-card__media--bleed {\n margin-inline-end: calc(-1 * var(--ds-card-padding));\n}\n\n.ds-card__media > * {\n flex: none;\n}\n\n/* A card that opens something. */\na.ds-card,\n.ds-card[data-interactive] {\n cursor: pointer;\n}\n\na.ds-card::after,\n.ds-card[data-interactive]::after {\n content: \"\";\n position: absolute;\n inset: 0;\n border-radius: inherit;\n background: transparent;\n pointer-events: none;\n}\n\na.ds-card:focus-visible,\n.ds-card[data-interactive]:focus-visible {\n outline: 2px solid var(--ds-focus-ring);\n outline-offset: -2px;\n}\n\n@media (hover: hover) {\n a.ds-card:hover::after,\n .ds-card[data-interactive]:hover::after {\n background: color-mix(in srgb, var(--ds-card-ink) 4%, transparent);\n }\n}\n\na.ds-card:active::after,\n.ds-card[data-interactive]:active::after {\n background: color-mix(in srgb, var(--ds-card-ink) 8%, transparent);\n}\n\n@media (hover: hover) and (prefers-reduced-motion: no-preference) {\n a.ds-card > .ds-card__media,\n .ds-card[data-interactive] > .ds-card__media {\n transition: transform 240ms cubic-bezier(0.23, 1, 0.32, 1);\n }\n\n a.ds-card:hover > .ds-card__media,\n .ds-card[data-interactive]:hover > .ds-card__media {\n transform: translateY(calc(-0.25 * var(--ds-unit)));\n }\n}\n/*\n * Figures, as plain classes on native elements: a stat and a group of stats.\n * The `ds-stat` element draws the same parts; controls.css imports this\n * file. A value against its range, steps and page dots are `progress.css`.\n *\n * Everything sits on the paper with no box, every line is one square and\n * widths come in whole squares. Colour is kept for a state: the danger colour\n * for a figure that is over.\n *\n * A stat: a label, a figure and a line for its change or caption.\n *\n * ds-stat the block, as wide as its column\n * ds-stat__label one line, muted; an icon may lead it on its own square\n * ds-stat__icon the square an icon from the library stands on\n * ds-stat__figure the figure in tabular numerals, 20 on two squares\n * ds-stat__digit one digit in a cell of one width, for a face without tabular numerals\n * ds-stat__caption one line, muted, under the figure\n * ds-stat__change the change at the start of the caption, in the text colour;\n * --danger or --warning where the page knows which way is bad\n * ds-stat--danger, --warning the figure in that colour\n * ds-stats a group of stats on whole squares: columns eight\n * squares wide, one square between them and between rows\n *\n * Tokens: `--ds-stat-size` (the figure's type size before the scale, 20px)\n * and `--ds-stat-lines` (the squares its line takes, 2), `--ds-stat-typeface`\n * (the medium face), `--ds-stat-digit` (a digit cell's width, 1ch),\n * `--ds-stat-change-color`, and `--ds-stats-width` (a column's width in\n * squares, 8).\n *\n */\n\n/* ---- Stat ------------------------------------------------------------ */\n\n.ds-stat {\n box-sizing: border-box;\n display: flex;\n flex-direction: column;\n align-items: flex-start;\n min-width: 0;\n margin: 0;\n color: var(--ds-text-color);\n font-family: var(--ds-typeface-regular);\n font-feature-settings: var(--ds-font-features);\n font-size: var(--ds-type-size-default);\n font-weight: var(--ds-type-weight-default);\n line-height: var(--ds-unit);\n letter-spacing: var(--ds-type-letterspacing-default);\n text-transform: none;\n}\n\n.ds-stat__label,\n.ds-stat__figure,\n.ds-stat__caption {\n box-sizing: border-box;\n max-width: 100%;\n margin: 0;\n font: inherit;\n letter-spacing: inherit;\n}\n\n.ds-stat__label,\n.ds-stat__caption {\n display: flex;\n align-items: flex-start;\n min-height: var(--ds-unit);\n color: var(--ds-text-color-muted);\n overflow-wrap: anywhere;\n}\n\n.ds-stat__icon {\n display: inline-flex;\n flex: none;\n align-items: center;\n justify-content: center;\n width: var(--ds-unit);\n height: var(--ds-unit);\n}\n\n.ds-stat__figure {\n display: block;\n overflow: hidden;\n font-family: var(--ds-stat-typeface, var(--ds-typeface-medium));\n font-size: calc(var(--ds-stat-size, var(--ds-display-text-size, 20px)) * var(--ds-sf, 1));\n font-weight: var(--ds-type-weight-bold);\n font-variant-numeric: tabular-nums;\n line-height: calc(var(--ds-stat-lines, 2) * var(--ds-unit));\n min-height: calc(var(--ds-stat-lines, 2) * var(--ds-unit));\n letter-spacing: calc(var(--ds-display-text-tracking, -0.4px) * var(--ds-sf, 1));\n white-space: nowrap;\n text-overflow: ellipsis;\n}\n\n.ds-stat__digit {\n display: inline-block;\n width: var(--ds-stat-digit, 1ch);\n text-align: center;\n}\n\n.ds-stat--danger .ds-stat__figure {\n color: var(--ds-danger-color);\n}\n\n.ds-stat--warning .ds-stat__figure {\n color: var(--ds-warning-color);\n}\n\n.ds-stat__change {\n display: inline-flex;\n flex: none;\n align-items: center;\n height: var(--ds-unit);\n margin-inline-end: calc(4px * var(--ds-sf, 1));\n color: var(--ds-stat-change-color, var(--ds-text-color));\n font-variant-numeric: tabular-nums;\n white-space: nowrap;\n}\n\n.ds-stat__change--danger {\n --ds-stat-change-color: var(--ds-danger-color);\n}\n\n.ds-stat__change--warning {\n --ds-stat-change-color: var(--ds-warning-color);\n}\n\n.ds-stats {\n box-sizing: border-box;\n display: grid;\n grid-template-columns: repeat(auto-fill, min(100%, calc(var(--ds-stats-width, 8) * var(--ds-unit))));\n gap: var(--ds-unit);\n margin: 0;\n padding: 0;\n list-style: none;\n}\n\n.ds-stats > li {\n min-width: 0;\n margin: 0;\n}\n/*\n * Progress, as plain classes on native elements: a value against its range,\n * a sequence of steps, or a dot for each page. The `ds-progress` element\n * draws the same parts; controls.css imports this file.\n *\n * Everything sits on the paper with no box, every line is one square and\n * widths come in whole squares. Colour is kept for a state: the danger colour\n * for a value that is over or a step that failed, the ink for the current\n * step and the current dot.\n *\n * A value against its range, one square high (HTML's <progress>):\n *\n * ds-progress the row; role=\"meter\" with aria-valuenow, -min, -max and -valuetext\n * ds-progress__fill the bar, half a square high, drawn to --ds-progress-value (0 to 1)\n * ds-progress--squares the range in squares instead, each one square\n * ds-progress__square one square of the range; --on when it is filled\n * ds-progress--over past the end: filled whole in the danger colour\n *\n * Tokens: `--ds-progress-value`, `--ds-progress-color` (the ink by default)\n * and `--ds-progress-track` (the grey fill).\n *\n * A sequence of steps, one square high, each step on whole squares:\n *\n * ds-progress--steps with ds-progress, on an <ol>; the steps on one row, joined by a line\n * ds-progress--vertical one step to a row, each with room for its body under it\n * ds-progress__step an <li>; aria-current=\"step\" on the current one\n * ds-progress__step--done, --current, --failed states; upcoming without one\n * ds-progress__link a step that goes somewhere: an <a href> around its mark and label\n * ds-progress__mark the number (or the done or failed icon), one control high\n * ds-progress__label the step's name on one line\n * ds-progress__state the state in words for assistive technology, hidden (\"Done\")\n * ds-progress__body what belongs under a step in a vertical sequence\n *\n * A dot for each page, one square each:\n *\n * ds-progress--dots with ds-progress, a group of dots (role=\"group\")\n * ds-progress__dot a button; `data-state` is `past`, `current` (with\n * `aria-current=\"true\"`), `next`, `future`, or `end` for a\n * last dot marked as an end\n *\n * Tokens: the dot colours `--ds-progress-dot-past` and `-future` (the muted\n * text colour by default), `-current`, `-next` and `-end` (the text colour),\n * set on the dots or any element around them. Past, current and next dots are\n * filled; future dots and the end marker are rings.\n */\n\n/* ---- A value against its range: the bar, or the range in squares ---- */\n\n.ds-progress {\n box-sizing: border-box;\n position: relative;\n display: block;\n width: 100%;\n height: var(--ds-unit);\n margin: 0;\n}\n\n/* The range and its bar are a band half a square high across the middle of\n the row, as a chart's ratio is drawn. */\n.ds-progress:not(.ds-progress--squares, .ds-progress--steps, .ds-progress--dots)::before,\n.ds-progress__fill {\n position: absolute;\n inset-inline: 0;\n top: calc(var(--ds-unit) / 4);\n height: calc(var(--ds-unit) / 2);\n}\n\n.ds-progress:not(.ds-progress--squares, .ds-progress--steps, .ds-progress--dots)::before {\n content: \"\";\n background: var(--ds-progress-track, var(--ds-fill));\n}\n\n.ds-progress__fill {\n display: block;\n background: var(--ds-progress-color, var(--ds-text-color));\n transform: scaleX(var(--ds-progress-value, 0));\n transform-origin: left center;\n transition: transform 0.4s cubic-bezier(0.2, 0.8, 0.2, 1);\n}\n\n.ds-progress__fill:dir(rtl) {\n transform-origin: right center;\n}\n\n.ds-progress--over .ds-progress__fill {\n background: var(--ds-danger-color);\n transform: none;\n}\n\n.ds-progress--squares {\n display: flex;\n width: max-content;\n max-width: 100%;\n overflow: hidden;\n}\n\n.ds-progress__square {\n flex: none;\n width: calc(var(--ds-unit) - 1px);\n height: calc(var(--ds-unit) - 1px);\n margin-inline-end: 1px;\n background: var(--ds-progress-track, var(--ds-fill));\n}\n\n.ds-progress__square--on {\n background: var(--ds-progress-color, var(--ds-text-color));\n}\n\n.ds-progress--over .ds-progress__square {\n background: var(--ds-danger-color);\n}\n\n@media (prefers-reduced-motion: reduce) {\n .ds-progress__fill {\n transition: none;\n }\n}\n\n/* ---- A sequence of steps --------------------------------------------- */\n\n.ds-progress--steps {\n box-sizing: border-box;\n position: static;\n display: flex;\n width: auto;\n height: auto;\n flex-wrap: wrap;\n align-items: flex-start;\n min-width: 0;\n margin: 0;\n padding: 0;\n list-style: none;\n color: var(--ds-text-color);\n font-family: var(--ds-typeface-regular);\n font-feature-settings: var(--ds-font-features);\n font-size: var(--ds-type-size-default);\n font-weight: var(--ds-type-weight-default);\n line-height: var(--ds-unit);\n letter-spacing: var(--ds-type-letterspacing-default);\n text-transform: none;\n}\n\n/* Each step rounds its width up to whole squares where the browser can size\n to content in calc; elsewhere it hugs its words. */\n.ds-progress__step {\n --ds-progress-mark: transparent;\n --ds-progress-mark-ink: var(--ds-text-color-muted);\n --ds-progress-mark-line: var(--ds-border-color);\n box-sizing: border-box;\n position: relative;\n display: flex;\n align-items: flex-start;\n min-width: 0;\n max-width: 100%;\n width: max-content;\n width: calc-size(max-content, round(up, size, var(--ds-unit)));\n min-height: var(--ds-unit);\n margin: 0;\n color: var(--ds-text-color-muted);\n}\n\n/* A line joins a step to the next: at least one square, across whatever the\n step's rounding leaves, a quarter of a square short of each end. */\n.ds-progress__step:not(:last-child)::after {\n content: \"\";\n flex: 1 0 var(--ds-unit);\n height: var(--ds-unit);\n background: linear-gradient(var(--ds-border-color), var(--ds-border-color)) center / calc(100% - var(--ds-unit) / 2) 1px no-repeat;\n}\n\n.ds-progress__step--done {\n --ds-progress-mark: var(--ds-fill);\n --ds-progress-mark-ink: var(--ds-text-color);\n --ds-progress-mark-line: transparent;\n color: var(--ds-text-color);\n}\n\n.ds-progress__step--current {\n --ds-progress-mark: var(--ds-text-color);\n --ds-progress-mark-ink: var(--ds-paper);\n --ds-progress-mark-line: transparent;\n color: var(--ds-text-color);\n}\n\n.ds-progress__step--failed {\n --ds-progress-mark: var(--ds-danger-color);\n --ds-progress-mark-ink: light-dark(var(--ds-white), var(--ds-black));\n --ds-progress-mark-line: transparent;\n color: var(--ds-danger-color);\n}\n\n.ds-progress__link {\n display: flex;\n align-items: flex-start;\n min-width: 0;\n color: inherit;\n text-decoration: none;\n border-radius: var(--ds-radius);\n}\n\n.ds-progress__link:hover .ds-progress__label {\n text-decoration: underline;\n text-decoration-thickness: 1px;\n text-underline-offset: calc(3px * var(--ds-sf, 1));\n}\n\n.ds-progress__link:focus-visible {\n outline: 2px solid var(--ds-focus-ring);\n outline-offset: -2px;\n}\n\n.ds-progress__mark {\n box-sizing: border-box;\n display: flex;\n flex: none;\n align-items: center;\n justify-content: center;\n width: var(--ds-control-height);\n height: var(--ds-control-height);\n margin: calc((var(--ds-unit) - var(--ds-control-height)) / 2);\n overflow: hidden;\n background: var(--ds-progress-mark);\n box-shadow: inset 0 0 0 1px var(--ds-progress-mark-line);\n color: var(--ds-progress-mark-ink);\n --ds-icon-color: var(--ds-progress-mark-ink);\n font-family: var(--ds-typeface-medium);\n font-size: var(--ds-type-size-small);\n font-weight: var(--ds-type-weight-bold);\n font-variant-numeric: tabular-nums;\n line-height: var(--ds-control-height);\n letter-spacing: 0;\n}\n\n.ds-progress__label {\n min-width: 0;\n padding-inline-end: calc(4px * var(--ds-sf, 1));\n overflow: hidden;\n white-space: nowrap;\n text-overflow: ellipsis;\n}\n\n.ds-progress__step--current .ds-progress__label {\n font-family: var(--ds-typeface-medium);\n font-weight: var(--ds-type-weight-bold);\n}\n\n.ds-progress__state {\n position: absolute;\n width: 1px;\n height: 1px;\n overflow: hidden;\n clip-path: inset(50%);\n white-space: nowrap;\n}\n\n.ds-progress--vertical {\n flex-direction: column;\n flex-wrap: nowrap;\n}\n\n.ds-progress--vertical .ds-progress__step {\n flex-wrap: wrap;\n width: 100%;\n}\n\n.ds-progress--vertical .ds-progress__step::after {\n content: none;\n}\n\n/* Its content stands in a column, so an inline element in it (text drawn by\n an element, say) takes its own lines rather than a line box's descent. */\n.ds-progress__body {\n box-sizing: border-box;\n display: flex;\n flex-direction: column;\n flex: 1 0 100%;\n min-width: 0;\n padding-inline-start: var(--ds-unit);\n color: var(--ds-text-color);\n}\n\n/* ---- A dot for each page ------------------------------------------- */\n\n.ds-progress--dots {\n position: static;\n display: inline-flex;\n width: auto;\n flex: none;\n align-items: center;\n height: var(--ds-row-height);\n margin: 0;\n padding: 0;\n}\n\n.ds-progress__dot {\n --ds-progress-dot-color: var(--ds-progress-dot-future, var(--ds-text-color-muted));\n appearance: none;\n box-sizing: border-box;\n display: inline-flex;\n flex: none;\n align-items: center;\n justify-content: center;\n width: var(--ds-unit);\n height: var(--ds-unit);\n margin: 0;\n padding: 0;\n border: 0;\n border-radius: var(--ds-radius);\n background: transparent;\n color: inherit;\n cursor: pointer;\n -webkit-tap-highlight-color: transparent;\n}\n\n/* The dot itself: 4px, scaled with the surface, a fifth of the square. */\n.ds-progress__dot::before {\n content: \"\";\n box-sizing: border-box;\n width: calc(4px * var(--ds-sf, 1));\n height: calc(4px * var(--ds-sf, 1));\n border-radius: 50%;\n background: transparent;\n box-shadow: inset 0 0 0 1px var(--ds-progress-dot-color);\n transition: transform 160ms ease-out;\n}\n\n.ds-progress__dot[data-state=\"past\"] { --ds-progress-dot-color: var(--ds-progress-dot-past, var(--ds-text-color-muted)); }\n.ds-progress__dot[data-state=\"next\"] { --ds-progress-dot-color: var(--ds-progress-dot-next, var(--ds-text-color)); }\n.ds-progress__dot[data-state=\"end\"] { --ds-progress-dot-color: var(--ds-progress-dot-end, var(--ds-text-color)); }\n.ds-progress__dot[aria-current=\"true\"] { --ds-progress-dot-color: var(--ds-progress-dot-current, var(--ds-text-color)); }\n\n.ds-progress__dot:is([data-state=\"past\"], [data-state=\"next\"], [aria-current=\"true\"])::before {\n background: var(--ds-progress-dot-color);\n}\n\n/* The current dot is half again as large. */\n.ds-progress__dot[aria-current=\"true\"]::before {\n transform: scale(1.5);\n}\n\n.ds-progress__dot:hover:not([aria-current=\"true\"])::before {\n transform: scale(1.25);\n}\n\n.ds-progress__dot:focus-visible {\n outline: 2px solid var(--ds-focus-ring);\n outline-offset: -2px;\n}\n\n@media (prefers-reduced-motion: reduce) {\n .ds-progress__dot::before {\n transition: none;\n }\n}\n/*\n * Rows, as plain classes on native elements: the `ds-row` and `ds-sidebar`\n * elements' look without the elements.\n *\n * A row is one square high, and what it holds stands on the lower sixteen of\n * the square with the spare four above, as Ezo sets every row: a line of\n * words on a 16px line box, a 16px icon and a 16px control all end on the\n * row's bottom line, so the capitals (7px below the top line, baseline 3px\n * above the next) are centred on an icon beside them. On an `<a href>` or a\n * `<button>` the whole row is one press target, a row, a tile or a card: the pointer over it, the\n * press and the focus ring cover the row, and its content keeps the row's\n * layout. A row that also holds controls of its own (a quick action, a link\n * in another cell) is any element, a `<li>`, a `<div>` or a `<tr>`, with one\n * `ds-row__target` inside: that link or button takes the press anywhere on\n * the row, and every other control inside stays separately pressable.\n *\n * ds-row a row one square high; a press target on <a> or <button>\n * ds-row__target the row's press target, when the row holds other controls\n * ds-row--auto as high as its content, at least one square\n * ds-row--stacked the content stacked, each line one square (a tile, a card)\n * ds-row--nav a navigation row: the sidebar's two-pixel corners\n * aria-current=\"page\" the destination being shown, filled and in the medium weight\n * aria-disabled=\"true\" or `disabled` on a button: dimmed, not pressable\n *\n * A sidebar of nested things (the `ds-sidebar tree` element without Lit) is a\n * `role=\"tree\"` list of `role=\"treeitem\"` rows, flat, each with its\n * `aria-level`, one square further in per level. `0-face/sidebar.ts`\n * (`connectSidebar`) gives it the keyboard of the tree pattern.\n *\n * ds-sidebar the tree (`role=\"tree\"`)\n * ds-sidebar__item a row (`role=\"treeitem\"`, `aria-level`, `aria-expanded` on a parent, `aria-selected`)\n * ds-sidebar__disclosure the arrow on its own square, turned down when the row is open; empty on a leaf\n * ds-sidebar__label the words, cut short with an ellipsis\n * ds-sidebar__meta small muted words at the row's end\n *\n * An icon (`.ds-icon`) in a tree row takes a square of its own. Tokens:\n * `--ds-row-padding` (the words' distance from the row's edges, 4px),\n * `--ds-row-fill-hover`, `--ds-row-fill-press`, `--ds-row-fill-current` and\n * `--ds-row-current-weight` (component-tokens.css, shared with the\n * element), `--ds-sidebar-disclosure` (the arrow's drawing, the library's\n * `right` icon) and `--ds-sidebar-indent` (a row's depth in squares, read\n * from `aria-level` up to twelve levels).\n */\n\n:where(.ds-row):not(tr) {\n box-sizing: border-box;\n display: flex;\n flex-direction: row;\n align-items: flex-end;\n gap: calc(4px * var(--ds-sf));\n min-width: 0;\n height: var(--ds-row-height);\n margin: 0;\n line-height: var(--ds-type-lineheight-default);\n}\n\n:where(.ds-row--auto):not(tr) {\n height: auto;\n min-height: var(--ds-row-height);\n}\n\n:where(.ds-row--stacked):not(tr) {\n flex-direction: column;\n align-items: flex-start;\n justify-content: flex-start;\n gap: 0;\n height: auto;\n}\n\n/* The press target: the row itself, or the one target inside it. */\na.ds-row,\nbutton.ds-row,\n.ds-row__target {\n appearance: none;\n box-sizing: border-box;\n margin: 0;\n border: 0;\n background: none;\n color: inherit;\n font: inherit;\n letter-spacing: inherit;\n text-align: start;\n text-decoration: none;\n text-transform: none;\n cursor: pointer;\n outline: none;\n -webkit-tap-highlight-color: transparent;\n}\n\n/* The font inherited above would bring the page's line into the row: the words go back on the\n sixteen, as every row's (a stacked tile keeps its square lines below). */\na.ds-row,\nbutton.ds-row {\n position: relative;\n width: 100%;\n line-height: var(--ds-type-lineheight-default);\n padding: 0 var(--ds-row-padding, calc(4px * var(--ds-sf)));\n border-radius: var(--ds-row-radius, 0);\n}\n\n.ds-row__target {\n padding: 0;\n}\n\n/* Each line of a tile one square, over the inherited font of a native link or button:\n a tile's lines wrap, so they stay on whole squares rather than the sixteen. */\n.ds-row.ds-row--stacked {\n line-height: var(--ds-row-height);\n}\n\n/* A row with a target inside: the target's layers cover the row. */\n.ds-row:has(.ds-row__target) {\n position: relative;\n isolation: isolate;\n}\n:where(.ds-row:has(.ds-row__target)):not(tr) {\n padding-inline: var(--ds-row-padding, calc(4px * var(--ds-sf)));\n}\n.ds-row__target::before,\n.ds-row__target::after {\n content: \"\";\n position: absolute;\n inset: 0;\n border-radius: var(--ds-row-radius, 0);\n}\n.ds-row__target::before { z-index: 1; }\n.ds-row__target::after { z-index: -1; }\n.ds-row:has(.ds-row__target) :where(a[href], button, input, select, textarea, label, summary, [tabindex]):not(.ds-row__target) {\n position: relative;\n z-index: 2;\n}\n\n/*\n * The pointer, the press, the current destination and the focus ring are one layer under the\n * row's content (Joachim, 19 October 2026). On a one-square row it is a square high and sits two\n * pixels around what the row holds: from two above the lower sixteen to two below the row's foot,\n * and two past the content at each side, its corners the icon tiles' 4px and those two more, so a\n * 16px icon stands in it with two all round. It is drawn over the row, never moving its words or\n * icons off the grid. An open row (`data-open`) wears the same layer. A taller row (a stacked\n * tile, `auto`) is filled whole.\n * Tokens: `--ds-row-fill-radius` (6px), `--ds-row-fill-overhang` (2px).\n */\na.ds-row,\nbutton.ds-row {\n isolation: isolate;\n}\na.ds-row::after,\nbutton.ds-row::after {\n content: \"\";\n position: absolute;\n z-index: -1;\n pointer-events: none;\n}\na.ds-row::after,\nbutton.ds-row::after,\n.ds-row__target::after {\n --ds-row-overhang: var(--ds-row-fill-overhang, calc(2px * var(--ds-sf)));\n inset:\n calc(var(--ds-row-height) - var(--ds-control-height) - var(--ds-row-overhang))\n calc(var(--ds-row-padding, calc(4px * var(--ds-sf))) - var(--ds-row-overhang))\n calc(0px - var(--ds-row-overhang));\n border-radius: var(--ds-row-radius, var(--ds-row-fill-radius, calc(6px * var(--ds-sf))));\n}\n:is(a, button).ds-row:is(.ds-row--stacked, .ds-row--auto)::after,\n:is(.ds-row--stacked, .ds-row--auto) .ds-row__target::after {\n inset: 0;\n}\na.ds-row[href]:hover::after,\nbutton.ds-row:hover:not(:disabled)::after,\n.ds-row__target:is(a[href], button:not(:disabled)):hover::after {\n background: var(--ds-row-fill-hover, var(--ds-fill));\n}\na.ds-row[href]:active::after,\nbutton.ds-row:active:not(:disabled)::after,\n.ds-row__target:is(a[href], button:not(:disabled)):active::after {\n background: var(--ds-row-fill-press, var(--ds-fill-hover));\n}\n.ds-row:is(a, button)[aria-current]:not([aria-current=\"false\"])::after,\n.ds-row__target[aria-current]:not([aria-current=\"false\"])::after {\n background: var(--ds-row-fill-current, var(--ds-fill-hover));\n}\n.ds-row:is(a, button)[aria-current]:not([aria-current=\"false\"]),\n.ds-row:has(.ds-row__target[aria-current]:not([aria-current=\"false\"])) {\n --ds-type-weight-default: var(--ds-row-current-weight, 500);\n font-weight: var(--ds-row-current-weight, 500);\n}\na.ds-row:focus-visible::after,\nbutton.ds-row:focus-visible::after,\n.ds-row__target:focus-visible::after {\n outline: 2px solid var(--ds-focus-ring);\n outline-offset: -2px;\n}\na.ds-row:not([href]),\na.ds-row[aria-disabled=\"true\"],\nbutton.ds-row:disabled,\nbutton.ds-row[aria-disabled=\"true\"],\n.ds-row:has(.ds-row__target:is(:disabled, [aria-disabled=\"true\"], a:not([href]))) {\n cursor: default;\n opacity: 0.5;\n}\n.ds-row__target:is(:disabled, [aria-disabled=\"true\"], a:not([href])) {\n cursor: default;\n}\na.ds-row[aria-disabled=\"true\"]:hover::after,\nbutton.ds-row[aria-disabled=\"true\"]:hover::after {\n background: none;\n}\n\n.ds-row--nav {\n --ds-row-radius: calc(2px * var(--ds-sf));\n}\n\n/* A sidebar of nested things: the tree. */\n\n.ds-sidebar {\n box-sizing: border-box;\n display: flex;\n flex-direction: column;\n min-width: 0;\n margin: 0;\n padding: 0;\n list-style: none;\n color: var(--ds-text-color);\n font-family: var(--ds-typeface-regular);\n font-feature-settings: var(--ds-font-features);\n font-size: var(--ds-type-size-default);\n font-weight: var(--ds-type-weight-default);\n line-height: var(--ds-type-lineheight-default);\n letter-spacing: var(--ds-type-letterspacing-default);\n}\n\n.ds-sidebar__item {\n box-sizing: border-box;\n display: flex;\n align-items: flex-end;\n height: var(--ds-row-height);\n min-width: 0;\n margin: 0;\n padding-block: 0;\n padding-inline: calc(var(--ds-sidebar-indent, 0) * var(--ds-unit)) var(--ds-row-padding, calc(4px * var(--ds-sf)));\n white-space: nowrap;\n cursor: pointer;\n user-select: none;\n outline: none;\n -webkit-tap-highlight-color: transparent;\n}\n.ds-sidebar__item[hidden] { display: none; }\n.ds-sidebar__item[aria-level=\"2\"] { --ds-sidebar-indent: 1; }\n.ds-sidebar__item[aria-level=\"3\"] { --ds-sidebar-indent: 2; }\n.ds-sidebar__item[aria-level=\"4\"] { --ds-sidebar-indent: 3; }\n.ds-sidebar__item[aria-level=\"5\"] { --ds-sidebar-indent: 4; }\n.ds-sidebar__item[aria-level=\"6\"] { --ds-sidebar-indent: 5; }\n.ds-sidebar__item[aria-level=\"7\"] { --ds-sidebar-indent: 6; }\n.ds-sidebar__item[aria-level=\"8\"] { --ds-sidebar-indent: 7; }\n.ds-sidebar__item[aria-level=\"9\"] { --ds-sidebar-indent: 8; }\n.ds-sidebar__item[aria-level=\"10\"] { --ds-sidebar-indent: 9; }\n.ds-sidebar__item[aria-level=\"11\"] { --ds-sidebar-indent: 10; }\n.ds-sidebar__item[aria-level=\"12\"] { --ds-sidebar-indent: 11; }\n.ds-sidebar__item:hover:not([aria-disabled=\"true\"]) { background: var(--ds-row-fill-hover, var(--ds-fill)); }\n.ds-sidebar__item:active:not([aria-disabled=\"true\"]) { background: var(--ds-row-fill-press, var(--ds-fill-hover)); }\n.ds-sidebar__item[aria-selected=\"true\"] {\n --ds-type-weight-default: var(--ds-row-current-weight, 500);\n background: var(--ds-row-fill-current, var(--ds-fill-hover));\n font-weight: var(--ds-row-current-weight, 500);\n}\n.ds-sidebar__item:focus-visible {\n outline: 2px solid var(--ds-focus-ring);\n outline-offset: -2px;\n}\n.ds-sidebar__item[aria-disabled=\"true\"] {\n cursor: default;\n opacity: 0.5;\n}\n\n/* The arrow and an icon each stand on a whole square, drawn on the row's sixteen (two\n pixels below the square's middle); a leaf keeps the arrow's square empty. */\n.ds-sidebar__disclosure,\n.ds-sidebar__item > .ds-icon {\n flex: 0 0 var(--ds-unit);\n width: var(--ds-unit);\n height: var(--ds-unit);\n -webkit-mask-size: var(--ds-icon-box, calc(14px * var(--ds-sf)));\n mask-size: var(--ds-icon-box, calc(14px * var(--ds-sf)));\n -webkit-mask-position: center calc(50% + 2px * var(--ds-sf));\n mask-position: center calc(50% + 2px * var(--ds-sf));\n}\n.ds-sidebar__disclosure {\n --ds-icon-box: calc(14px * var(--ds-sf));\n display: inline-block;\n color: var(--ds-text-color-muted);\n background-color: currentColor;\n -webkit-mask: var(--ds-sidebar-disclosure, url(\"data:image/svg+xml,%3Csvg xmlns='http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg' viewBox='0 0 16 16'%3E%3Cpath d='M13.1566 8.60594H0V9.61651L13.1562 9.61791L10.249 12.5251L10.9558 13.219L15.0636 9.11123L10.9524 5L10.245 5.70734L13.1566 8.60594Z'/%3E%3C/svg%3E\")) center calc(50% + 2px * var(--ds-sf)) / var(--ds-icon-box) no-repeat;\n mask: var(--ds-sidebar-disclosure, url(\"data:image/svg+xml,%3Csvg xmlns='http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg' viewBox='0 0 16 16'%3E%3Cpath d='M13.1566 8.60594H0V9.61651L13.1562 9.61791L10.249 12.5251L10.9558 13.219L15.0636 9.11123L10.9524 5L10.245 5.70734L13.1566 8.60594Z'/%3E%3C/svg%3E\")) center calc(50% + 2px * var(--ds-sf)) / var(--ds-icon-box) no-repeat;\n transform: rotate(0deg);\n transition: transform 120ms ease-out;\n}\n.ds-sidebar__item:not([aria-expanded]) > .ds-sidebar__disclosure {\n visibility: hidden;\n}\n.ds-sidebar__item[aria-expanded=\"true\"] > .ds-sidebar__disclosure {\n transform: rotate(90deg);\n}\n.ds-sidebar__label {\n flex: 1 1 auto;\n min-width: 0;\n padding-inline-start: calc(4px * var(--ds-sf));\n overflow: hidden;\n text-overflow: ellipsis;\n}\n.ds-sidebar__meta {\n flex: none;\n padding-inline-start: calc(4px * var(--ds-sf));\n color: var(--ds-text-color-muted);\n font-size: var(--ds-type-size-small);\n font-variant-numeric: tabular-nums;\n}\n\n@media (prefers-reduced-motion: reduce) {\n .ds-sidebar__disclosure { transition: none; }\n}\n\n@media (forced-colors: active) {\n .ds-row:is(a, button)[aria-current]:not([aria-current=\"false\"]),\n .ds-row__target[aria-current]:not([aria-current=\"false\"])::after,\n .ds-sidebar__item[aria-selected=\"true\"] {\n outline: 1px solid Highlight;\n outline-offset: -1px;\n }\n .ds-sidebar__disclosure {\n background-color: CanvasText;\n }\n}\n\n/* A controlled detail view: the caller marks its open row, and clears it on close.\n Navigation's current state and the text weight remain independent. */\n.ds-row[data-open]:not([data-open=\"false\"]) {\n position: relative;\n isolation: isolate;\n}\n.ds-row[data-open]:not([data-open=\"false\"])::after {\n content: \"\";\n position: absolute;\n z-index: -1;\n pointer-events: none;\n --ds-row-overhang: var(--ds-row-fill-overhang, calc(2px * var(--ds-sf)));\n inset: calc(var(--ds-row-height) - var(--ds-control-height) - var(--ds-row-overhang))\n calc(var(--ds-row-padding, calc(4px * var(--ds-sf))) - var(--ds-row-overhang))\n calc(0px - var(--ds-row-overhang));\n border-radius: var(--ds-row-radius, var(--ds-row-fill-radius, calc(6px * var(--ds-sf))));\n background: var(--ds-row-fill-current, var(--ds-fill-hover));\n}\n/* A plain row (no press target inside) has no padding of its own: its words and icons stand on\n the row's edges, so the layer reaches two past them, as a flush row's does. */\n.ds-row[data-open]:not([data-open=\"false\"]):not(a, button, .ds-row--stacked, .ds-row--auto, :has(.ds-row__target))::after {\n inset: calc(var(--ds-row-height) - var(--ds-control-height) - var(--ds-row-overhang))\n calc(0px - var(--ds-row-overhang))\n calc(0px - var(--ds-row-overhang));\n}\n.ds-row[data-open]:is(.ds-row--stacked, .ds-row--auto)::after { inset: 0; }\n@media (forced-colors: active) {\n .ds-row[data-open]:not([data-open=\"false\"])::after { outline: 1px solid Highlight; outline-offset: -1px; }\n}\n/*\n * `.ds-context` is the `ds-context` element's look on a native menu, for a page\n * without Lit or a menu a library draws: Ezo's gap face. The rows carry the\n * colour and the menu only cuts the outer silhouette, so the page shows\n * through a pixel between rows and two between groups. The rows are black\n * with white words in both themes, as Ezo's menus always were (the slate in\n * dark, darker than the page). Every row is 19px with the pixel under it, a square's pitch, its words\n * on the sixteen and an icon at its end. A Select's menu is the light face,\n * `.ds-menu`; a Context's is this dark one.\n *\n * ds-context the menu (`role=\"menu\"`); its rows are its buttons,\n * links and menu items, or `ds-context__item`\n * ds-context__item a row; `--danger` (or `data-danger`) in red\n * ds-context__label a heading row, muted\n * ds-context__shortcut a shortcut at the row's end, muted\n * ds-context__separator a group gap (or an `hr`, or `role=\"separator\"`):\n * never a line; first, last or doubled it is quiet\n * [data-ds-refused] a refused change: the row turns red\n *\n * The page places and opens it (a popover at the pointer, say) and owns its\n * keys; the faces of hover, focus, disabled and the wait of a pending menu\n * (`aria-busy=\"true\"`) are here. Tokens as the element's: --ds-context-fill,\n * --ds-context-ink, --ds-context-hover, --ds-context-danger,\n * --ds-context-refused, --ds-context-radius.\n */\n\n.ds-context {\n --ds-context-row: calc(var(--ds-row-height) - 1px);\n /* Black in both themes, as Ezo's menus always were: in dark the slate, darker than the page. */\n --ds-context-fill: light-dark(var(--ds-black, #2a2a2a), var(--ds-slate, #1e1e1e));\n --ds-context-ink: var(--ds-white, #ffffff);\n --ds-context-hover: color-mix(in srgb, var(--ds-context-fill) 78%, var(--ds-context-ink));\n --ds-context-danger: var(--ds-tuned-red);\n --ds-context-refused: var(--ds-tuned-red);\n box-sizing: border-box;\n display: flex;\n flex-direction: column;\n gap: 1px;\n width: var(--ds-menu-width, max-content);\n min-width: calc(4 * var(--ds-unit));\n max-height: var(--ds-menu-max-height, calc(16 * var(--ds-unit)));\n overflow-y: auto;\n margin: 0;\n padding: 0;\n border: 0;\n background: transparent;\n box-shadow: none;\n clip-path: inset(0 round var(--ds-context-radius, var(--ds-radius, 4px)));\n color: var(--ds-context-ink);\n font-family: var(--ds-typeface-regular);\n font-feature-settings: var(--ds-font-features);\n font-size: var(--ds-type-size-default);\n font-weight: var(--ds-type-weight-default);\n line-height: var(--ds-type-lineheight-default);\n letter-spacing: var(--ds-type-letterspacing-default);\n list-style: none;\n}\n\n.ds-context > [role=\"group\"] {\n display: contents;\n}\n\n/* A row: whatever the page or library styles its buttons with, one row on the sixteen. */\n.ds-context :is(.ds-context__item, :is(.ds-context, .ds-context > [role=\"group\"]) > :is(button, a, li, [role^=\"menuitem\"]):not(.ds-context__label, .ds-context__separator, [role=\"separator\"])) {\n box-sizing: border-box !important;\n display: flex !important;\n flex: 0 0 auto !important;\n align-items: flex-end !important;\n justify-content: space-between !important;\n gap: calc(4px * var(--ds-sf));\n width: 100%;\n height: var(--ds-context-row) !important;\n min-height: var(--ds-context-row) !important;\n max-height: var(--ds-context-row) !important;\n margin: 0 !important;\n padding: 0 calc(4px * var(--ds-sf)) !important;\n border: 0 !important;\n border-radius: 0 !important;\n background: var(--ds-context-fill) !important;\n color: var(--ds-context-ink) !important;\n font: inherit;\n line-height: var(--ds-type-lineheight-default) !important;\n letter-spacing: inherit;\n text-align: start;\n text-decoration: none;\n white-space: nowrap;\n cursor: pointer;\n outline: none;\n appearance: none;\n -webkit-tap-highlight-color: transparent;\n}\n\n.ds-context :is(.ds-context__item, :is(.ds-context, .ds-context > [role=\"group\"]) > :is(button, a, li, [role^=\"menuitem\"])):is(:hover, :focus-visible, [data-highlighted]):not(:disabled, [aria-disabled=\"true\"], [data-disabled]) {\n background: var(--ds-context-hover) !important;\n}\n\n.ds-context :is(.ds-context__item, :is(.ds-context, .ds-context > [role=\"group\"]) > :is(button, a, li, [role^=\"menuitem\"])):focus-visible {\n box-shadow: inset 0 0 0 2px var(--ds-focus-ring);\n}\n\n.ds-context :is(.ds-context__item, :is(.ds-context, .ds-context > [role=\"group\"]) > :is(button, a, li, [role^=\"menuitem\"])):is(:disabled, [aria-disabled=\"true\"], [data-disabled]) {\n cursor: default;\n opacity: 0.5;\n}\n\n.ds-context[aria-busy=\"true\"] > * {\n cursor: wait !important;\n}\n\n/* Danger is red, on either fill. */\n.ds-context :is(.ds-context__item, :is(.ds-context, .ds-context > [role=\"group\"]) > :is(button, a, li, [role^=\"menuitem\"])):is(.ds-context__item--danger, [data-danger], [data-variant=\"destructive\"]) {\n color: var(--ds-context-danger) !important;\n}\n\n/* A refused change: its row turns red a moment. */\n.ds-context :is(.ds-context__item, :is(.ds-context, .ds-context > [role=\"group\"]) > :is(button, a, li, [role^=\"menuitem\"]))[data-ds-refused] {\n background: var(--ds-context-refused) !important;\n}\n\n/* Groups are a gap, never a line: the separator takes nothing but the gap after it. */\n.ds-context > :is(hr, .ds-context__separator, [role=\"separator\"]) {\n flex: 0 0 0 !important;\n height: 0 !important;\n margin: 0 !important;\n padding: 0 !important;\n border: 0 !important;\n background: none !important;\n}\n\n/* A group left empty leaves no gap. */\n.ds-context > :is(hr, .ds-context__separator, [role=\"separator\"]):is(:first-child, :last-child),\n.ds-context > :is(hr, .ds-context__separator, [role=\"separator\"]) + :is(hr, .ds-context__separator, [role=\"separator\"]) {\n display: none !important;\n}\n\n.ds-context :is(.ds-context__label, [data-ds-menu-label]) {\n box-sizing: border-box;\n height: var(--ds-context-row);\n /* The spare three above the sixteen. */\n padding: calc(var(--ds-context-row) - var(--ds-type-lineheight-default)) calc(4px * var(--ds-sf)) 0;\n background: var(--ds-context-fill);\n color: color-mix(in srgb, var(--ds-context-ink) 60%, var(--ds-context-fill));\n line-height: var(--ds-type-lineheight-default);\n white-space: nowrap;\n}\n\n.ds-context__shortcut {\n margin-left: auto;\n color: color-mix(in srgb, var(--ds-context-ink) 60%, var(--ds-context-fill));\n}\n\n/*\n * Native controls in shared dress.\n *\n * DS one keeps a few components as plain classes on native elements. shared does\n * the same for everything a person types into or picks from: text fields,\n * selects and checkboxes stay `<input>` and `<select>`, so labels, form\n * semantics and React's controlled inputs work as they always have.\n *\n * `.ds-button` is the `ds-button` element's look on a native `<button>`,\n * for a button inside a drag handle. The drag library recognises only native\n * controls: inside a handle it would lift the row on Space where a\n * `ds-button` was meant to be pressed. Both read the same custom properties.\n * On an `<a href>` it is a link drawn as a button (see `a.ds-button` below).\n */\n\n.ds-button {\n appearance: none;\n box-sizing: border-box;\n display: inline-flex;\n /* At the foot of a line, so the 16px face takes the lower sixteen of the square. */\n vertical-align: bottom;\n flex: 0 0 auto;\n width: var(--ds-button-width, max-content);\n align-items: center;\n justify-content: var(--ds-button-align, flex-start);\n gap: var(--ds-button-gap, calc(4px * var(--ds-sf)));\n height: var(--ds-button-height, var(--ds-control-height));\n margin: 0;\n padding: var(--ds-button-padding, 0);\n border: 0;\n border-radius: var(--ds-radius);\n background: var(--ds-button-background, transparent);\n color: var(--ds-button-color, var(--ds-button-text-color));\n font-family: var(--ds-typeface-regular);\n font-feature-settings: var(--ds-font-features);\n font-size: var(--ds-type-size-default);\n line-height: var(--ds-type-lineheight-default);\n letter-spacing: var(--ds-type-letterspacing-default);\n white-space: nowrap;\n cursor: pointer;\n -webkit-tap-highlight-color: transparent;\n}\n\n.ds-button--icon {\n justify-content: center;\n width: var(--ds-button-height, var(--ds-control-height));\n padding: 0;\n color: var(--ds-button-color, var(--ds-text-color-muted));\n}\n\n.ds-button--icon:hover:not(:disabled, [aria-disabled=\"true\"]) {\n --ds-button-color: var(--ds-text-color);\n}\n\n.ds-button:focus-visible {\n outline: 2px solid var(--ds-focus-ring);\n outline-offset: 1px;\n}\n\n.ds-button:disabled,\n.ds-button[aria-disabled=\"true\"] {\n cursor: default;\n opacity: 0.5;\n}\n\n/*\n * one.css carries older button rules that dim a button on hover and nudge it\n * on press. The shared button does neither: these match their specificity, so\n * controls.css, loaded after one.css, wins.\n */\n.ds-button:hover:not(:disabled, [aria-disabled=\"true\"]) {\n filter: none;\n}\n\n.ds-button:active:not(:disabled, [aria-disabled=\"true\"]) {\n transform: none;\n}\n\n/*\n * `a.ds-button` is a link drawn as a button. The browser keeps the link:\n * middle-click, a new tab, Copy link and Enter. It never takes the link's\n * underline or colours, in any state, so every face (primary, secondary,\n * icon, tabs) looks as it does on a `<button>`. A disabled link has no `href`\n * and carries `aria-disabled=\"true\"` and `role=\"link\"`.\n */\na.ds-button,\na.ds-button:is(:hover, :focus, :active) {\n text-decoration: none;\n}\n\na.ds-button:is(:link, :visited) {\n color: var(--ds-button-color, var(--ds-button-text-color));\n}\n\na.ds-button.ds-button--icon:is(:link, :visited) {\n color: var(--ds-button-color, var(--ds-text-color-muted));\n}\n\na.ds-button[aria-disabled=\"true\"] {\n pointer-events: none;\n}\n\n/*\n * `.ds-link` is a link in running text: the text's ink, underlined by a\n * hairline 2px below the letters (as a toast's actions are), which turns to the full ink under\n * the pointer. A visited link is drawn in the muted ink. Words keep their\n * sentence case. Tokens: `--ds-link-color`, `--ds-link-visited-color`,\n * `--ds-link-line-color`, `--ds-link-hover-line-color`.\n */\n.ds-link {\n color: var(--ds-link-color, currentColor);\n text-decoration-line: underline;\n text-decoration-thickness: 1px;\n text-decoration-color: var(--ds-link-line-color, color-mix(in srgb, currentColor 40%, transparent));\n text-underline-offset: calc(2px * var(--ds-sf));\n cursor: pointer;\n}\n\n.ds-link:visited {\n color: var(--ds-link-visited-color, var(--ds-text-color-muted));\n}\n\n.ds-link:hover {\n text-decoration-color: var(--ds-link-hover-line-color, currentColor);\n}\n\n/* Quiet navigation and related-component lists: no underline in any state. */\n.ds-link.ds-link--plain {\n text-decoration: none;\n}\n\n.ds-link:focus-visible {\n outline: 2px solid var(--ds-focus-ring);\n outline-offset: 1px;\n}\n\n.ds-link[aria-disabled=\"true\"] {\n cursor: default;\n opacity: 0.5;\n pointer-events: none;\n}\n\n.ds-input,\n.ds-select {\n box-sizing: border-box;\n min-width: 0;\n height: var(--ds-input-height, var(--ds-control-height));\n margin: 0;\n padding: 0 calc(4px * var(--ds-sf));\n border: 0;\n border-radius: var(--ds-radius);\n background: var(--ds-fill);\n color: var(--ds-text-color);\n font-family: var(--ds-typeface-regular);\n font-feature-settings: var(--ds-font-features);\n font-size: var(--ds-type-size-default);\n line-height: var(--ds-type-lineheight-default);\n letter-spacing: var(--ds-type-letterspacing-default);\n outline: none;\n}\n\n.ds-input::placeholder {\n color: var(--ds-title-color);\n}\n\n.ds-input:focus-visible,\n.ds-select:focus-visible,\n.ds-checkbox:focus-visible,\n.ds-radio:focus-visible,\n.ds-switch:focus-visible {\n outline: 2px solid var(--ds-focus-ring);\n outline-offset: 1px;\n}\n\n.ds-input:disabled,\n.ds-select:disabled,\n.ds-checkbox:disabled,\n.ds-radio:disabled,\n.ds-switch:disabled {\n cursor: default;\n opacity: 0.5;\n}\n\n.ds-select {\n appearance: none;\n padding-right: calc(16px * var(--ds-sf));\n background-image:\n linear-gradient(45deg, transparent 50%, currentColor 50%),\n linear-gradient(135deg, currentColor 50%, transparent 50%);\n background-position:\n calc(100% - 9px) 50%,\n calc(100% - 6px) 50%;\n background-size:\n 3px 3px,\n 3px 3px;\n background-repeat: no-repeat;\n cursor: pointer;\n}\n\n/* A multiline field, `ds-input` on a <textarea>, spans whole rows: --ds-textarea-rows sets how many, three by default. */\ntextarea.ds-input {\n display: block;\n height: var(--ds-textarea-height, calc(var(--ds-textarea-rows, 3) * var(--ds-row-height)));\n min-height: var(--ds-row-height);\n padding: var(--ds-textarea-padding, calc(4px * var(--ds-sf)));\n border-radius: var(--ds-textarea-radius, calc(4px * var(--ds-sf)));\n resize: vertical;\n}\n\n/*\n * `.ds-checkbox` and `.ds-radio` are the `ds-checkbox` and `ds-radio` elements'\n * faces on a native `<input>`: one square on the field's ground with a 1px\n * line. The checkbox has the corners of a control and fills with the accent,\n * the check (`x-icon/check.svg`) in its ink; the radio is a circle with a dot\n * half a square across in the text colour.\n */\n.ds-checkbox,\n.ds-radio {\n appearance: none;\n box-sizing: border-box;\n display: inline-grid;\n flex: 0 0 auto;\n place-items: center;\n vertical-align: middle;\n width: var(--ds-row-height);\n height: var(--ds-row-height);\n margin: 0;\n padding: 0;\n border: 1px solid var(--ds-border-color);\n background: var(--ds-input-background);\n cursor: pointer;\n}\n\n.ds-checkbox {\n --ds-checkbox-mark: url(\"data:image/svg+xml,%3Csvg%20width%3D%2216%22%20height%3D%2216%22%20viewBox%3D%220%200%2016%2016%22%20fill%3D%22none%22%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%3E%0A%3Cpath%20d%3D%22M6.68649%2011.884L12.443%206.13601L11.736%205.42715L6.68835%2010.4827L4.26399%208.0501L3.55696%208.74525L6.68649%2011.884Z%22%20fill%3D%22currentColor%22%2F%3E%0A%3C%2Fsvg%3E\");\n border-radius: var(--ds-radius);\n corner-shape: var(--ds-corner-shape, round);\n color: var(--ds-button-text-color-on-accent);\n}\n\n.ds-checkbox:is(:checked, :indeterminate) {\n background: var(--ds-accent-color);\n}\n\n.ds-checkbox::before,\n.ds-radio::before {\n content: \"\";\n opacity: 0;\n background: currentColor;\n}\n\n.ds-checkbox::before {\n width: calc(0.8 * var(--ds-row-height));\n height: calc(0.8 * var(--ds-row-height));\n mask: var(--ds-checkbox-mark) center / contain no-repeat;\n}\n\n.ds-checkbox:indeterminate::before {\n width: calc(var(--ds-row-height) / 2);\n height: calc(2px * var(--ds-sf));\n mask: none;\n}\n\n.ds-radio {\n border-radius: 50%;\n color: var(--ds-text-color);\n}\n\n.ds-radio::before {\n width: calc(var(--ds-row-height) / 2);\n height: calc(var(--ds-row-height) / 2);\n border-radius: 50%;\n}\n\n.ds-checkbox:is(:checked, :indeterminate)::before,\n.ds-radio:checked::before {\n opacity: 1;\n}\n\n/*\n * `.ds-switch` is the `ds-switch` element's look on a native\n * `<button role=\"switch\" aria-checked>`: two control heights wide, its thumb\n * one control high less a 2px inset, travelling one control height.\n * `.ds-switch--rounded` is the round variant with a white thumb.\n */\n\n.ds-switch {\n --ds-choice-unit: var(--ds-control-height);\n appearance: none;\n box-sizing: border-box;\n position: relative;\n display: inline-block;\n flex: 0 0 auto;\n vertical-align: middle;\n width: calc(2 * var(--ds-choice-unit));\n height: var(--ds-choice-unit);\n margin: 0;\n padding: calc(2px * var(--ds-sf));\n border: 0;\n border-radius: var(--ds-radius);\n background: var(--ds-fill);\n color: var(--ds-text-color-muted);\n cursor: pointer;\n touch-action: manipulation;\n}\n\n.ds-switch::after {\n content: \"\";\n display: block;\n width: calc(var(--ds-choice-unit) - 4px * var(--ds-sf));\n height: 100%;\n border-radius: var(--ds-radius);\n background: currentColor;\n transform: translateX(0);\n transition: transform 140ms ease;\n}\n\n.ds-switch[aria-checked=\"true\"] {\n background: var(--ds-accent-color);\n color: var(--ds-button-text-color-on-accent);\n}\n\n.ds-switch[aria-checked=\"true\"]::after {\n transform: translateX(var(--ds-choice-unit));\n}\n\n.ds-switch--rounded {\n border-radius: var(--ds-choice-unit);\n color: var(--ds-white);\n}\n\n.ds-switch--rounded::after {\n border-radius: 50%;\n background: var(--ds-white);\n}\n\n.ds-switch--rounded[aria-checked=\"true\"] {\n background: var(--ds-switch-track-on);\n}\n\n@media (prefers-reduced-motion: reduce) {\n .ds-switch::after {\n transition: none;\n }\n}\n\n/*\n * `.ds-range` draws a native `<input type=\"range\">`: one control high,\n * standing on the lower sixteen of its square (the spare four above it as a\n * margin, so it takes one square alone and in a row), eight squares wide.\n * The track is a 1px line across the middle of the control, the thumb one\n * control high and half a control wide with the shared corners, in the ink.\n * The browser keeps the value, the keys, the form data and the events.\n *\n * Tokens: `--ds-range-width` (eight squares), `--ds-range-track` (the line,\n * the title grey), `--ds-range-thumb` (the ink) and `--ds-range-thumb-width`.\n * WebKit and Blink draw the parts as `::-webkit-slider-*`, Firefox as\n * `::-moz-range-*`; both get the same track and thumb.\n */\n\n.ds-range {\n -webkit-appearance: none;\n appearance: none;\n box-sizing: border-box;\n display: inline-block;\n vertical-align: bottom;\n width: var(--ds-range-width, calc(8 * var(--ds-unit)));\n min-width: 0;\n height: var(--ds-control-height);\n margin: calc(var(--ds-row-height) - var(--ds-control-height)) 0 0;\n padding: 0;\n border: 0;\n border-radius: var(--ds-radius);\n background: transparent;\n color: var(--ds-range-thumb, var(--ds-text-color));\n font: inherit;\n cursor: pointer;\n touch-action: pan-y;\n -webkit-tap-highlight-color: transparent;\n}\n\n.ds-range::-webkit-slider-runnable-track {\n box-sizing: border-box;\n height: var(--ds-control-height);\n border: 0;\n background: linear-gradient(var(--ds-range-track, var(--ds-title-color)) 0 0) 0 calc(var(--ds-control-height) / 2) / 100% 1px no-repeat;\n}\n\n.ds-range::-moz-range-track {\n box-sizing: border-box;\n height: var(--ds-control-height);\n border: 0;\n background: linear-gradient(var(--ds-range-track, var(--ds-title-color)) 0 0) 0 calc(var(--ds-control-height) / 2) / 100% 1px no-repeat;\n}\n\n.ds-range::-moz-range-progress {\n background: transparent;\n}\n\n.ds-range::-webkit-slider-thumb {\n -webkit-appearance: none;\n appearance: none;\n box-sizing: border-box;\n width: var(--ds-range-thumb-width, calc(var(--ds-control-height) / 2));\n height: var(--ds-control-height);\n border: 0;\n border-radius: var(--ds-radius);\n background: currentColor;\n}\n\n.ds-range::-moz-range-thumb {\n box-sizing: border-box;\n width: var(--ds-range-thumb-width, calc(var(--ds-control-height) / 2));\n height: var(--ds-control-height);\n border: 0;\n border-radius: var(--ds-radius);\n background: currentColor;\n}\n\n.ds-range:focus-visible {\n outline: 2px solid var(--ds-focus-ring);\n outline-offset: 1px;\n}\n\n.ds-range:disabled {\n cursor: default;\n opacity: 0.5;\n}\n\n/*\n * `.ds-tabs` is the `ds-tabs` element's row on native buttons. As an option\n * group (role=\"group\", a segmented control) its `.ds-button` choices are\n * grey and the chosen one, aria-pressed, aria-selected or aria-current, is in\n * the accent, as the primary and secondary buttons are.\n */\n\n.ds-tabs {\n box-sizing: border-box;\n display: flex;\n flex-direction: row;\n align-items: center;\n gap: calc(4px * var(--ds-sf));\n min-width: 0;\n height: var(--ds-row-height);\n}\n\n.ds-tabs--fill > * {\n flex: 1 1 0;\n justify-content: center;\n}\n\n.ds-tabs[role=\"group\"] > .ds-button {\n --ds-button-height: var(--ds-row-height);\n --ds-button-padding: 0 calc(4px * var(--ds-sf));\n --ds-button-background: var(--ds-button-background-color-secondary);\n min-width: 0;\n}\n\n.ds-tabs[role=\"group\"] > .ds-button:hover:not(:disabled, [aria-disabled=\"true\"]) {\n --ds-button-background: var(--ds-fill-hover);\n}\n\n.ds-tabs[role=\"group\"] > .ds-button:is([aria-pressed=\"true\"], [aria-selected=\"true\"], [aria-current]:not([aria-current=\"false\"])) {\n --ds-button-background: var(--ds-button-background-color-primary);\n --ds-button-color: var(--ds-button-text-color-on-accent);\n}\n\n/*\n * `.ds-overlay` is the `ds-overlay` element's frame on a native `<dialog>`, a\n * modal by default: twenty squares wide, a square of padding, square corners,\n * a hairline and the paper. `ds-overlay--sheet`, `ds-overlay--drawer` (with\n * `ds-overlay--start` for the start side) and `ds-overlay--screen` are its\n * other types (overlay.css). Its header, title, description, footer and close button are marked\n * with data-ds-overlay, as inside the element.\n */\n\ndialog.ds-overlay {\n box-sizing: border-box;\n position: fixed;\n inset: 0;\n width: var(--ds-overlay-width, calc(20 * var(--ds-unit)));\n max-width: var(--ds-overlay-max-width, calc(100vw - 2 * var(--ds-unit)));\n max-height: var(--ds-overlay-max-height, calc(100dvh - 2 * var(--ds-unit)));\n height: var(--ds-overlay-height, fit-content);\n margin: auto;\n padding: var(--ds-overlay-padding, var(--ds-unit));\n border: var(--ds-overlay-border, 1px solid var(--ds-border-color));\n border-radius: 0;\n background: var(--ds-overlay-paper, var(--ds-paper));\n color: var(--ds-text-color);\n box-shadow: none;\n overflow: auto;\n overscroll-behavior: contain;\n font-family: var(--ds-typeface-regular);\n font-feature-settings: var(--ds-font-features);\n font-size: var(--ds-type-size-default);\n font-weight: var(--ds-type-weight-default);\n line-height: var(--ds-type-lineheight-default);\n letter-spacing: var(--ds-type-letterspacing-default);\n}\n\ndialog.ds-overlay[open] {\n display: flex;\n flex-direction: column;\n gap: var(--ds-unit);\n}\n\ndialog.ds-overlay::backdrop {\n background: color-mix(in srgb, var(--ds-black) 40%, transparent);\n}\n\n.ds-overlay [data-ds-overlay=\"header\"] {\n display: flex;\n flex-direction: column;\n}\n\n/* The header keeps the last square of its row for the close button, only when it has one. */\ndialog.ds-overlay:has(> [data-ds-overlay=\"close\"]) [data-ds-overlay=\"header\"] {\n padding-inline-end: var(--ds-unit);\n}\n\n/* The title on its square's lower sixteen, as every row's words. */\n.ds-overlay [data-ds-overlay=\"title\"] {\n display: flex;\n align-items: flex-end;\n min-height: var(--ds-row-height);\n margin: 0;\n color: var(--ds-text-color);\n font: inherit;\n font-weight: var(--ds-type-weight-bold);\n line-height: var(--ds-type-lineheight-default);\n}\n\n.ds-overlay [data-ds-overlay=\"description\"] {\n margin: 0;\n color: var(--ds-text-color-muted);\n font: inherit;\n}\n\n.ds-overlay [data-ds-overlay=\"footer\"] {\n display: flex;\n flex-wrap: wrap;\n align-items: center;\n justify-content: flex-end;\n gap: calc(var(--ds-unit) / 2);\n min-height: var(--ds-row-height);\n}\n\n.ds-overlay [data-ds-overlay=\"close\"] {\n position: absolute;\n top: var(--ds-unit);\n right: var(--ds-unit);\n}\n\n/* A field in the frame, as a prompt has: its label one row high, the field\n * one row high beneath it and as wide as the frame, two squares in all. */\n.ds-overlay [data-ds-overlay=\"field\"] {\n display: flex;\n flex-direction: column;\n}\n\n.ds-overlay [data-ds-overlay=\"label\"] {\n min-height: var(--ds-row-height);\n line-height: var(--ds-row-height);\n}\n\n.ds-overlay [data-ds-overlay=\"field\"] > .ds-input {\n --ds-input-height: var(--ds-row-height);\n width: 100%;\n}\n\n/*\n * `.ds-button--primary` and `--secondary` are the element's variants on a\n * native button: a form's submit button stays native so Enter in a field\n * submits the form. `--danger` is its `danger` attribute.\n */\n\n.ds-button--primary,\n.ds-button--secondary {\n --ds-button-padding: 0 calc(4px * var(--ds-sf));\n}\n\n.ds-button--primary {\n --ds-button-background: var(--ds-button-background-color-primary);\n --ds-button-color: var(--ds-button-text-color-on-accent);\n}\n\n.ds-button--secondary {\n --ds-button-background: var(--ds-button-background-color-secondary);\n}\n\n.ds-button--secondary:hover:not(:disabled, [aria-disabled=\"true\"]) {\n --ds-button-background: var(--ds-fill-hover);\n}\n\n/* `.ds-button--danger` is the element's `danger`: a destructive action's words\n * in the danger colour, on the secondary face or none. */\n.ds-button--danger {\n --ds-button-color: var(--ds-danger-color, var(--ds-tuned-red));\n}\n\n.ds-button--fixed {\n width: var(--ds-button-width, calc(4 * var(--ds-unit)));\n}\n\n.ds-button--wide {\n justify-content: center;\n width: 100%;\n}\n\n/*\n * `.ds-menu` is the `ds-menu` element's look on a menu a library draws:\n * the context menu's items come from Radix, which owns their roles, focus and\n * keys, so they stay Radix's and take shared's paper, rows and type.\n * On whole squares, as the element: the line and the padding inside it make\n * half a square on each side, entries are one square each with nothing\n * between them, a separator is one square with its line, and there is no\n * shadow. n entries make a menu n + 1 squares high.\n */\n\n.ds-menu {\n box-sizing: border-box;\n display: flex;\n flex-direction: column;\n gap: 0;\n min-width: calc(8 * var(--ds-unit));\n max-width: calc(12 * var(--ds-unit));\n max-height: var(--ds-menu-max-height, calc(16 * var(--ds-unit)));\n overflow-y: auto;\n padding: calc(var(--ds-unit) / 2 - 1px);\n border: 1px solid var(--ds-border-color);\n border-radius: var(--ds-radius-card);\n background: var(--ds-paper);\n color: var(--ds-text-color);\n box-shadow: none;\n font-family: var(--ds-typeface-regular);\n font-feature-settings: var(--ds-font-features);\n font-size: var(--ds-type-size-default);\n font-weight: var(--ds-type-weight-default);\n line-height: var(--ds-type-lineheight-default);\n letter-spacing: var(--ds-type-letterspacing-default);\n}\n\n.ds-menu__item {\n position: relative;\n box-sizing: border-box;\n display: flex;\n align-items: center;\n gap: calc(4px * var(--ds-sf));\n width: 100%;\n min-height: var(--ds-row-height);\n padding: calc(2px * var(--ds-sf)) calc(6px * var(--ds-sf));\n border-radius: calc(4px * var(--ds-sf));\n color: var(--ds-text-color);\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n cursor: default;\n user-select: none;\n outline: none;\n}\n\n/* An entry a library draws as its own button or link is one square high too,\n * whatever that library's button styles say. */\n.ds-menu > :is(button, a, [role=\"option\"], [role^=\"menuitem\"]),\n.ds-menu > [role=\"group\"] > :is(button, a, [role=\"option\"], [role^=\"menuitem\"]) {\n box-sizing: border-box !important;\n flex: 0 0 auto !important;\n height: var(--ds-row-height) !important;\n min-height: var(--ds-row-height) !important;\n max-height: var(--ds-row-height) !important;\n margin-block: 0 !important;\n padding-block: 0 !important;\n line-height: var(--ds-type-lineheight-default) !important;\n}\n\n/* A menu item may be a native button: it keeps the row's look, not a button's. */\n:where(button).ds-menu__item {\n appearance: none;\n margin: 0;\n border: 0;\n background: transparent;\n font: inherit;\n letter-spacing: inherit;\n text-align: start;\n}\n\n.ds-menu__item--inset {\n padding-left: calc(var(--ds-unit) + calc(4px * var(--ds-sf)));\n}\n\n.ds-menu__item:hover,\n.ds-menu__item:focus-visible,\n.ds-menu__item[data-highlighted] {\n background: var(--ds-fill);\n}\n\n.ds-menu__item[data-variant=\"destructive\"] {\n color: var(--ds-danger-color, var(--ds-tuned-red));\n}\n\n.ds-menu__item[data-disabled],\n.ds-menu__item[aria-disabled=\"true\"] {\n opacity: 0.5;\n pointer-events: none;\n}\n\n.ds-menu__indicator {\n position: absolute;\n left: calc(6px * var(--ds-sf));\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: calc(12px * var(--ds-sf));\n height: calc(12px * var(--ds-sf));\n pointer-events: none;\n}\n\n.ds-menu__indicator svg {\n width: 100%;\n height: 100%;\n}\n\n.ds-menu__chevron {\n width: calc(12px * var(--ds-sf));\n height: calc(12px * var(--ds-sf));\n margin-left: auto;\n color: var(--ds-text-color-muted);\n}\n\n.ds-menu__label {\n box-sizing: border-box;\n min-height: var(--ds-row-height);\n padding: calc(2px * var(--ds-sf)) calc(6px * var(--ds-sf));\n color: var(--ds-title-color);\n font-size: var(--ds-type-size-small);\n}\n\n.ds-menu__separator {\n flex: 0 0 auto;\n height: 1px;\n /* One square with its line. */\n margin: calc(var(--ds-unit) / 2 - 1px) calc(6px * var(--ds-sf)) calc(var(--ds-unit) / 2);\n background: var(--ds-border-color);\n}\n\n.ds-menu__shortcut {\n margin-left: auto;\n padding-left: var(--ds-unit);\n color: var(--ds-title-color);\n font-size: var(--ds-type-size-small);\n}\n\n/*\n * Pieces the components draw, as classes on native elements: a field's label\n * row, an avatar, a badge, a toggle button, an icon and a file drop zone. Each\n * reads the same tokens as its element, so a page without Lit draws the same\n * look.\n */\n\n/*\n * `.ds-field` is the label row `ds-input` draws, around any native control:\n * the label (`.ds-field__label`) on a one-square line above it, then a hint\n * (`.ds-field__hint`) in the muted ink and an error (`.ds-field__error`) in\n * the danger colour, each on one-square lines. Every row is at least one\n * square high and a control lower than that stands centred on it, so the\n * field keeps to whole squares. `.ds-field--beside` sets the label beside the\n * control, in a column `--ds-field-label-width` wide (four squares), with the\n * hint and the error under the control. An empty hint or error takes no room,\n * so the error can stay in the page as a live region.\n */\n\n.ds-field {\n box-sizing: border-box;\n display: grid;\n grid-template-columns: minmax(0, 1fr);\n grid-auto-rows: minmax(var(--ds-row-height), auto);\n align-items: center;\n justify-items: start;\n min-width: 0;\n margin: 0;\n color: var(--ds-text-color);\n font-family: var(--ds-typeface-regular);\n font-feature-settings: var(--ds-font-features);\n font-size: var(--ds-type-size-default);\n font-weight: var(--ds-type-weight-default);\n line-height: var(--ds-unit);\n letter-spacing: var(--ds-type-letterspacing-default);\n}\n\n.ds-field > :is(.ds-input, .ds-select) {\n justify-self: stretch;\n}\n\n.ds-field__label,\n.ds-field__hint,\n.ds-field__error {\n display: block;\n min-width: 0;\n margin: 0;\n font: inherit;\n letter-spacing: inherit;\n}\n\n.ds-field__label {\n color: var(--ds-field-label-color, var(--ds-text-color));\n}\n\n.ds-field__hint {\n color: var(--ds-text-color-muted);\n}\n\n.ds-field__error {\n color: var(--ds-danger-color);\n}\n\n.ds-field__hint:empty,\n.ds-field__error:empty {\n display: none;\n}\n\n.ds-field--beside {\n grid-template-columns: var(--ds-field-label-width, calc(4 * var(--ds-unit))) minmax(0, 1fr);\n}\n\n.ds-field--beside > * {\n grid-column: 2;\n}\n\n.ds-field--beside > .ds-field__label {\n grid-column: 1;\n grid-row: 1;\n align-self: start;\n}\n\n/*\n * `.ds-avatar` is the `ds-avatar` element's mark: round and one control high,\n * an initial in small type on the neutral fill, or an `<img alt=\"\">` after the\n * initial, covering it. While the picture loads the initial shows; remove a\n * picture that fails (`onerror`), as the element does, or the browser draws\n * its broken-image mark. `--large` is two squares with type a square high,\n * `--pair` fits two characters between the hairline edges, `--square` gives it\n * a picture's corners, `--outlined` draws the hairline in its ink and\n * `--pending` greys out someone who has not accepted yet.\n * `--ds-avatar-background` fills it with a colour and `--ds-avatar-color`\n * letters it: on a fill, pick the black or white ink that reads on it\n * (`--ds-black`, `--ds-white`).\n */\n\n.ds-avatar {\n --ds-avatar-size: var(--ds-control-height);\n --ds-avatar-pair-type-size: var(--ds-type-size-small);\n box-sizing: border-box;\n position: relative;\n display: inline-grid;\n place-items: center;\n flex: 0 0 auto;\n vertical-align: middle;\n width: var(--ds-avatar-size);\n height: var(--ds-avatar-size);\n overflow: hidden;\n border-radius: 50%;\n corner-shape: round;\n background: var(--ds-avatar-background, var(--ds-fill));\n color: var(--ds-avatar-color, var(--ds-text-color));\n font: var(--ds-type-weight-default) var(--ds-type-size-small) / 1 var(--ds-typeface-regular);\n letter-spacing: normal;\n text-align: center;\n white-space: nowrap;\n user-select: none;\n -webkit-user-select: none;\n}\n\n.ds-avatar > img {\n position: absolute;\n inset: 0;\n display: block;\n width: 100%;\n height: 100%;\n object-fit: cover;\n}\n\n.ds-avatar--large {\n --ds-avatar-size: calc(2 * var(--ds-unit));\n --ds-avatar-pair-type-size: var(--ds-type-size-default);\n font-size: var(--ds-unit);\n}\n\n.ds-avatar--pair {\n font-size: min(var(--ds-avatar-pair-type-size), calc((var(--ds-avatar-size) - 2px) / 2));\n}\n\n.ds-avatar--square {\n border-radius: var(--ds-avatar-radius, var(--ds-radius));\n corner-shape: var(--ds-corner-shape, round);\n}\n\n.ds-avatar--outlined::after {\n content: \"\";\n position: absolute;\n inset: 0;\n border: 1px solid var(--ds-avatar-outline, currentColor);\n border-radius: inherit;\n pointer-events: none;\n}\n\n.ds-avatar--pending {\n background: var(--ds-fill);\n color: var(--ds-text-color-muted);\n}\n\n.ds-avatar--pending > img {\n filter: grayscale(1);\n opacity: 0.5;\n}\n\n/*\n * `.ds-badge` is the `ds-badge` element's status label: one square high on the\n * neutral fill, its words padded 4px and cut short with an ellipsis, never a\n * button. Where the browser can size to content in calc (calc-size), its width\n * rounds up to whole squares as the element's does; elsewhere it hugs the\n * words. An icon inside is a `.ds-icon` before the words. `--icon` shows the\n * icon alone, one square wide, and keeps the words for assistive technology:\n * put them in an element of their own. `--ds-badge-background` and\n * `--ds-badge-color` give a status a meaningful colour.\n */\n\n.ds-badge {\n box-sizing: border-box;\n display: inline-block;\n flex: 0 0 auto;\n vertical-align: middle;\n width: max-content;\n width: calc-size(max-content, round(up, size, var(--ds-unit)));\n min-width: var(--ds-row-height);\n max-width: 100%;\n height: var(--ds-row-height);\n padding: 0 calc(4px * var(--ds-sf));\n overflow: hidden;\n background: var(--ds-badge-background, var(--ds-fill));\n color: var(--ds-badge-color, var(--ds-text-color));\n font-family: var(--ds-typeface-regular);\n font-feature-settings: var(--ds-font-features);\n font-size: var(--ds-type-size-default);\n font-weight: var(--ds-type-weight-default);\n line-height: var(--ds-row-height);\n letter-spacing: var(--ds-type-letterspacing-default);\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n.ds-badge > .ds-icon {\n vertical-align: top;\n margin-top: calc((var(--ds-row-height) - var(--ds-icon-box, var(--ds-control-height))) / 2);\n margin-right: calc(4px * var(--ds-sf));\n}\n\n.ds-badge--icon {\n position: relative;\n width: var(--ds-row-height);\n padding: 0;\n text-align: center;\n}\n\n.ds-badge--icon > .ds-icon {\n margin-right: 0;\n}\n\n.ds-badge--icon > :not(.ds-icon) {\n position: absolute;\n width: 1px;\n height: 1px;\n overflow: hidden;\n clip-path: inset(50%);\n white-space: nowrap;\n}\n\n/*\n * `.ds-toggle` makes a `.ds-button` a toggle button, `<button aria-pressed>`:\n * the secondary button's grey while it is off, the primary button's accent\n * while it is on, as a chosen segment of `.ds-tabs[role=\"group\"]` is. Its\n * words stay the same in both states; the page toggles `aria-pressed`.\n * A setting that is on or off is a `.ds-switch`; one of several choices is a\n * `.ds-tabs[role=\"group\"]`.\n */\n\n.ds-toggle {\n --ds-button-padding: 0 calc(4px * var(--ds-sf));\n --ds-button-background: var(--ds-button-background-color-secondary);\n}\n\n.ds-toggle:hover:not(:disabled, [aria-disabled=\"true\"]) {\n --ds-button-background: var(--ds-fill-hover);\n}\n\n.ds-toggle[aria-pressed=\"true\"],\n.ds-toggle[aria-pressed=\"true\"]:hover:not(:disabled, [aria-disabled=\"true\"]) {\n --ds-button-background: var(--ds-button-background-color-primary);\n --ds-button-color: var(--ds-button-text-color-on-accent);\n}\n\n/*\n * `.ds-icon` is the `ds-icon` element's drawing without the element: a\n * Design system 1 icon file as a mask, painted in the text colour\n * (`--ds-icon-color`), 14px by default, 12px with `--small` and 16px with\n * `--large`, times the scale. `--ds-icon` names the file, as Sync 1's `icons`\n * export copies it: `style=\"--ds-icon: url(icons/close.svg)\"` (a path from the\n * page) or a rule per icon in the page's stylesheet. The mask takes only the\n * drawing's shape, so an icon with colours of its own is an `<img>`. These\n * rules have no specificity: a page that drew its own `.ds-icon` keeps its\n * rule until it removes it.\n */\n\n:where(.ds-icon) {\n --ds-icon-box: calc(var(--ds-icon-size, 14px) * var(--ds-sf));\n display: inline-block;\n flex: 0 0 auto;\n width: var(--ds-icon-box);\n height: calc(var(--ds-icon-box) / var(--ds-icon-ratio, 1));\n color: var(--ds-icon-color, currentColor);\n background-color: currentColor;\n -webkit-mask: var(--ds-icon) center / contain no-repeat;\n mask: var(--ds-icon) center / contain no-repeat;\n}\n\n:where(.ds-icon--small) {\n --ds-icon-size: 12px;\n}\n\n:where(.ds-icon--large) {\n --ds-icon-size: 16px;\n}\n\n/*\n * `.ds-drop` is `ds-file-picker`'s area on a `<label>` around a native\n * `<input type=\"file\">`: the secondary button's face, as wide as its row and\n * eight squares high (`--compact`: four), its words centred in a square of\n * padding. The input covers the zone unseen, so a click, the keyboard and a\n * dropped file all reach it, and the browser keeps labels, forms, `required`,\n * `multiple` and reset. Keyboard focus draws the focus ring. A page that also\n * handles drops on a larger surface sets `data-dragging` on the zone while\n * files are dragged over it, for the ring and the hover fill. A `.ds-button`\n * on a `<span>` inside draws a button face among the words.\n *\n * The same native input directly inside a `label.ds-button` is the file\n * picker's button: the button's face, one square high.\n */\n\n.ds-drop {\n box-sizing: border-box;\n position: relative;\n display: flex;\n flex-wrap: wrap;\n align-content: center;\n align-items: center;\n justify-content: center;\n gap: calc(var(--ds-unit) / 2);\n width: 100%;\n min-width: 0;\n height: calc(8 * var(--ds-unit));\n margin: 0;\n padding: var(--ds-unit);\n overflow: hidden;\n border-radius: var(--ds-radius);\n corner-shape: var(--ds-corner-shape, round);\n background: var(--ds-button-background-color-secondary);\n color: var(--ds-button-text-color);\n font-family: var(--ds-typeface-regular);\n font-feature-settings: var(--ds-font-features);\n font-size: var(--ds-type-size-default);\n font-weight: var(--ds-type-weight-default);\n line-height: var(--ds-type-lineheight-default);\n letter-spacing: var(--ds-type-letterspacing-default);\n text-align: center;\n cursor: pointer;\n user-select: none;\n -webkit-user-select: none;\n -webkit-tap-highlight-color: transparent;\n}\n\n.ds-drop--compact {\n height: calc(4 * var(--ds-unit));\n}\n\nlabel.ds-button:has(> input[type=\"file\"]) {\n --ds-button-height: var(--ds-row-height);\n position: relative;\n overflow: hidden;\n}\n\n:is(.ds-drop, label.ds-button) > input[type=\"file\"]:not([hidden]) {\n position: absolute;\n inset: 0;\n box-sizing: border-box;\n display: block;\n width: 100%;\n height: 100%;\n min-width: 0;\n margin: 0;\n padding: 0;\n border: 0;\n opacity: 0;\n cursor: pointer;\n}\n\n:is(.ds-drop, label.ds-button) > input[type=\"file\"]::file-selector-button {\n cursor: pointer;\n}\n\n.ds-drop:hover:not(:has(> input:disabled)),\n.ds-drop[data-dragging]:not(:has(> input:disabled)) {\n background: var(--ds-fill-hover);\n}\n\n.ds-drop:has(> input:focus-visible),\n.ds-drop[data-dragging]:not(:has(> input:disabled)),\nlabel.ds-button:has(> input[type=\"file\"]:focus-visible) {\n outline: 2px solid var(--ds-focus-ring);\n outline-offset: 1px;\n}\n\n.ds-drop:has(> input:disabled),\nlabel.ds-button:has(> input[type=\"file\"]:disabled) {\n cursor: default;\n opacity: 0.5;\n}\n\n:is(.ds-drop, label.ds-button) > input[type=\"file\"]:disabled {\n cursor: default;\n}\n";
8831
+ var controls_default = "/* Shape is a surface preference. Keep these base lengths unscaled: each\n * component resolves them with its own --ds-sf in component-metrics.css. */\n[data-ds-shape=\"square\"],\n:host([data-ds-shape=\"square\"]) {\n --ds-corner-size: 0px;\n --ds-corner-shape: round;\n --ds-button-inset: 0.5px;\n}\n\n[data-ds-shape=\"rounded\"],\n:host([data-ds-shape=\"rounded\"]) {\n --ds-corner-size: 4px;\n --ds-corner-shape: round;\n --ds-button-inset: 2.5px;\n}\n\n[data-ds-shape=\"circular\"],\n:host([data-ds-shape=\"circular\"]) {\n --ds-corner-size: 999px;\n --ds-corner-shape: round;\n --ds-button-inset: 5px;\n}\n\n/* A squircle needs twice an arc's radius for the same apparent corner.\n * Circular controls keep true semicircles even in a squircle browser. */\n@supports (corner-shape: squircle) {\n [data-ds-shape=\"rounded\"],\n :host([data-ds-shape=\"rounded\"]) {\n --ds-corner-size: 8px;\n --ds-corner-shape: squircle;\n }\n}\n\n/* Resolve dimensions where a component is drawn. Inherited calc() values have\n * already used their ancestor's scale. Base tokens stay unscaled and inherit;\n * resolved tokens can still be overridden directly on a component.\n * data-ds-surface gives ordinary layout elements the same scaled measures.\n */\n:root,\n:host,\n:where([data-ds-surface]) {\n --ds-unit: calc(var(--ds-1, 20px) * var(--ds-sf, 1));\n --ds-control-height: calc(var(--ds-control-size, var(--ds-08, 16px)) * var(--ds-sf, 1));\n --ds-row-height: calc(var(--ds-row-size, var(--ds-1, 20px)) * var(--ds-sf, 1));\n --ds-type-size-default: calc(var(--ds-text-size, 14px) * var(--ds-sf, 1));\n --ds-type-size-small: calc(var(--ds-small-text-size, 10px) * var(--ds-sf, 1));\n --ds-type-size-heading: calc(var(--ds-heading-text-size, 13px) * var(--ds-sf, 1));\n --ds-type-size-display: calc(var(--ds-display-text-size, 20px) * var(--ds-sf, 1));\n --ds-type-lineheight-default: calc(var(--ds-text-leading, 16px) * var(--ds-sf, 1));\n --ds-type-letterspacing-default: calc(var(--ds-text-tracking, -0.3px) * var(--ds-sf, 1));\n --ds-radius: calc(var(--ds-corner-size, 4px) * var(--ds-sf, 1));\n --ds-radius-card: calc(var(--ds-card-corner-size, 4px) * var(--ds-sf, 1));\n}\n/*\n * A table: words straight on the paper, one square a row. No box and no\n * column lines: each row stands on a hairline at its foot, its words set on\n * that line like a caption: the sixteen of words against the 1px line, three\n * spare above, a 20px pitch, as Ezo sets every row.\n * Column headers keep the text's weight in the title grey; the first column\n * of a body row is a row header in the text colour. Nothing is filled with\n * the accent except a cell someone has selected.\n *\n * `.ds-table` dresses a native <table>; `<ds-table>` draws the same table\n * from data. Put a wide table in `.ds-table-scroll` to scroll it sideways,\n * and give the table `data-sticky` to keep its first column in place.\n *\n * <th data-numeric>, <td data-numeric> numbers, set to the column's end\n * <tfoot> totals, under a line of their own\n * <th colspan=\"2\"> a column group, in a header row\n * <th scope=\"rowgroup\"> a row group, a heading row in grey\n * <td aria-selected=\"true\"> a selected cell\n *\n * `data-sheet` makes it a spreadsheet: every cell four squares by one (80 by\n * 20), its 1px lines at its end and foot so the words have 79 by 19, set 4px\n * in on the sixteen, as an Ezo item's are. Column letters and the row numbers\n * (`.ds-table__letters`, `.ds-table__number`, two squares wide) stay in place\n * while the sheet scrolls both ways inside `.ds-table-scroll`; give the table\n * `--ds-table-columns` (the number of data columns) and the scroll a height\n * with `--ds-table-height`.\n */\n\n.ds-table {\n --ds-table-row: var(--ds-row-height, calc(20px * var(--ds-sf, 1)));\n --ds-table-gap: calc(var(--ds-table-row) / 2);\n --ds-table-rule: var(--ds-border-color, light-dark(#d8d8d8, #3d3d3d));\n --ds-table-paper: var(--ds-background, Canvas);\n width: 100%;\n border-collapse: collapse;\n border-spacing: 0;\n color: var(--ds-text-color, inherit);\n font-family: var(--ds-typeface-regular, inherit);\n font-feature-settings: var(--ds-font-features, normal);\n font-size: var(--ds-type-size-default, 14px);\n letter-spacing: var(--ds-type-letterspacing-default, normal);\n}\n\n.ds-table :is(th, td) {\n box-sizing: border-box;\n height: var(--ds-table-row);\n padding: 0 var(--ds-table-gap) 0 0;\n border: 0;\n border-bottom: 1px solid var(--ds-table-rule);\n background: transparent;\n line-height: var(--ds-type-lineheight-default);\n text-align: start;\n vertical-align: bottom;\n font-weight: inherit;\n white-space: nowrap;\n}\n\n.ds-table :is(th, td):last-child {\n padding-inline-end: 0;\n}\n\n.ds-table thead th,\n.ds-table th[scope=\"rowgroup\"] {\n color: var(--ds-title-color, light-dark(#797979, #9a9a9a));\n}\n\n.ds-table tbody th:not([scope=\"rowgroup\"]) {\n color: inherit;\n}\n\n.ds-table [data-numeric] {\n text-align: end;\n font-variant-numeric: tabular-nums;\n}\n\n/* Totals: the rule above them is the last body row's; theirs closes the table. */\n.ds-table tfoot :is(th, td) {\n color: inherit;\n}\n\n.ds-table [aria-selected=\"true\"] {\n background: var(--ds-accent-color, Highlight);\n color: var(--ds-button-text-color-on-accent, inherit);\n}\n\n.ds-table :is(th, td):has(> :is(a, button):only-child) {\n cursor: pointer;\n}\n\n.ds-table caption {\n box-sizing: border-box;\n height: var(--ds-table-row);\n padding-top: calc(var(--ds-table-row) - var(--ds-type-lineheight-default));\n line-height: var(--ds-type-lineheight-default);\n text-align: start;\n color: var(--ds-title-color, light-dark(#797979, #9a9a9a));\n}\n\n.ds-table-scroll {\n max-width: 100%;\n overflow-x: auto;\n overscroll-behavior-x: contain;\n}\n\n.ds-table-scroll > .ds-table {\n width: max-content;\n min-width: 100%;\n}\n\n.ds-table[data-sticky] :is(th, td):first-child {\n position: sticky;\n inset-inline-start: 0;\n z-index: 1;\n background: var(--ds-table-paper);\n}\n\n.ds-table[data-sticky] [aria-selected=\"true\"]:first-child {\n background: var(--ds-accent-color, Highlight);\n}\n\n/* Keep the row whose details are open visible, including its sticky first cell.\n Cell selection remains independent and keeps its accent. */\n.ds-table tbody > tr[data-open]:not([data-open=\"false\"]) > :is(th, td):not([aria-selected=\"true\"]) {\n background: var(--ds-row-fill-current, var(--ds-fill-hover));\n}\n@media (forced-colors: active) {\n .ds-table tbody > tr[data-open]:not([data-open=\"false\"]) > :is(th, td):not([aria-selected=\"true\"]) {\n background: Highlight;\n color: HighlightText;\n }\n}\n\n/* A spreadsheet: cells four squares by one, on lines, lettered and numbered. */\n.ds-table[data-sheet] {\n --ds-table-cell: calc(4 * var(--ds-table-row));\n --ds-table-index: calc(2 * var(--ds-table-row));\n --ds-table-text: calc(4px * var(--ds-sf, 1));\n table-layout: fixed;\n width: calc(var(--ds-table-index) + var(--ds-table-columns, 8) * var(--ds-table-cell));\n min-width: 0;\n border-collapse: separate;\n border-spacing: 0;\n}\n.ds-table-scroll > .ds-table[data-sheet] {\n width: calc(var(--ds-table-index) + var(--ds-table-columns, 8) * var(--ds-table-cell));\n min-width: 0;\n}\n.ds-table[data-sheet] :is(th, td) {\n width: var(--ds-table-cell);\n max-width: var(--ds-table-cell);\n height: var(--ds-table-row);\n padding: 0 var(--ds-table-text);\n border-bottom: 1px solid var(--ds-table-rule);\n border-inline-end: 1px solid var(--ds-table-rule);\n overflow: hidden;\n text-overflow: ellipsis;\n}\n.ds-table[data-sheet] :is(th, td):last-child {\n padding-inline-end: var(--ds-table-text);\n}\n.ds-table[data-sheet] .ds-table__number {\n width: var(--ds-table-index);\n max-width: var(--ds-table-index);\n position: sticky;\n inset-inline-start: 0;\n z-index: 1;\n background: var(--ds-table-paper);\n color: var(--ds-title-color, light-dark(#797979, #9a9a9a));\n text-align: center;\n font-variant-numeric: tabular-nums;\n}\n.ds-table[data-sheet] thead :is(th, td) {\n position: sticky;\n top: 0;\n z-index: 2;\n background: var(--ds-table-paper);\n}\n.ds-table[data-sheet] thead tr + tr :is(th, td) {\n top: var(--ds-table-row);\n}\n.ds-table[data-sheet] thead .ds-table__number {\n z-index: 3;\n}\n.ds-table[data-sheet] .ds-table__letters td {\n color: var(--ds-title-color, light-dark(#797979, #9a9a9a));\n text-align: center;\n}\n.ds-table[data-sheet] tbody td:not([data-numeric]) {\n color: inherit;\n}\n.ds-table[data-sheet] [aria-selected=\"true\"] {\n background: transparent;\n color: inherit;\n box-shadow: inset 0 0 0 2px var(--ds-focus-ring, Highlight);\n}\n.ds-table-scroll:has(> .ds-table[data-sheet]) {\n max-height: var(--ds-table-height, none);\n overflow: auto;\n overscroll-behavior: contain;\n}\n/*\n * Text on the grid, as plain classes on native text.\n *\n * Interface copy on a page without Lit: a label, a message, a title. Each line\n * is one square (`--ds-unit`), so a paragraph of any length stands on whole\n * squares, and a display title takes two. The `ds-text` element draws the same\n * words when they come from a translation key.\n *\n * one.css and controls.css both import this file, so a page that loads either\n * of them, or both, has one definition of these classes.\n *\n * ds-text 14 on a one-square line, the text colour\n * ds-text--small 10\n * ds-text--heading 13, medium\n * ds-text--display 20 on two squares, medium\n * ds-text--strong medium\n * ds-text--muted, --title, --danger tones\n */\n\n.ds-text {\n margin: 0;\n color: var(--ds-text-color);\n font-family: var(--ds-typeface-regular);\n font-feature-settings: var(--ds-font-features);\n font-size: var(--ds-type-size-default);\n font-weight: var(--ds-type-weight-default);\n line-height: var(--ds-unit);\n letter-spacing: var(--ds-type-letterspacing-default);\n}\n\n.ds-text--small {\n font-size: var(--ds-type-size-small);\n}\n\n.ds-text--heading {\n font-family: var(--ds-typeface-medium);\n font-size: var(--ds-type-size-heading);\n font-weight: var(--ds-type-weight-bold);\n}\n\n.ds-text--display {\n font-family: var(--ds-typeface-medium);\n font-size: var(--ds-type-size-display);\n font-weight: var(--ds-type-weight-bold);\n line-height: calc(2 * var(--ds-unit));\n letter-spacing: calc(var(--ds-display-text-tracking, -0.4px) * var(--ds-sf, 1));\n}\n\n.ds-text--strong {\n font-family: var(--ds-typeface-medium);\n font-weight: var(--ds-type-weight-bold);\n}\n\n.ds-text--muted {\n color: var(--ds-text-color-muted);\n}\n\n.ds-text--title {\n color: var(--ds-title-color);\n}\n\n.ds-text--danger {\n color: var(--ds-danger-color);\n}\n\n.ds-text--warning {\n color: var(--ds-warning-color);\n}\n/*\n * An empty state, as plain classes on native elements.\n *\n * It says that a place has nothing in it yet and what to do about it: a title,\n * a line of text and, when there is one, the action that fills it. The words\n * sit on the paper with no box, no illustration and no colour; every line is\n * one square, so the whole stands on whole squares. The `ds-empty` element\n * draws the same parts from a translation key, with the shared words' \"Nothing\n * here yet\" as its title when none is given.\n *\n * ds-empty the block, at most sixteen squares wide\n * ds-empty__icon an icon from the library, on its own square, muted\n * ds-empty__title one line in the medium face\n * ds-empty__text lines of one square, muted\n * ds-empty__actions buttons or links on one row, one square below\n * ds-empty--centered centred in the space it stands in\n * ds-empty--done all done: the check on a mark in the success\n * green, the title in that green\n *\n * Tokens: `--ds-empty-measure` (the widest it grows, sixteen squares) and\n * `--ds-empty-padding` (the room above and below, none by default).\n */\n\n.ds-empty {\n box-sizing: border-box;\n display: flex;\n flex-direction: column;\n align-items: flex-start;\n width: 100%;\n max-width: var(--ds-empty-measure, calc(16 * var(--ds-unit)));\n margin: 0;\n padding-block: var(--ds-empty-padding, 0);\n color: var(--ds-text-color);\n font-family: var(--ds-typeface-regular);\n font-feature-settings: var(--ds-font-features);\n font-size: var(--ds-type-size-default);\n font-weight: var(--ds-type-weight-default);\n line-height: var(--ds-unit);\n letter-spacing: var(--ds-type-letterspacing-default);\n text-transform: none;\n}\n\n.ds-empty__icon {\n display: flex;\n align-items: center;\n height: var(--ds-unit);\n color: var(--ds-text-color-muted);\n}\n\n.ds-empty__title,\n.ds-empty__text {\n margin: 0;\n font: inherit;\n letter-spacing: inherit;\n}\n\n.ds-empty__title {\n font-family: var(--ds-typeface-medium);\n font-weight: var(--ds-type-weight-bold);\n}\n\n.ds-empty__text {\n color: var(--ds-text-color-muted);\n}\n\n.ds-empty__actions {\n display: flex;\n flex-wrap: wrap;\n align-items: center;\n gap: 0 calc(var(--ds-unit) / 2);\n min-height: var(--ds-row-height);\n margin-top: var(--ds-unit);\n}\n\n.ds-empty--centered {\n align-items: center;\n margin-inline: auto;\n text-align: center;\n}\n\n.ds-empty--centered .ds-empty__actions {\n justify-content: center;\n}\n\n/* Done: a place empty because everything in it is finished (every receipt\n found, nothing left to review). The icon, the check by default, stands on a\n round mark one control high in the success green, on the sixteen, and the\n title takes the same green; the line under it stays muted. */\n.ds-empty--done .ds-empty__icon {\n box-sizing: border-box;\n justify-content: center;\n width: var(--ds-control-height);\n height: var(--ds-control-height);\n margin-top: calc(var(--ds-unit) - var(--ds-control-height));\n border-radius: 50%;\n background: var(--ds-success-color);\n color: light-dark(var(--ds-white), var(--ds-black));\n --ds-icon-color: currentColor;\n}\n\n.ds-empty--done .ds-empty__title {\n color: var(--ds-success-color);\n}\n/*\n * An inline notice, as plain classes on native elements.\n *\n * A notice stands in the flow of the page, where its words apply: a failure\n * beside the form that failed, a warning above the list it is about. It is not\n * positioned and takes no box or shadow. A square mark, one control high and\n * filled in the tone's colour, carries the tone; the words sit on the paper\n * beside it, each line one square, with the actions on the row below and the\n * dismiss button at the end of the first line. Danger turns the words into\n * the danger colour. The `ds-notice` element draws the same parts.\n *\n * ds-notice the block: mark, words, dismiss\n * ds-notice__mark the square mark; holds an icon in its ink\n * ds-notice__title one line in the medium face\n * ds-notice__text lines of one square\n * ds-notice__actions buttons or links on one row\n * ds-notice__dismiss an icon button at the end of the first line\n * ds-notice--success, --warning, --danger tones; neutral without one\n * ds-notice--banner a strip across the top of its positioning\n * context instead: one square high, filled in\n * the tone's colour, everything on one line\n * ds-notice--app a row at the top of the page leading to the\n * site's iPhone app: its picture\n * (ds-notice__picture, two squares), its name\n * and one line about it, Open\n * (a.ds-notice__open) and the close; three\n * squares high with a hairline at its foot.\n * startAppBanners() from 0-face/app-banner.ts\n * shows it only where it belongs\n *\n * Give the block role=\"status\", or role=\"alert\" for danger, so assistive\n * technology reads it when it appears.\n *\n * Tokens: `--ds-notice-mark`, `--ds-notice-mark-ink` and `--ds-notice-ink`,\n * which the tones set.\n */\n\n.ds-notice {\n --ds-notice-mark: var(--ds-fill);\n --ds-notice-mark-ink: var(--ds-text-color);\n --ds-notice-ink: var(--ds-text-color);\n box-sizing: border-box;\n display: grid;\n grid-template-columns: var(--ds-unit) minmax(0, 1fr) auto;\n align-items: start;\n margin: 0;\n color: var(--ds-notice-ink);\n font-family: var(--ds-typeface-regular);\n font-feature-settings: var(--ds-font-features);\n font-size: var(--ds-type-size-default);\n font-weight: var(--ds-type-weight-default);\n line-height: var(--ds-unit);\n letter-spacing: var(--ds-type-letterspacing-default);\n text-transform: none;\n}\n\n.ds-notice--success {\n --ds-notice-mark: var(--ds-apple-green);\n --ds-notice-mark-ink: var(--ds-black);\n}\n\n.ds-notice--warning {\n --ds-notice-mark: var(--ds-orange);\n --ds-notice-mark-ink: var(--ds-black);\n}\n\n.ds-notice--danger {\n --ds-notice-mark: var(--ds-danger-color);\n --ds-notice-mark-ink: light-dark(var(--ds-white), var(--ds-black));\n --ds-notice-ink: var(--ds-danger-color);\n}\n\n/* The mark stands on the first line, one control high in a one-square cell. */\n.ds-notice__mark {\n box-sizing: border-box;\n grid-column: 1;\n grid-row: 1;\n display: flex;\n align-items: center;\n justify-content: center;\n width: var(--ds-control-height);\n height: var(--ds-control-height);\n margin-block: calc((var(--ds-unit) - var(--ds-control-height)) / 2);\n overflow: hidden;\n background: var(--ds-notice-mark);\n color: var(--ds-notice-mark-ink);\n --ds-icon-color: var(--ds-notice-mark-ink);\n}\n\n.ds-notice__title,\n.ds-notice__text,\n.ds-notice__actions {\n grid-column: 2;\n min-width: 0;\n margin: 0;\n}\n\n.ds-notice__title,\n.ds-notice__text {\n font: inherit;\n letter-spacing: inherit;\n overflow-wrap: anywhere;\n}\n\n.ds-notice__title {\n font-family: var(--ds-typeface-medium);\n font-weight: var(--ds-type-weight-bold);\n}\n\n.ds-notice__actions {\n display: flex;\n flex-wrap: wrap;\n align-items: center;\n gap: 0 calc(var(--ds-unit) / 2);\n min-height: var(--ds-row-height);\n}\n\n/* The dismiss button closes the first line: a one-square cell at the end.\n Two classes, so the button's own reset of its margin does not undo it. */\n.ds-notice .ds-notice__dismiss {\n grid-column: 3;\n grid-row: 1;\n margin-block: calc((var(--ds-unit) - var(--ds-control-height)) / 2);\n margin-inline-start: calc(var(--ds-unit) - var(--ds-control-height));\n}\n\n/* A banner: the same parts on one line, one square high, across the top of\n the nearest positioned ancestor (or the page), on a fill of the tone's\n colour. It takes no room in the flow; leave a square for it where words\n stand under it. The actions stand at the end of the line, half a square\n apart; danger words keep the text colour on the danger fill. */\n.ds-notice--banner {\n position: absolute;\n top: 0;\n inset-inline: 0;\n z-index: 9999;\n display: flex;\n align-items: center;\n gap: calc(var(--ds-unit) / 2);\n height: var(--ds-unit);\n padding-inline: var(--ds-unit);\n background: color-mix(in srgb, var(--ds-notice-mark) 40%, transparent);\n --ds-notice-ink: var(--ds-text-color);\n}\n\n.ds-notice--banner .ds-notice__mark {\n flex: none;\n margin-block: 0;\n}\n\n.ds-notice--banner .ds-notice__title,\n.ds-notice--banner .ds-notice__text {\n min-width: 0;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n.ds-notice--banner .ds-notice__text {\n flex: 1;\n}\n\n.ds-notice--banner .ds-notice__actions {\n flex: none;\n min-height: 0;\n}\n\n.ds-notice--banner .ds-notice__dismiss {\n margin-block: 0;\n margin-inline-start: 0;\n}\n\n/* The app banner: a row at the top of the page, in the flow, three squares\n high: half a square above and below two squares of content, a hairline at\n its foot. The app's picture fills two squares with a picture's corners; the\n name and the line about it take a square each, on the sixteen; Open and the\n close stand on the sixteen of the square in the middle of the two. */\n.ds-notice--app {\n grid-template-columns: calc(2 * var(--ds-unit)) minmax(0, 1fr) auto var(--ds-unit);\n grid-template-rows: var(--ds-unit) var(--ds-unit);\n column-gap: calc(var(--ds-unit) / 2);\n align-items: end;\n padding: calc(var(--ds-unit) / 2) var(--ds-unit);\n background: var(--ds-paper);\n box-shadow: inset 0 -1px 0 var(--ds-border-color);\n line-height: var(--ds-type-lineheight-default);\n}\n\n.ds-notice--app[hidden] {\n display: none;\n}\n\n.ds-notice__picture {\n box-sizing: border-box;\n grid-column: 1;\n grid-row: 1 / 3;\n align-self: stretch;\n overflow: hidden;\n border-radius: var(--ds-radius);\n background: var(--ds-fill);\n outline: 1px solid var(--ds-border-color);\n outline-offset: -1px;\n}\n\n.ds-notice__picture img {\n display: block;\n width: 100%;\n height: 100%;\n object-fit: cover;\n}\n\n.ds-notice--app .ds-notice__title,\n.ds-notice--app .ds-notice__text {\n grid-column: 2;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n.ds-notice--app .ds-notice__title { grid-row: 1; }\n\n.ds-notice--app .ds-notice__text {\n grid-row: 2;\n color: var(--ds-text-color-muted);\n}\n\n/* Open and the close: their square starts half a square into the two, its\n control on the lower sixteen of it. */\n.ds-notice--app .ds-notice__open,\n.ds-notice--app .ds-notice__dismiss {\n grid-row: 1 / 3;\n align-self: start;\n margin: calc(1.5 * var(--ds-unit) - var(--ds-control-height)) 0 0;\n}\n\n.ds-notice--app .ds-notice__open {\n grid-column: 3;\n text-decoration: none;\n}\n\n.ds-notice--app .ds-notice__dismiss {\n grid-column: 4;\n justify-self: end;\n}\n/*\n * Overlay: everything that stands over the page, one component with a type.\n * A `modal` stands in the centre (controls.css and the element's frame); this\n * sheet draws the others, for the `ds-overlay` element (`type=\"sheet\"`,\n * `\"drawer\"` with `side`, `\"screen\"`, which mark its native dialog\n * `data-ds-type` and `data-ds-edge`) and the native frame\n * (`dialog.ds-overlay.ds-overlay--sheet`, `--drawer` with `--start`,\n * `--screen`); controls.css imports it. A popover is placed by the element.\n *\n * - A sheet is as wide as the screen up to 32 squares and centred beyond\n * that, as high as its content up to two squares below the top, with no\n * line at its foot; its one line, at the top, is drawn inside its first\n * square (`--ds-overlay-line`), so it stands on whole squares. A handle two squares wide stands in the middle of its\n * first square and stays there while the content scrolls.\n * - A drawer is the screen's height and 16 squares wide (`--ds-overlay-width`),\n * leaving at least two squares of the page beside it; its one line is on\n * the side that faces the page. `end` is the right in a left-to-right page.\n * - Each keeps the square of padding inside the screen's safe area\n * (`env(safe-area-inset-*)`, with `viewport-fit=cover` on the page).\n * - Each slides in from its edge and back out to it, in transform alone,\n * while the backdrop fades; with reduced motion it fades in place. Dragging\n * it towards its edge (0-face/overlay-swipe.ts) moves it with the finger and\n * fades the backdrop as it goes.\n * - The page behind a modal native sheet or drawer does not scroll.\n */\n\n:is(ds-overlay > dialog[data-ds-edge=\"bottom\"], dialog.ds-overlay.ds-overlay--sheet),\n:is(ds-overlay > dialog[data-ds-edge=\"end\"], dialog.ds-overlay.ds-overlay--drawer:not(.ds-overlay--start)),\n:is(ds-overlay > dialog[data-ds-edge=\"start\"], dialog.ds-overlay.ds-overlay--drawer.ds-overlay--start) {\n --ds-overlay-gap: var(--ds-unit);\n --ds-overlay-inner: var(--ds-overlay-padding, var(--ds-unit));\n /* The line it faces the page with is drawn inside its first square. */\n --ds-overlay-within: max(0px, var(--ds-overlay-inner) - var(--ds-overlay-line, 1px));\n --ds-overlay-motion: var(--ds-overlay-enter, 380ms);\n --ds-overlay-curve: var(--ds-overlay-easing, cubic-bezier(0.32, 0.72, 0, 1));\n margin: 0;\n gap: var(--ds-overlay-gap);\n transform: var(--ds-overlay-held);\n transition:\n transform var(--ds-overlay-motion) var(--ds-overlay-curve),\n opacity var(--ds-overlay-motion) var(--ds-overlay-curve),\n overlay var(--ds-overlay-motion) allow-discrete,\n display var(--ds-overlay-motion) allow-discrete;\n}\n\n/* Content that supplies its own room. */\n:is(ds-overlay > dialog[data-ds-edge], dialog.ds-overlay:is(.ds-overlay--sheet, .ds-overlay--drawer))[data-ds-overlay-flush] {\n --ds-overlay-inner: 0px;\n --ds-overlay-gap: 0px;\n}\n\n:is(ds-overlay > dialog[data-ds-edge=\"bottom\"], dialog.ds-overlay.ds-overlay--sheet) {\n --ds-overlay-held: translateY(var(--ds-overlay-drag, 0px));\n --ds-overlay-away: translateY(100%);\n inset: auto 0 0;\n width: var(--ds-overlay-width, 100%);\n max-width: min(100%, var(--ds-overlay-sheet-width, calc(32 * var(--ds-unit))));\n height: var(--ds-overlay-height, fit-content);\n max-height: calc(100dvh - var(--ds-overlay-sheet-gap, calc(2 * var(--ds-unit))) - env(safe-area-inset-top, 0px));\n margin: 0 auto;\n padding:\n var(--ds-overlay-within)\n calc(var(--ds-overlay-inner) + env(safe-area-inset-right, 0px))\n calc(var(--ds-overlay-inner) + env(safe-area-inset-bottom, 0px))\n calc(var(--ds-overlay-inner) + env(safe-area-inset-left, 0px));\n border-bottom: 0;\n}\n\n/* The handle: two squares wide, in the middle of the first square, above the\n * content as it scrolls. It takes no room: the content starts where it would. */\n:is(ds-overlay > dialog[data-ds-edge=\"bottom\"], dialog.ds-overlay.ds-overlay--sheet)::before {\n --ds-overlay-handle-height: calc(4px * var(--ds-sf, 1));\n content: \"\";\n display: var(--ds-overlay-handle, block);\n position: sticky;\n z-index: 1;\n /* A sticky offset counts from the content edge, under the sheet's top padding: take that\n padding off, so the handle is held where it already stands, in the first square. */\n top: calc((var(--ds-unit) - var(--ds-overlay-handle-height)) / 2 - var(--ds-overlay-line, 1px) - var(--ds-overlay-within));\n flex: 0 0 auto;\n align-self: center;\n width: calc(2 * var(--ds-unit));\n height: var(--ds-overlay-handle-height);\n margin-top: calc(var(--ds-overlay-inner) * -1 + (var(--ds-unit) - var(--ds-overlay-handle-height)) / 2);\n margin-bottom: calc(var(--ds-overlay-inner) - var(--ds-overlay-gap) - var(--ds-overlay-handle-height) - (var(--ds-unit) - var(--ds-overlay-handle-height)) / 2);\n border-radius: calc(var(--ds-overlay-handle-height) / 2);\n background: var(--ds-overlay-handle-color, var(--ds-border-color));\n pointer-events: none;\n}\n\n:is(ds-overlay > dialog[data-ds-edge=\"end\"], dialog.ds-overlay.ds-overlay--drawer:not(.ds-overlay--start)),\n:is(ds-overlay > dialog[data-ds-edge=\"start\"], dialog.ds-overlay.ds-overlay--drawer.ds-overlay--start) {\n --ds-overlay-held: translateX(var(--ds-overlay-drag, 0px));\n width: calc(var(--ds-overlay-width, calc(16 * var(--ds-unit))) + var(--ds-overlay-safe-side, 0px));\n max-width: calc(100vw - 2 * var(--ds-unit));\n height: 100dvh;\n max-height: none;\n border-top: 0;\n border-bottom: 0;\n}\n\n/* At the right: the end of a left-to-right page, the start of a right-to-left one. */\n:is(ds-overlay > dialog[data-ds-edge=\"end\"], dialog.ds-overlay.ds-overlay--drawer:not(.ds-overlay--start)):not(:dir(rtl)),\n:is(ds-overlay > dialog[data-ds-edge=\"start\"], dialog.ds-overlay.ds-overlay--drawer.ds-overlay--start):dir(rtl) {\n --ds-overlay-away: translateX(100%);\n --ds-overlay-safe-side: env(safe-area-inset-right, 0px);\n inset: 0 0 0 auto;\n padding:\n calc(var(--ds-overlay-inner) + env(safe-area-inset-top, 0px))\n calc(var(--ds-overlay-inner) + env(safe-area-inset-right, 0px))\n calc(var(--ds-overlay-inner) + env(safe-area-inset-bottom, 0px))\n var(--ds-overlay-within);\n border-right: 0;\n}\n\n:is(ds-overlay > dialog[data-ds-edge=\"start\"], dialog.ds-overlay.ds-overlay--drawer.ds-overlay--start):not(:dir(rtl)),\n:is(ds-overlay > dialog[data-ds-edge=\"end\"], dialog.ds-overlay.ds-overlay--drawer:not(.ds-overlay--start)):dir(rtl) {\n --ds-overlay-away: translateX(-100%);\n --ds-overlay-safe-side: env(safe-area-inset-left, 0px);\n inset: 0 auto 0 0;\n padding:\n calc(var(--ds-overlay-inner) + env(safe-area-inset-top, 0px))\n var(--ds-overlay-within)\n calc(var(--ds-overlay-inner) + env(safe-area-inset-bottom, 0px))\n calc(var(--ds-overlay-inner) + env(safe-area-inset-left, 0px));\n border-left: 0;\n}\n\n/* The page behind a native sheet or drawer holds still while it is open, as\n * the element holds it (the element saves and restores the scroll itself). */\n:root:has(dialog.ds-overlay:is(.ds-overlay--sheet, .ds-overlay--drawer):modal) {\n overflow: hidden;\n overscroll-behavior: none;\n}\n\n/* Out to its edge, a little quicker than it came; and in from it. */\n:is(ds-overlay > dialog[data-ds-edge], dialog.ds-overlay:is(.ds-overlay--sheet, .ds-overlay--drawer)):not([open]) {\n --ds-overlay-motion: var(--ds-overlay-exit, 260ms);\n transform: var(--ds-overlay-away);\n}\n\n@starting-style {\n :is(ds-overlay > dialog[data-ds-edge], dialog.ds-overlay:is(.ds-overlay--sheet, .ds-overlay--drawer))[open] {\n transform: var(--ds-overlay-away);\n }\n}\n\n:is(ds-overlay > dialog[data-ds-edge], dialog.ds-overlay:is(.ds-overlay--sheet, .ds-overlay--drawer))::backdrop {\n opacity: calc(1 - var(--ds-overlay-progress, 0));\n transition:\n opacity var(--ds-overlay-motion, 380ms) ease,\n overlay var(--ds-overlay-motion, 380ms) allow-discrete,\n display var(--ds-overlay-motion, 380ms) allow-discrete;\n}\n\n:is(ds-overlay > dialog[data-ds-edge], dialog.ds-overlay:is(.ds-overlay--sheet, .ds-overlay--drawer)):not([open])::backdrop {\n opacity: 0;\n}\n\n@starting-style {\n :is(ds-overlay > dialog[data-ds-edge], dialog.ds-overlay:is(.ds-overlay--sheet, .ds-overlay--drawer))[open]::backdrop {\n opacity: 0;\n }\n}\n\n/* While a finger holds it, it follows the finger alone. */\n:is(ds-overlay > dialog[data-ds-edge], dialog.ds-overlay:is(.ds-overlay--sheet, .ds-overlay--drawer))[data-ds-overlay-dragging],\n:is(ds-overlay > dialog[data-ds-edge], dialog.ds-overlay:is(.ds-overlay--sheet, .ds-overlay--drawer))[data-ds-overlay-dragging]::backdrop {\n transition: none;\n}\n\n/* Reduced motion: no slide. It fades where it stands, a dragged one too. */\n@media (prefers-reduced-motion: reduce) {\n :is(ds-overlay > dialog[data-ds-edge], dialog.ds-overlay:is(.ds-overlay--sheet, .ds-overlay--drawer)) {\n --ds-overlay-motion: 150ms;\n transition:\n opacity var(--ds-overlay-motion) ease,\n overlay var(--ds-overlay-motion) allow-discrete,\n display var(--ds-overlay-motion) allow-discrete;\n }\n\n :is(ds-overlay > dialog[data-ds-edge], dialog.ds-overlay:is(.ds-overlay--sheet, .ds-overlay--drawer)):not([open]) {\n --ds-overlay-motion: 150ms;\n transform: var(--ds-overlay-held);\n opacity: 0;\n }\n\n @starting-style {\n :is(ds-overlay > dialog[data-ds-edge], dialog.ds-overlay:is(.ds-overlay--sheet, .ds-overlay--drawer))[open] {\n transform: var(--ds-overlay-held);\n opacity: 0;\n }\n }\n}\n\n/*\n * The screen: an overlay over the whole screen, for navigation folded away on\n * a narrow screen (`ds-header`, `ds-page drawer`, `attachOverlay()`).\n *\n * The panel is the dialog frame (`dialog.ds-overlay`) laid over the whole\n * screen, on the page's own paper, a square of room on every side. Its first\n * row holds the close button where the menu button stood; what the page\n * folded away (its navigation and actions) follows, every link one square\n * high. The page script `0-face/attach-overlay.ts` opens it: it moves the folded parts\n * into the panel and back, keeps focus inside, closes on Escape, on a link and\n * when the screen widens, and holds the page's scroll while it is open.\n * `ds-header` and `ds-page drawer` use the same script and these rules.\n *\n * ds-overlay--screen on a <dialog class=\"ds-overlay\">, the panel\n * ds-overlay__bar the first row: the close button at its end\n * ds-overlay__close the close button, an icon button\n * ds-overlay__toggle the button that opens it: it carries\n * two icons, the first shown while closed and the\n * second (close) while open\n *\n * Tokens: `--ds-overlay-paper` (the page's paper by default).\n */\n\n:is(ds-overlay > dialog[data-ds-type=\"screen\"], dialog.ds-overlay.ds-overlay--screen) {\n --ds-overlay-width: 100vw;\n width: 100vw;\n max-width: none;\n height: 100dvh;\n max-height: none;\n margin: 0;\n padding: var(--ds-unit);\n gap: 0;\n border: 0;\n background: var(--ds-overlay-paper, var(--background, Canvas));\n overflow-y: auto;\n}\n\n:is(ds-overlay > dialog[data-ds-type=\"screen\"], dialog.ds-overlay.ds-overlay--screen)[open] {\n display: flex;\n flex-direction: column;\n align-items: stretch;\n gap: var(--ds-unit);\n}\n\n/* Content that supplies its own room, as the documentation's navigation does. */\n:is(ds-overlay > dialog[data-ds-type=\"screen\"], dialog.ds-overlay.ds-overlay--screen)[data-ds-overlay-flush] {\n padding: 0;\n gap: 0;\n}\n\n:is(ds-overlay > dialog[data-ds-type=\"screen\"], dialog.ds-overlay.ds-overlay--screen)::backdrop {\n background: transparent;\n}\n\n/* It arrives by fading in and settling half a square, and leaves at once. */\n@media (prefers-reduced-motion: no-preference) {\n :is(ds-overlay > dialog[data-ds-type=\"screen\"], dialog.ds-overlay.ds-overlay--screen)[open] {\n transition: opacity 160ms ease-out, transform 160ms ease-out;\n }\n\n @starting-style {\n :is(ds-overlay > dialog[data-ds-type=\"screen\"], dialog.ds-overlay.ds-overlay--screen)[open] {\n opacity: 0;\n transform: translateY(calc(var(--ds-unit) / -2));\n }\n }\n}\n\n.ds-overlay__bar {\n display: flex;\n align-items: center;\n justify-content: flex-end;\n min-height: var(--ds-row-height);\n}\n\n/* Centred in the last square of the row, as the menu button is. Two classes,\n so the button's own margin does not undo it. */\n.ds-overlay__bar > .ds-overlay__close {\n margin-inline-end: calc((var(--ds-unit) - var(--ds-control-height)) / 2);\n}\n\n/* The toggle shows its first icon while closed and its second while open; the\n close button, a copy of it, shows the second. */\n.ds-overlay__toggle:not([aria-expanded=\"true\"]) > :nth-child(2),\n.ds-overlay__toggle[aria-expanded=\"true\"] > :first-child:not(:only-child),\n.ds-overlay__close > :first-child:not(:only-child) {\n display: none;\n}\n/*\n * A site header, as plain classes on native elements.\n *\n * One row of one square, a square of room around it: the brand at the start\n * in twelve squares (as a page's navigation column is, so the links stand\n * over the work), the navigation two squares after it, the actions at the end. Every link is\n * one square high, a square apart, in the text's ink; the page you are on\n * (`aria-current=\"page\"`) stands on a hairline of the full ink, the others\n * show a faint one under the pointer. Below thirty squares of width the\n * navigation and the actions fold into a drawer: the menu button takes their\n * place at the end of the row, and `0-face/header.ts` opens them over the page.\n * The `ds-header` element draws the same parts.\n *\n * ds-header the row, a <header>\n * ds-header__brand the mark or name, a link home; a picture in it is one square high\n * ds-header__nav the links, a <nav>\n * ds-header__actions buttons or links at the end\n * ds-header__toggle the menu button: `.ds-button.ds-button--icon.ds-overlay__toggle`\n * with a menu icon and a close icon, shown only on a narrow screen\n * ds-header--sticky stays at the top of the page as it scrolls, on the paper\n *\n * Tokens: `--ds-header-brand` (the brand's width, at least twelve squares),\n * `--ds-header-paper` (the sticky header's paper) and `--ds-header-line` (the\n * hairline under a sticky header, none by default).\n */\n\n.ds-header {\n box-sizing: border-box;\n container-type: inline-size;\n display: flex;\n align-items: center;\n gap: calc(2 * var(--ds-unit));\n min-width: 0;\n margin: 0;\n padding: var(--ds-unit);\n color: var(--ds-text-color);\n font-family: var(--ds-typeface-regular);\n font-feature-settings: var(--ds-font-features);\n font-size: var(--ds-type-size-default);\n font-weight: var(--ds-type-weight-default);\n line-height: var(--ds-unit);\n letter-spacing: var(--ds-type-letterspacing-default);\n text-transform: none;\n}\n\n.ds-header--sticky {\n position: sticky;\n top: 0;\n z-index: 1;\n background: var(--ds-header-paper, var(--background, Canvas));\n box-shadow: inset 0 -1px var(--ds-header-line, transparent);\n}\n\n.ds-header__brand {\n box-sizing: border-box;\n display: inline-flex;\n flex: 0 0 auto;\n min-width: var(--ds-header-brand, calc(12 * var(--ds-unit)));\n align-items: center;\n gap: calc(var(--ds-unit) / 2);\n height: var(--ds-unit);\n color: inherit;\n font-family: var(--ds-typeface-medium);\n font-weight: var(--ds-type-weight-bold);\n text-decoration: none;\n white-space: nowrap;\n}\n\n.ds-header__brand :is(img, svg) {\n display: block;\n width: auto;\n height: var(--ds-unit);\n}\n\n.ds-header__nav,\n.ds-header__actions {\n display: flex;\n align-items: center;\n gap: var(--ds-unit);\n min-width: 0;\n margin: 0;\n padding: 0;\n}\n\n.ds-header__nav {\n flex: 1 1 auto;\n flex-wrap: wrap;\n row-gap: 0;\n}\n\n.ds-header__actions {\n flex: 0 0 auto;\n justify-content: flex-end;\n gap: calc(var(--ds-unit) / 2);\n margin-inline-start: auto;\n}\n\n/* A link in the navigation: the text's ink on a one-square line. */\n.ds-header__nav a {\n display: block;\n height: var(--ds-unit);\n color: inherit;\n text-decoration-line: underline;\n text-decoration-thickness: 1px;\n text-decoration-color: transparent;\n text-underline-offset: calc(2px * var(--ds-sf));\n white-space: nowrap;\n}\n\n.ds-header__nav a:hover {\n text-decoration-color: color-mix(in srgb, currentColor 40%, transparent);\n}\n\n.ds-header__nav a[aria-current]:not([aria-current=\"false\"]) {\n text-decoration-color: currentColor;\n}\n\n.ds-header__nav a:focus-visible,\n.ds-header__brand:focus-visible {\n outline: 2px solid var(--ds-focus-ring);\n outline-offset: 1px;\n}\n\n/* The menu button stands at the end of the row, and only on a narrow screen.\n Two classes, so the button's own display and margin do not undo it. */\n.ds-header > .ds-header__toggle {\n display: none;\n margin-inline-start: auto;\n /* Centred in the last square of the row, where the close button stands too. */\n margin-inline-end: calc((var(--ds-unit) - var(--ds-control-height)) / 2);\n}\n\n@container (max-width: 599px) {\n .ds-header > :is(.ds-header__nav, .ds-header__actions) {\n display: none;\n }\n\n .ds-header > .ds-header__toggle {\n display: inline-flex;\n }\n\n .ds-header > .ds-header__brand {\n min-width: 0;\n }\n}\n\n/* In the drawer the navigation is a column of one-square links, and the\n actions a row one square below it. */\n.ds-overlay--screen :is(.ds-header__nav, .ds-header__actions) {\n flex: 0 0 auto;\n flex-direction: column;\n align-items: flex-start;\n flex-wrap: nowrap;\n gap: 0;\n margin: 0;\n}\n\n.ds-overlay--screen .ds-header__actions {\n flex-direction: row;\n flex-wrap: wrap;\n gap: calc(var(--ds-unit) / 2);\n}\n/*\n * A site footer, as plain classes on native elements.\n *\n * The brand and its line at the start, twelve squares wide; the columns of\n * links beside it, eight squares each, two squares apart; then, two squares\n * below, the legal line at the start and the preferences (language and theme,\n * as `ds-cycle` or native buttons) at the end. Every line is one square, the\n * column headings in the title grey, the links in the text's ink with a faint\n * hairline under the pointer. A hairline runs along its top. Columns that do\n * not fit beside the brand go below it, and on a narrow screen everything\n * stands in one column. The `ds-footer` element draws the same parts from data.\n *\n * ds-footer the block, a <footer>\n * ds-footer__brand the mark and its line\n * ds-footer__mark the mark or name, a link home; a picture in it is one square high\n * ds-footer__tagline a line about the site, muted\n * ds-footer__columns the columns, a <nav> or <div>\n * ds-footer__column one column: a heading and its links\n * ds-footer__heading the column's heading, one line in the title grey\n * ds-footer__links the links, a <ul> with one link per <li>\n * ds-footer__base the last row, two squares below\n * ds-footer__legal in it, the copyright and legal line, muted\n * ds-footer__preferences in it, the language and theme controls, at its end\n *\n * Tokens: `--ds-footer-line` (the hairline along the top).\n */\n\n.ds-footer {\n box-sizing: border-box;\n container-type: inline-size;\n display: flex;\n flex-wrap: wrap;\n align-items: flex-start;\n gap: calc(2 * var(--ds-unit));\n min-width: 0;\n margin: 0;\n padding: calc(2 * var(--ds-unit)) var(--ds-unit) var(--ds-unit);\n box-shadow: inset 0 1px var(--ds-footer-line, var(--ds-border-color));\n color: var(--ds-text-color);\n font-family: var(--ds-typeface-regular);\n font-feature-settings: var(--ds-font-features);\n font-size: var(--ds-type-size-default);\n font-weight: var(--ds-type-weight-default);\n line-height: var(--ds-unit);\n letter-spacing: var(--ds-type-letterspacing-default);\n text-transform: none;\n}\n\n.ds-footer :is(p, h2, h3, h4, ul) {\n margin: 0;\n font: inherit;\n letter-spacing: inherit;\n}\n\n.ds-footer__brand {\n display: flex;\n flex: 0 0 calc(12 * var(--ds-unit));\n flex-direction: column;\n max-width: 100%;\n min-width: 0;\n}\n\n.ds-footer__mark {\n display: inline-flex;\n align-items: center;\n gap: calc(var(--ds-unit) / 2);\n align-self: flex-start;\n height: var(--ds-unit);\n color: inherit;\n font-family: var(--ds-typeface-medium);\n font-weight: var(--ds-type-weight-bold);\n text-decoration: none;\n}\n\n.ds-footer__mark :is(img, svg) {\n display: block;\n width: auto;\n height: var(--ds-unit);\n}\n\n.ds-footer__tagline,\n.ds-footer__legal {\n color: var(--ds-text-color-muted);\n}\n\n.ds-footer__columns {\n display: flex;\n /* Never narrower than one column: below that the columns go under the brand. */\n flex: 1 1 calc(8 * var(--ds-unit));\n flex-wrap: wrap;\n gap: var(--ds-unit) calc(2 * var(--ds-unit));\n min-width: min(100%, calc(8 * var(--ds-unit)));\n}\n\n.ds-footer__column {\n display: flex;\n flex: 0 0 calc(8 * var(--ds-unit));\n flex-direction: column;\n max-width: 100%;\n min-width: 0;\n}\n\n.ds-footer .ds-footer__heading {\n color: var(--ds-title-color);\n}\n\n.ds-footer .ds-footer__links {\n padding: 0;\n list-style: none;\n}\n\n.ds-footer__links li {\n margin: 0;\n padding: 0;\n}\n\n.ds-footer__links a {\n display: inline-block;\n max-width: 100%;\n overflow: hidden;\n color: inherit;\n text-decoration-line: underline;\n text-decoration-thickness: 1px;\n text-decoration-color: transparent;\n text-overflow: ellipsis;\n text-underline-offset: calc(2px * var(--ds-sf));\n vertical-align: top;\n white-space: nowrap;\n}\n\n.ds-footer__links a:hover {\n text-decoration-color: color-mix(in srgb, currentColor 40%, transparent);\n}\n\n.ds-footer__links a[aria-current]:not([aria-current=\"false\"]) {\n text-decoration-color: currentColor;\n}\n\n:is(.ds-footer__links a, .ds-footer__mark):focus-visible {\n outline: 2px solid var(--ds-focus-ring);\n outline-offset: 1px;\n}\n\n/* The last row, two squares below: the legal line at the start, the\n preferences at the end; on a narrow screen the preferences go first. */\n.ds-footer__base {\n display: flex;\n flex: 0 0 100%;\n flex-wrap: wrap;\n align-items: flex-start;\n gap: var(--ds-unit) calc(2 * var(--ds-unit));\n min-width: 0;\n}\n\n.ds-footer__legal {\n flex: 1 1 auto;\n min-width: 0;\n}\n\n.ds-footer__preferences {\n display: flex;\n flex: 0 0 auto;\n flex-wrap: wrap;\n align-items: center;\n gap: 0 calc(var(--ds-unit) / 2);\n min-height: var(--ds-unit);\n margin-inline-start: auto;\n}\n\n@container (max-width: 599px) {\n .ds-footer__brand,\n .ds-footer__columns {\n flex-basis: 100%;\n }\n\n .ds-footer__base {\n flex-direction: column;\n }\n\n .ds-footer__preferences {\n order: -1;\n margin-inline-start: 0;\n }\n}\n/*\n * A document page: terms, a privacy policy, a legal notice, a help article.\n *\n * The contents stand at the start, twelve squares wide, and stay in view as\n * the writing scrolls past; the writing, two squares after them, is a reading\n * column of at most thirty-two squares, native headings and paragraphs marked\n * `data-ds-prose` (prose.css draws them). Where the two do not fit side by\n * side the contents stand above the writing. Every line is one square; the\n * contents' links are in the text's ink, the section in view (`aria-current`)\n * on a hairline of the full ink, a third level half a square in. The\n * `ds-document` element builds the contents from the headings and marks the\n * one in view.\n *\n * ds-document the page's two columns\n * ds-document__toc the contents, a <nav>, as tall as the writing\n * ds-document__contents inside it, what stays in view: the title and the list\n * ds-document__toc-title \"Contents\", one line in the title grey\n * ds-document__toc-list the links, an <ol> with one link per <li>\n * ds-document__toc-sub an <li> for a third-level heading\n * ds-document__body the writing, marked data-ds-prose\n *\n * A definition table (`ds-definitions` on a <dl>) sets terms beside what they\n * mean, as a legal notice such as 特定商取引法に基づく表記 does: the term eight\n * squares wide in the muted ink, its definition beside it, each pair on a\n * hairline at its foot with half a square above and below, as a prose table's\n * rows are. Pairs may stand in a <div> each. Below twenty-four squares the\n * definition goes under its term. It works inside or outside prose.\n *\n * Tokens: `--ds-document-top` (where the contents stop below the top of the\n * view, one square; add a sticky header's height), `--ds-definitions-term`\n * (the term column, eight squares).\n */\n\n.ds-document {\n box-sizing: border-box;\n display: flex;\n flex-wrap: wrap;\n align-items: stretch;\n gap: var(--ds-unit) calc(2 * var(--ds-unit));\n min-width: 0;\n color: var(--ds-text-color);\n font-family: var(--ds-typeface-regular);\n font-feature-settings: var(--ds-font-features);\n font-size: var(--ds-type-size-default);\n font-weight: var(--ds-type-weight-default);\n line-height: var(--ds-unit);\n letter-spacing: var(--ds-type-letterspacing-default);\n}\n\n/* The contents column stretches to the writing's height when the two stand\n side by side, so what is inside it can stay in view; standing above the\n writing it is only as tall as itself, and nothing sticks. */\n.ds-document__toc {\n flex: 0 0 calc(12 * var(--ds-unit));\n max-width: 100%;\n min-width: 0;\n}\n\n.ds-document__contents {\n position: sticky;\n top: var(--ds-document-top, var(--ds-unit));\n}\n\n.ds-document__toc-title {\n margin: 0;\n color: var(--ds-title-color);\n font: inherit;\n letter-spacing: inherit;\n}\n\n.ds-document__toc-list,\n.ds-document__toc-list ol {\n margin: 0;\n padding: 0;\n list-style: none;\n}\n\n.ds-document__toc-list li {\n margin: 0;\n padding: 0;\n}\n\n.ds-document__toc-list .ds-document__toc-sub {\n padding-inline-start: calc(var(--ds-unit) / 2);\n}\n\n.ds-document__toc-list a {\n display: block;\n overflow: hidden;\n color: inherit;\n text-decoration-line: underline;\n text-decoration-thickness: 1px;\n text-decoration-color: transparent;\n text-overflow: ellipsis;\n text-underline-offset: calc(2px * var(--ds-sf));\n white-space: nowrap;\n}\n\n.ds-document__toc-list a:hover {\n text-decoration-color: color-mix(in srgb, currentColor 40%, transparent);\n}\n\n.ds-document__toc-list a[aria-current]:not([aria-current=\"false\"]) {\n text-decoration-color: currentColor;\n}\n\n.ds-document__toc-list a:focus-visible {\n outline: 2px solid var(--ds-focus-ring);\n outline-offset: -1px;\n}\n\n/* The writing: at least twenty squares beside the contents, else below them. */\n.ds-document__body {\n flex: 1 1 0;\n min-width: min(100%, calc(20 * var(--ds-unit)));\n max-width: calc(32 * var(--ds-unit));\n}\n\n/* A heading the contents jump to stops where the contents do. */\n.ds-document__body :is(h1, h2, h3, h4, h5, h6) {\n scroll-margin-top: var(--ds-document-top, var(--ds-unit));\n}\n\n/* A definition table. */\n\n.ds-definitions {\n box-sizing: border-box;\n container-type: inline-size;\n display: grid;\n grid-template-columns: minmax(0, var(--ds-definitions-term, calc(8 * var(--ds-unit)))) minmax(0, 1fr);\n margin: 0;\n padding: 0;\n color: var(--ds-text-color);\n font-family: var(--ds-typeface-regular);\n font-size: var(--ds-type-size-default);\n line-height: var(--ds-unit);\n letter-spacing: var(--ds-type-letterspacing-default);\n}\n\n.ds-definitions > div {\n display: contents;\n}\n\n.ds-definitions :is(dt, dd) {\n box-sizing: border-box;\n min-width: 0;\n margin: 0;\n padding-block: calc(var(--ds-unit) / 2);\n box-shadow: inset 0 -1px var(--ds-border-color);\n font: inherit;\n letter-spacing: inherit;\n line-height: var(--ds-unit);\n overflow-wrap: anywhere;\n}\n\n.ds-definitions dt {\n grid-column: 1;\n padding-inline-end: calc(var(--ds-unit) / 2);\n color: var(--ds-text-color-muted);\n}\n\n.ds-definitions dd {\n grid-column: 2;\n}\n\n@container (max-width: 479px) {\n .ds-definitions dt,\n .ds-definitions dd {\n grid-column: 1 / -1;\n }\n\n .ds-definitions dt {\n padding-block-end: 0;\n padding-inline-end: 0;\n box-shadow: none;\n }\n\n .ds-definitions dd {\n padding-block-start: 0;\n }\n}\n/*\n * A bento, as plain classes on native elements: tiles of different sizes\n * standing half a square (10px) apart, each a card (`.ds-card`, or any box)\n * that holds one thing. The `ds-bento` element draws the same.\n *\n * Flow (the default): columns that share the width (`--ds-bento-columns`,\n * three), a tile one column wide or more (`data-span`, or\n * `--ds-bento-span`) and one row high or more (`data-rows`, or\n * `--ds-bento-rows`); a row is as high as its tallest tile, at least\n * `--ds-bento-row` (ten squares by default). Below thirty squares of width\n * the bento is one column.\n *\n * Squares (`data-squares`): the bento is exactly `--ds-bento-columns` squares wide\n * and every tile is placed on whole squares (`data-place=\"x y w h\"`,\n * counted from 0). Tiles are placed a square apart, and a tile's surface\n * reaches a quarter square towards each tile beside it, so they stand half a\n * square apart while what they hold stays on the squares, and the bento's\n * own edges stay on the page's. `placeBento()` (0-face/bento.ts) reads the\n * places and sets the reach; the element does it itself.\n *\n * data-span=\"2\" a tile two columns wide (to 6)\n * data-rows=\"2\" a tile two rows high (to 6)\n * data-place=\"0 0 15 7\" a tile's square, width and height in squares\n *\n * `data-fit` lets a squares bento's columns share a measure other than its\n * squares (each tile still reaches a quarter square, so the gap is a column\n * less half a square); `data-layout` (say `phone`) makes `placeBento()` take each tile's\n * `data-place-phone` where it has one, a place per layout.\n *\n * Tokens: `--ds-bento-unit` (the square, `--ds-unit` by default),\n * `--ds-bento-gap` (half of it), `--ds-bento-columns`, `--ds-bento-row`,\n * `--ds-bento-padding` (a squares tile that is not a card, one square), and\n * on a tile `--ds-bento-span`, `--ds-bento-rows`.\n */\n\n.ds-bento {\n --ds-bento-unit: var(--ds-unit);\n --ds-bento-gap: calc(var(--ds-bento-unit) / 2);\n box-sizing: border-box;\n display: grid;\n grid-template-columns: repeat(var(--ds-bento-columns, 3), minmax(0, 1fr));\n grid-auto-rows: minmax(var(--ds-bento-row, calc(10 * var(--ds-bento-unit))), auto);\n grid-auto-flow: row dense;\n gap: var(--ds-bento-gap);\n margin: 0;\n padding: 0;\n list-style: none;\n}\n.ds-bento[hidden] { display: none; }\n\n.ds-bento > * {\n --ds-card-width: auto;\n --ds-card-height: auto;\n box-sizing: border-box;\n min-width: 0;\n min-height: 0;\n grid-column: span var(--ds-bento-span, 1);\n grid-row: span var(--ds-bento-rows, 1);\n}\n.ds-bento > [data-span=\"2\"] { --ds-bento-span: 2; }\n.ds-bento > [data-span=\"3\"] { --ds-bento-span: 3; }\n.ds-bento > [data-span=\"4\"] { --ds-bento-span: 4; }\n.ds-bento > [data-span=\"5\"] { --ds-bento-span: 5; }\n.ds-bento > [data-span=\"6\"] { --ds-bento-span: 6; }\n.ds-bento > [data-rows=\"2\"] { --ds-bento-rows: 2; }\n.ds-bento > [data-rows=\"3\"] { --ds-bento-rows: 3; }\n.ds-bento > [data-rows=\"4\"] { --ds-bento-rows: 4; }\n.ds-bento > [data-rows=\"5\"] { --ds-bento-rows: 5; }\n.ds-bento > [data-rows=\"6\"] { --ds-bento-rows: 6; }\n\n@media (max-width: 600px) {\n .ds-bento:not([data-squares]) { grid-template-columns: minmax(0, 1fr); }\n .ds-bento:not([data-squares]) > * { grid-column: auto; }\n}\n\n/* Squares: every tile on whole squares, a square apart, its surface a quarter square nearer each neighbour. */\n.ds-bento[data-squares] {\n --ds-bento-reach: calc(var(--ds-bento-unit) / 4);\n /* Exactly its squares wide: each column one square. */\n width: calc(var(--ds-bento-columns, 48) * var(--ds-bento-unit));\n max-width: none;\n grid-template-columns: repeat(var(--ds-bento-columns, 48), var(--ds-bento-unit));\n grid-auto-rows: var(--ds-bento-unit);\n grid-auto-flow: row;\n gap: 0;\n}\n/* Fit: the columns share a measure narrower (or wider) than the squares, the rows still one square. */\n.ds-bento[data-squares][data-fit] {\n width: auto;\n grid-template-columns: repeat(var(--ds-bento-columns, 48), minmax(0, 1fr));\n}\n.ds-bento[data-squares] > * {\n --ds-bento-inset-top: calc(var(--ds-bento-reach) * var(--ds-bento-top, 0));\n --ds-bento-inset-end: calc(var(--ds-bento-reach) * var(--ds-bento-end, 0));\n --ds-bento-inset-bottom: calc(var(--ds-bento-reach) * var(--ds-bento-bottom, 0));\n --ds-bento-inset-start: calc(var(--ds-bento-reach) * var(--ds-bento-start, 0));\n grid-column: calc(var(--ds-bento-x, 0) + 1) / span var(--ds-bento-w, 4);\n grid-row: calc(var(--ds-bento-y, 0) + 1) / span var(--ds-bento-h, 4);\n margin: calc(-1 * var(--ds-bento-inset-top)) calc(-1 * var(--ds-bento-inset-end)) calc(-1 * var(--ds-bento-inset-bottom)) calc(-1 * var(--ds-bento-inset-start));\n}\n/* A card grows its own padding by the reach (card.css); any other tile is padded here, a square inside. */\n.ds-bento[data-squares] > :not(.ds-card, ds-card) {\n padding:\n calc(var(--ds-bento-padding, var(--ds-bento-unit)) + var(--ds-bento-inset-top))\n calc(var(--ds-bento-padding, var(--ds-bento-unit)) + var(--ds-bento-inset-end))\n calc(var(--ds-bento-padding, var(--ds-bento-unit)) + var(--ds-bento-inset-bottom))\n calc(var(--ds-bento-padding, var(--ds-bento-unit)) + var(--ds-bento-inset-start));\n}\n/*\n * A carousel, as plain classes on native elements.\n *\n * A carousel is a row of slides that snaps sideways, one slide to a stop,\n * with a row of controls one square high under it: optional previous and\n * next buttons and a dot for each slide. Slides are the track's width, or\n * whole squares wide, a whole number of squares apart (one by default). The\n * controls stand one square below the track, on the grid from its start.\n * The `ds-carousel` element draws the same parts, and\n * `0-face/carousel.ts` gives the native markup its behaviour.\n *\n * ds-carousel the region: track, controls, status;\n * `data-slides=\"auto\"` for slides of their\n * own width, `data-bleed` `end` or `both`,\n * `data-snap=\"none\"` to slide freely\n * ds-carousel__track the scroller; every child is a slide\n * ds-carousel__controls the row of buttons and dots\n * ds-carousel__previous, __next, icon buttons, on `.ds-button.ds-button--icon`\n * __pause\n * ds-carousel__status the polite announcement, kept out of sight\n *\n * The dots are `ds-progress--dots` from progress.css.\n *\n * A strip of slides of their own width can run on past its box to the\n * window's end edge, or to both edges, while its first slide keeps to the\n * box's start, so it lines up with the page's column; `--ds-carousel-before`\n * and `--ds-carousel-after` are the room to the edges, which the script\n * measures.\n *\n * Tokens: `--ds-carousel-slide` (a slide's width, the track's by default)\n * and `--ds-carousel-gap` (between slides, one square by default).\n */\n\n.ds-carousel {\n box-sizing: border-box;\n display: grid;\n grid-template-columns: minmax(0, 1fr);\n row-gap: var(--ds-unit);\n position: relative;\n min-width: 0;\n margin: 0;\n}\n\n.ds-carousel__track {\n box-sizing: border-box;\n display: grid;\n grid-auto-flow: column;\n grid-auto-columns: var(--ds-carousel-slide, 100%);\n column-gap: var(--ds-carousel-gap, var(--ds-unit));\n min-width: 0;\n margin: 0;\n padding: 0;\n list-style: none;\n overflow-x: auto;\n overflow-y: hidden;\n overscroll-behavior-x: contain;\n scroll-snap-type: x mandatory;\n scrollbar-width: none;\n}\n\n.ds-carousel__track::-webkit-scrollbar {\n display: none;\n}\n\n/* Slides of their own width, several in view. */\n.ds-carousel[data-slides=\"auto\"] > .ds-carousel__track {\n grid-auto-columns: max-content;\n}\n\n.ds-carousel[data-snap=\"none\"] > .ds-carousel__track {\n scroll-snap-type: none;\n}\n\n/* To the window's end edge: the track reaches out over the room after the\n box and keeps a gap at its end, so the last slide stops short of the edge. */\n.ds-carousel[data-bleed=\"end\"] > .ds-carousel__track {\n margin-inline-end: calc(-1 * var(--ds-carousel-after, 0px));\n padding-inline-end: var(--ds-carousel-gap, var(--ds-unit));\n}\n\n/* To both edges: the track reaches out both ways, and the first slide, and\n each one it stops at, still stands on the box's start. */\n.ds-carousel[data-bleed=\"both\"] > .ds-carousel__track {\n margin-inline: calc(-1 * var(--ds-carousel-before, 0px)) calc(-1 * var(--ds-carousel-after, 0px));\n padding-inline: var(--ds-carousel-before, 0px) var(--ds-carousel-gap, var(--ds-unit));\n scroll-padding-inline-start: var(--ds-carousel-before, 0px);\n}\n\n.ds-carousel__track:focus-visible {\n outline: 2px solid var(--ds-focus-ring);\n outline-offset: 1px;\n}\n\n.ds-carousel__track > * {\n box-sizing: border-box;\n min-width: 0;\n margin: 0;\n scroll-snap-align: start;\n}\n\n/* One slide to a stop; a strip of several in view may pass a few. */\n.ds-carousel:not([data-slides=\"auto\"]) > .ds-carousel__track > * {\n scroll-snap-stop: always;\n}\n\n.ds-carousel__controls {\n display: flex;\n align-items: center;\n height: var(--ds-row-height);\n min-width: 0;\n}\n\n/* The buttons take a one-square cell each, as the dots do. Two classes, so\n the button's own reset of its margin does not undo it. */\n.ds-carousel .ds-carousel__previous,\n.ds-carousel .ds-carousel__next,\n.ds-carousel .ds-carousel__pause {\n flex: none;\n margin: calc((var(--ds-unit) - var(--ds-control-height)) / 2);\n}\n\n/* Previous points back along the reading direction. */\n.ds-carousel:dir(rtl) :is(.ds-carousel__previous, .ds-carousel__next) > * {\n transform: scaleX(-1);\n}\n\n.ds-carousel__status {\n position: absolute;\n width: 1px;\n height: 1px;\n overflow: hidden;\n clip-path: inset(50%);\n white-space: nowrap;\n}\n/*\n * A card, as plain classes on native elements.\n *\n * A card holds one thing on a fill of its own: its name in the muted ink on\n * one square, a title in the display size on lines of a square and a half, writing,\n * and a picture of it (`ds-card__media`) a square below, which can run off\n * the card's foot and end edge and be cut there, never framed. Its size is\n * given in whole squares, its padding one square, its corners a card's\n * (`--ds-radius-card`). A card that opens something is one press target, an\n * `<a class=\"ds-card\" href>`: the pointer tints it, keyboard focus rings it\n * 2px inside and its picture rises a little. Ordinary writing still sits\n * straight on the paper; a card is for a thing shown among others, as in a\n * slide. The `ds-card` element draws the same parts.\n *\n * ds-card the card; `data-tone` names a palette colour\n * for its fill (the colour's pastel, dim in dark\n * mode, from palette.css, which one.css imports),\n * `ink` for the ink with the paper's words\n * ds-card--outlined a 1px line and no fill\n * ds-card__label its name, muted, on one square\n * ds-card__title the title, display size, a square and a half a line\n * ds-card__body writing, one square a line\n * ds-card__media the picture, a square below the words\n * ds-card__media--center standing in the card's middle\n * ds-card__media--bleed running on past the padding to the end edge\n *\n * Tokens: `--ds-card-width` and `--ds-card-height` (whole squares; the\n * content's size by default), `--ds-card-padding` (one square), and\n * `--ds-card-fill`, `--ds-card-ink` and `--ds-card-muted`.\n */\n\n.ds-card {\n --ds-card-fill: var(--ds-fill);\n --ds-card-ink: var(--ds-text-color);\n --ds-card-muted: var(--ds-text-color-muted);\n --ds-card-padding: var(--ds-unit);\n position: relative;\n box-sizing: border-box;\n display: flex;\n flex-direction: column;\n align-items: stretch;\n width: var(--ds-card-width, auto);\n height: var(--ds-card-height, auto);\n min-width: 0;\n margin: 0;\n /* In a squares bento the surface reaches a quarter square towards its neighbours (`--ds-bento-inset-*`, 0 elsewhere), and the padding grows by as much so what it holds stays on the squares. */\n padding:\n calc(var(--ds-card-padding) + var(--ds-bento-inset-top, 0px))\n calc(var(--ds-card-padding) + var(--ds-bento-inset-end, 0px))\n var(--ds-bento-inset-bottom, 0px)\n calc(var(--ds-card-padding) + var(--ds-bento-inset-start, 0px));\n overflow: hidden;\n border-radius: var(--ds-radius-card);\n background: var(--ds-card-fill);\n color: var(--ds-card-ink);\n font-family: var(--ds-typeface-regular);\n font-size: var(--ds-type-size-default);\n text-decoration: none;\n -webkit-tap-highlight-color: transparent;\n}\n\n.ds-card[hidden] {\n display: none;\n}\n\n.ds-card--outlined {\n --ds-card-fill: transparent;\n box-shadow: inset 0 0 0 1px var(--ds-border-color);\n}\n\n.ds-card[data-tone=\"apple-green\"] { --ds-card-fill: var(--one-apple-green-pastel); }\n.ds-card[data-tone=\"chartreuse\"] { --ds-card-fill: var(--one-chartreuse-pastel); }\n.ds-card[data-tone=\"every-green\"] { --ds-card-fill: var(--one-every-green-pastel); }\n.ds-card[data-tone=\"yellow\"] { --ds-card-fill: var(--one-yellow-pastel); }\n.ds-card[data-tone=\"orange\"] { --ds-card-fill: var(--one-orange-pastel); }\n.ds-card[data-tone=\"tuned-red\"] { --ds-card-fill: var(--one-tuned-red-pastel); }\n.ds-card[data-tone=\"pink\"] { --ds-card-fill: var(--one-pink-pastel); }\n.ds-card[data-tone=\"sharp-blue\"] { --ds-card-fill: var(--one-sharp-blue-pastel); }\n.ds-card[data-tone=\"winning-blue\"] { --ds-card-fill: var(--one-winning-blue-pastel); }\n.ds-card[data-tone=\"hysteric-blue\"] { --ds-card-fill: var(--one-hysteric-blue-pastel); }\n.ds-card[data-tone=\"purple\"] { --ds-card-fill: var(--one-purple-pastel); }\n.ds-card[data-tone=\"metal-green\"] { --ds-card-fill: var(--one-metal-green-pastel); }\n.ds-card[data-tone=\"drip-yellow\"] { --ds-card-fill: var(--one-drip-yellow-pastel); }\n.ds-card[data-tone=\"sand\"] { --ds-card-fill: var(--one-sand-pastel); }\n.ds-card[data-tone=\"old-gold\"] { --ds-card-fill: var(--one-old-gold-pastel); }\n.ds-card[data-tone=\"red-for-blood\"] { --ds-card-fill: var(--one-red-for-blood-pastel); }\n.ds-card[data-tone=\"dark-red-variant\"] { --ds-card-fill: var(--one-dark-red-variant-pastel); }\n.ds-card[data-tone=\"signal-red\"] { --ds-card-fill: var(--one-signal-red-pastel); }\n.ds-card[data-tone=\"ink\"] {\n --ds-card-fill: var(--ds-black);\n --ds-card-ink: var(--ds-white);\n --ds-card-muted: color-mix(in srgb, var(--ds-white) 60%, transparent);\n box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--ds-white) 8%, transparent);\n}\n\n/* Words: each line on the lower sixteen of its square. They keep their room\n in a card of a set height; only the picture is cut at the foot. */\n.ds-card__label,\n.ds-card__title,\n.ds-card__body {\n flex: none;\n}\n\n.ds-card__label {\n margin: 0;\n padding-top: calc(4px * var(--ds-sf, 1));\n color: var(--ds-card-muted);\n font: inherit;\n line-height: var(--ds-type-lineheight-default, calc(16px * var(--ds-sf, 1)));\n}\n\n.ds-card__title {\n margin: 0;\n color: var(--ds-card-ink);\n font-family: var(--ds-typeface-medium);\n font-size: var(--ds-type-size-display);\n font-weight: var(--ds-type-weight-bold);\n /* A title that wraps keeps its lines together: a square and a half each. */\n line-height: calc(1.5 * var(--ds-unit));\n letter-spacing: calc(var(--ds-display-text-tracking, -0.4px) * var(--ds-sf, 1));\n text-wrap: balance;\n}\n\n.ds-card__body {\n margin: 0;\n line-height: var(--ds-unit);\n}\n\n.ds-card__media {\n display: flex;\n flex: none;\n align-items: flex-start;\n justify-content: flex-start;\n min-width: 0;\n margin-top: var(--ds-unit);\n}\n\n.ds-card__media--center {\n justify-content: center;\n margin-inline: calc(-1 * var(--ds-card-padding));\n}\n\n.ds-card__media--bleed {\n margin-inline-end: calc(-1 * var(--ds-card-padding));\n}\n\n.ds-card__media > * {\n flex: none;\n}\n\n/* A card that opens something. */\na.ds-card,\n.ds-card[data-interactive] {\n cursor: pointer;\n}\n\na.ds-card::after,\n.ds-card[data-interactive]::after {\n content: \"\";\n position: absolute;\n inset: 0;\n border-radius: inherit;\n background: transparent;\n pointer-events: none;\n}\n\na.ds-card:focus-visible,\n.ds-card[data-interactive]:focus-visible {\n outline: 2px solid var(--ds-focus-ring);\n outline-offset: -2px;\n}\n\n@media (hover: hover) {\n a.ds-card:hover::after,\n .ds-card[data-interactive]:hover::after {\n background: color-mix(in srgb, var(--ds-card-ink) 4%, transparent);\n }\n}\n\na.ds-card:active::after,\n.ds-card[data-interactive]:active::after {\n background: color-mix(in srgb, var(--ds-card-ink) 8%, transparent);\n}\n\n@media (hover: hover) and (prefers-reduced-motion: no-preference) {\n a.ds-card > .ds-card__media,\n .ds-card[data-interactive] > .ds-card__media {\n transition: transform 240ms cubic-bezier(0.23, 1, 0.32, 1);\n }\n\n a.ds-card:hover > .ds-card__media,\n .ds-card[data-interactive]:hover > .ds-card__media {\n transform: translateY(calc(-0.25 * var(--ds-unit)));\n }\n}\n/*\n * Figures, as plain classes on native elements: a stat and a group of stats.\n * The `ds-stat` element draws the same parts; controls.css imports this\n * file. A value against its range, steps and page dots are `progress.css`.\n *\n * Everything sits on the paper with no box, every line is one square and\n * widths come in whole squares. Colour is kept for a state: the danger colour\n * for a figure that is over.\n *\n * A stat: a label, a figure and a line for its change or caption.\n *\n * ds-stat the block, as wide as its column\n * ds-stat__label one line, muted; an icon may lead it on its own square\n * ds-stat__icon the square an icon from the library stands on\n * ds-stat__figure the figure in tabular numerals, 20 on two squares\n * ds-stat__digit one digit in a cell of one width, for a face without tabular numerals\n * ds-stat__caption one line, muted, under the figure\n * ds-stat__change the change at the start of the caption, in the text colour;\n * --danger or --warning where the page knows which way is bad\n * ds-stat--danger, --warning the figure in that colour\n * ds-stats a group of stats on whole squares: columns eight\n * squares wide, one square between them and between rows\n *\n * Tokens: `--ds-stat-size` (the figure's type size before the scale, 20px)\n * and `--ds-stat-lines` (the squares its line takes, 2), `--ds-stat-typeface`\n * (the medium face), `--ds-stat-digit` (a digit cell's width, 1ch),\n * `--ds-stat-change-color`, and `--ds-stats-width` (a column's width in\n * squares, 8).\n *\n */\n\n/* ---- Stat ------------------------------------------------------------ */\n\n.ds-stat {\n box-sizing: border-box;\n display: flex;\n flex-direction: column;\n align-items: flex-start;\n min-width: 0;\n margin: 0;\n color: var(--ds-text-color);\n font-family: var(--ds-typeface-regular);\n font-feature-settings: var(--ds-font-features);\n font-size: var(--ds-type-size-default);\n font-weight: var(--ds-type-weight-default);\n line-height: var(--ds-unit);\n letter-spacing: var(--ds-type-letterspacing-default);\n text-transform: none;\n}\n\n.ds-stat__label,\n.ds-stat__figure,\n.ds-stat__caption {\n box-sizing: border-box;\n max-width: 100%;\n margin: 0;\n font: inherit;\n letter-spacing: inherit;\n}\n\n.ds-stat__label,\n.ds-stat__caption {\n display: flex;\n align-items: flex-start;\n min-height: var(--ds-unit);\n color: var(--ds-text-color-muted);\n overflow-wrap: anywhere;\n}\n\n.ds-stat__icon {\n display: inline-flex;\n flex: none;\n align-items: center;\n justify-content: center;\n width: var(--ds-unit);\n height: var(--ds-unit);\n}\n\n.ds-stat__figure {\n display: block;\n overflow: hidden;\n font-family: var(--ds-stat-typeface, var(--ds-typeface-medium));\n font-size: calc(var(--ds-stat-size, var(--ds-display-text-size, 20px)) * var(--ds-sf, 1));\n font-weight: var(--ds-type-weight-bold);\n font-variant-numeric: tabular-nums;\n line-height: calc(var(--ds-stat-lines, 2) * var(--ds-unit));\n min-height: calc(var(--ds-stat-lines, 2) * var(--ds-unit));\n letter-spacing: calc(var(--ds-display-text-tracking, -0.4px) * var(--ds-sf, 1));\n white-space: nowrap;\n text-overflow: ellipsis;\n}\n\n.ds-stat__digit {\n display: inline-block;\n width: var(--ds-stat-digit, 1ch);\n text-align: center;\n}\n\n.ds-stat--danger .ds-stat__figure {\n color: var(--ds-danger-color);\n}\n\n.ds-stat--warning .ds-stat__figure {\n color: var(--ds-warning-color);\n}\n\n.ds-stat__change {\n display: inline-flex;\n flex: none;\n align-items: center;\n height: var(--ds-unit);\n margin-inline-end: calc(4px * var(--ds-sf, 1));\n color: var(--ds-stat-change-color, var(--ds-text-color));\n font-variant-numeric: tabular-nums;\n white-space: nowrap;\n}\n\n.ds-stat__change--danger {\n --ds-stat-change-color: var(--ds-danger-color);\n}\n\n.ds-stat__change--warning {\n --ds-stat-change-color: var(--ds-warning-color);\n}\n\n.ds-stats {\n box-sizing: border-box;\n display: grid;\n grid-template-columns: repeat(auto-fill, min(100%, calc(var(--ds-stats-width, 8) * var(--ds-unit))));\n gap: var(--ds-unit);\n margin: 0;\n padding: 0;\n list-style: none;\n}\n\n.ds-stats > li {\n min-width: 0;\n margin: 0;\n}\n/*\n * Progress, as plain classes on native elements: a value against its range,\n * a sequence of steps, or a dot for each page. The `ds-progress` element\n * draws the same parts; controls.css imports this file.\n *\n * Everything sits on the paper with no box, every line is one square and\n * widths come in whole squares. Colour is kept for a state: the danger colour\n * for a value that is over or a step that failed, the ink for the current\n * step and the current dot.\n *\n * A value against its range, one square high (HTML's <progress>):\n *\n * ds-progress the row; role=\"meter\" with aria-valuenow, -min, -max and -valuetext\n * ds-progress__fill the bar, half a square high, drawn to --ds-progress-value (0 to 1)\n * ds-progress--squares the range in squares instead, each one square\n * ds-progress__square one square of the range; --on when it is filled\n * ds-progress--over past the end: filled whole in the danger colour\n *\n * Tokens: `--ds-progress-value`, `--ds-progress-color` (the ink by default)\n * and `--ds-progress-track` (the grey fill).\n *\n * A sequence of steps, one square high, each step on whole squares:\n *\n * ds-progress--steps with ds-progress, on an <ol>; the steps on one row, joined by a line\n * ds-progress--vertical one step to a row, each with room for its body under it\n * ds-progress__step an <li>; aria-current=\"step\" on the current one\n * ds-progress__step--done, --current, --failed states; upcoming without one\n * ds-progress__link a step that goes somewhere: an <a href> around its mark and label\n * ds-progress__mark the number (or the done or failed icon), one control high\n * ds-progress__label the step's name on one line\n * ds-progress__state the state in words for assistive technology, hidden (\"Done\")\n * ds-progress__body what belongs under a step in a vertical sequence\n *\n * A dot for each page, one square each:\n *\n * ds-progress--dots with ds-progress, a group of dots (role=\"group\")\n * ds-progress__dot a button; `data-state` is `past`, `current` (with\n * `aria-current=\"true\"`), `next`, `future`, or `end` for a\n * last dot marked as an end\n *\n * Tokens: the dot colours `--ds-progress-dot-past` and `-future` (the muted\n * text colour by default), `-current`, `-next` and `-end` (the text colour),\n * set on the dots or any element around them. Past, current and next dots are\n * filled; future dots and the end marker are rings.\n */\n\n/* ---- A value against its range: the bar, or the range in squares ---- */\n\n.ds-progress {\n box-sizing: border-box;\n position: relative;\n display: block;\n width: 100%;\n height: var(--ds-unit);\n margin: 0;\n}\n\n/* The range and its bar are a band half a square high across the middle of\n the row, as a chart's ratio is drawn. */\n.ds-progress:not(.ds-progress--squares, .ds-progress--steps, .ds-progress--dots)::before,\n.ds-progress__fill {\n position: absolute;\n inset-inline: 0;\n top: calc(var(--ds-unit) / 4);\n height: calc(var(--ds-unit) / 2);\n}\n\n.ds-progress:not(.ds-progress--squares, .ds-progress--steps, .ds-progress--dots)::before {\n content: \"\";\n background: var(--ds-progress-track, var(--ds-fill));\n}\n\n.ds-progress__fill {\n display: block;\n background: var(--ds-progress-color, var(--ds-text-color));\n transform: scaleX(var(--ds-progress-value, 0));\n transform-origin: left center;\n transition: transform 0.4s cubic-bezier(0.2, 0.8, 0.2, 1);\n}\n\n.ds-progress__fill:dir(rtl) {\n transform-origin: right center;\n}\n\n.ds-progress--over .ds-progress__fill {\n background: var(--ds-danger-color);\n transform: none;\n}\n\n.ds-progress--squares {\n display: flex;\n width: max-content;\n max-width: 100%;\n overflow: hidden;\n}\n\n.ds-progress__square {\n flex: none;\n width: calc(var(--ds-unit) - 1px);\n height: calc(var(--ds-unit) - 1px);\n margin-inline-end: 1px;\n background: var(--ds-progress-track, var(--ds-fill));\n}\n\n.ds-progress__square--on {\n background: var(--ds-progress-color, var(--ds-text-color));\n}\n\n.ds-progress--over .ds-progress__square {\n background: var(--ds-danger-color);\n}\n\n@media (prefers-reduced-motion: reduce) {\n .ds-progress__fill {\n transition: none;\n }\n}\n\n/* ---- A sequence of steps --------------------------------------------- */\n\n.ds-progress--steps {\n box-sizing: border-box;\n position: static;\n display: flex;\n width: auto;\n height: auto;\n flex-wrap: wrap;\n align-items: flex-start;\n min-width: 0;\n margin: 0;\n padding: 0;\n list-style: none;\n color: var(--ds-text-color);\n font-family: var(--ds-typeface-regular);\n font-feature-settings: var(--ds-font-features);\n font-size: var(--ds-type-size-default);\n font-weight: var(--ds-type-weight-default);\n line-height: var(--ds-unit);\n letter-spacing: var(--ds-type-letterspacing-default);\n text-transform: none;\n}\n\n/* Each step rounds its width up to whole squares where the browser can size\n to content in calc; elsewhere it hugs its words. */\n.ds-progress__step {\n --ds-progress-mark: transparent;\n --ds-progress-mark-ink: var(--ds-text-color-muted);\n --ds-progress-mark-line: var(--ds-border-color);\n box-sizing: border-box;\n position: relative;\n display: flex;\n align-items: flex-start;\n min-width: 0;\n max-width: 100%;\n width: max-content;\n width: calc-size(max-content, round(up, size, var(--ds-unit)));\n min-height: var(--ds-unit);\n margin: 0;\n color: var(--ds-text-color-muted);\n}\n\n/* A line joins a step to the next: at least one square, across whatever the\n step's rounding leaves, a quarter of a square short of each end. */\n.ds-progress__step:not(:last-child)::after {\n content: \"\";\n flex: 1 0 var(--ds-unit);\n height: var(--ds-unit);\n background: linear-gradient(var(--ds-border-color), var(--ds-border-color)) center / calc(100% - var(--ds-unit) / 2) 1px no-repeat;\n}\n\n.ds-progress__step--done {\n --ds-progress-mark: var(--ds-fill);\n --ds-progress-mark-ink: var(--ds-text-color);\n --ds-progress-mark-line: transparent;\n color: var(--ds-text-color);\n}\n\n.ds-progress__step--current {\n --ds-progress-mark: var(--ds-text-color);\n --ds-progress-mark-ink: var(--ds-paper);\n --ds-progress-mark-line: transparent;\n color: var(--ds-text-color);\n}\n\n.ds-progress__step--failed {\n --ds-progress-mark: var(--ds-danger-color);\n --ds-progress-mark-ink: light-dark(var(--ds-white), var(--ds-black));\n --ds-progress-mark-line: transparent;\n color: var(--ds-danger-color);\n}\n\n.ds-progress__link {\n display: flex;\n align-items: flex-start;\n min-width: 0;\n color: inherit;\n text-decoration: none;\n border-radius: var(--ds-radius);\n}\n\n.ds-progress__link:hover .ds-progress__label {\n text-decoration: underline;\n text-decoration-thickness: 1px;\n text-underline-offset: calc(3px * var(--ds-sf, 1));\n}\n\n.ds-progress__link:focus-visible {\n outline: 2px solid var(--ds-focus-ring);\n outline-offset: -2px;\n}\n\n.ds-progress__mark {\n box-sizing: border-box;\n display: flex;\n flex: none;\n align-items: center;\n justify-content: center;\n width: var(--ds-control-height);\n height: var(--ds-control-height);\n margin: calc((var(--ds-unit) - var(--ds-control-height)) / 2);\n overflow: hidden;\n background: var(--ds-progress-mark);\n box-shadow: inset 0 0 0 1px var(--ds-progress-mark-line);\n color: var(--ds-progress-mark-ink);\n --ds-icon-color: var(--ds-progress-mark-ink);\n font-family: var(--ds-typeface-medium);\n font-size: var(--ds-type-size-small);\n font-weight: var(--ds-type-weight-bold);\n font-variant-numeric: tabular-nums;\n line-height: var(--ds-control-height);\n letter-spacing: 0;\n}\n\n.ds-progress__label {\n min-width: 0;\n padding-inline-end: calc(4px * var(--ds-sf, 1));\n overflow: hidden;\n white-space: nowrap;\n text-overflow: ellipsis;\n}\n\n.ds-progress__step--current .ds-progress__label {\n font-family: var(--ds-typeface-medium);\n font-weight: var(--ds-type-weight-bold);\n}\n\n.ds-progress__state {\n position: absolute;\n width: 1px;\n height: 1px;\n overflow: hidden;\n clip-path: inset(50%);\n white-space: nowrap;\n}\n\n.ds-progress--vertical {\n flex-direction: column;\n flex-wrap: nowrap;\n}\n\n.ds-progress--vertical .ds-progress__step {\n flex-wrap: wrap;\n width: 100%;\n}\n\n.ds-progress--vertical .ds-progress__step::after {\n content: none;\n}\n\n/* Its content stands in a column, so an inline element in it (text drawn by\n an element, say) takes its own lines rather than a line box's descent. */\n.ds-progress__body {\n box-sizing: border-box;\n display: flex;\n flex-direction: column;\n flex: 1 0 100%;\n min-width: 0;\n padding-inline-start: var(--ds-unit);\n color: var(--ds-text-color);\n}\n\n/* ---- A dot for each page ------------------------------------------- */\n\n.ds-progress--dots {\n position: static;\n display: inline-flex;\n width: auto;\n flex: none;\n align-items: center;\n height: var(--ds-row-height);\n margin: 0;\n padding: 0;\n}\n\n.ds-progress__dot {\n --ds-progress-dot-color: var(--ds-progress-dot-future, var(--ds-text-color-muted));\n appearance: none;\n box-sizing: border-box;\n display: inline-flex;\n flex: none;\n align-items: center;\n justify-content: center;\n width: var(--ds-unit);\n height: var(--ds-unit);\n margin: 0;\n padding: 0;\n border: 0;\n border-radius: var(--ds-radius);\n background: transparent;\n color: inherit;\n cursor: pointer;\n -webkit-tap-highlight-color: transparent;\n}\n\n/* The dot itself: 4px, scaled with the surface, a fifth of the square. */\n.ds-progress__dot::before {\n content: \"\";\n box-sizing: border-box;\n width: calc(4px * var(--ds-sf, 1));\n height: calc(4px * var(--ds-sf, 1));\n border-radius: 50%;\n background: transparent;\n box-shadow: inset 0 0 0 1px var(--ds-progress-dot-color);\n transition: transform 160ms ease-out;\n}\n\n.ds-progress__dot[data-state=\"past\"] { --ds-progress-dot-color: var(--ds-progress-dot-past, var(--ds-text-color-muted)); }\n.ds-progress__dot[data-state=\"next\"] { --ds-progress-dot-color: var(--ds-progress-dot-next, var(--ds-text-color)); }\n.ds-progress__dot[data-state=\"end\"] { --ds-progress-dot-color: var(--ds-progress-dot-end, var(--ds-text-color)); }\n.ds-progress__dot[aria-current=\"true\"] { --ds-progress-dot-color: var(--ds-progress-dot-current, var(--ds-text-color)); }\n\n.ds-progress__dot:is([data-state=\"past\"], [data-state=\"next\"], [aria-current=\"true\"])::before {\n background: var(--ds-progress-dot-color);\n}\n\n/* The current dot is half again as large. */\n.ds-progress__dot[aria-current=\"true\"]::before {\n transform: scale(1.5);\n}\n\n.ds-progress__dot:hover:not([aria-current=\"true\"])::before {\n transform: scale(1.25);\n}\n\n.ds-progress__dot:focus-visible {\n outline: 2px solid var(--ds-focus-ring);\n outline-offset: -2px;\n}\n\n@media (prefers-reduced-motion: reduce) {\n .ds-progress__dot::before {\n transition: none;\n }\n}\n/*\n * Rows, as plain classes on native elements: the `ds-row` and `ds-sidebar`\n * elements' look without the elements.\n *\n * A row is one square high, and what it holds stands on the lower sixteen of\n * the square with the spare four above, as Ezo sets every row: a line of\n * words on a 16px line box, a 16px icon and a 16px control all end on the\n * row's bottom line, so the capitals (7px below the top line, baseline 3px\n * above the next) are centred on an icon beside them. On an `<a href>` or a\n * `<button>` the whole row is one press target, a row, a tile or a card: the pointer over it, the\n * press and the focus ring cover the row, and its content keeps the row's\n * layout. A row that also holds controls of its own (a quick action, a link\n * in another cell) is any element, a `<li>`, a `<div>` or a `<tr>`, with one\n * `ds-row__target` inside: that link or button takes the press anywhere on\n * the row, and every other control inside stays separately pressable.\n *\n * ds-row a row one square high; a press target on <a> or <button>\n * ds-row__target the row's press target, when the row holds other controls\n * ds-row--auto as high as its content, at least one square\n * ds-row--stacked the content stacked, each line one square (a tile, a card)\n * ds-row--nav a navigation row: the sidebar's two-pixel corners\n * aria-current=\"page\" the destination being shown, filled and in the medium weight\n * aria-disabled=\"true\" or `disabled` on a button: dimmed, not pressable\n *\n * A sidebar of nested things (the `ds-sidebar tree` element without Lit) is a\n * `role=\"tree\"` list of `role=\"treeitem\"` rows, flat, each with its\n * `aria-level`, one square further in per level. `0-face/sidebar.ts`\n * (`connectSidebar`) gives it the keyboard of the tree pattern.\n *\n * ds-sidebar the tree (`role=\"tree\"`)\n * ds-sidebar__item a row (`role=\"treeitem\"`, `aria-level`, `aria-expanded` on a parent, `aria-selected`)\n * ds-sidebar__disclosure the arrow on its own square, turned down when the row is open; empty on a leaf\n * ds-sidebar__label the words, cut short with an ellipsis\n * ds-sidebar__meta small muted words at the row's end\n *\n * An icon (`.ds-icon`) in a tree row takes a square of its own. Tokens:\n * `--ds-row-padding` (the words' distance from the row's edges, 4px),\n * `--ds-row-fill-hover`, `--ds-row-fill-press`, `--ds-row-fill-current` and\n * `--ds-row-current-weight` (component-tokens.css, shared with the\n * element), `--ds-sidebar-disclosure` (the arrow's drawing, the library's\n * `right` icon) and `--ds-sidebar-indent` (a row's depth in squares, read\n * from `aria-level` up to twelve levels).\n */\n\n:where(.ds-row):not(tr) {\n box-sizing: border-box;\n display: flex;\n flex-direction: row;\n align-items: flex-end;\n gap: calc(4px * var(--ds-sf));\n min-width: 0;\n height: var(--ds-row-height);\n margin: 0;\n line-height: var(--ds-type-lineheight-default);\n}\n\n:where(.ds-row--auto):not(tr) {\n height: auto;\n min-height: var(--ds-row-height);\n}\n\n:where(.ds-row--stacked):not(tr) {\n flex-direction: column;\n align-items: flex-start;\n justify-content: flex-start;\n gap: 0;\n height: auto;\n}\n\n/* The press target: the row itself, or the one target inside it. */\na.ds-row,\nbutton.ds-row,\n.ds-row__target {\n appearance: none;\n box-sizing: border-box;\n margin: 0;\n border: 0;\n background: none;\n color: inherit;\n font: inherit;\n letter-spacing: inherit;\n text-align: start;\n text-decoration: none;\n text-transform: none;\n cursor: pointer;\n outline: none;\n -webkit-tap-highlight-color: transparent;\n}\n\n/* The font inherited above would bring the page's line into the row: the words go back on the\n sixteen, as every row's (a stacked tile keeps its square lines below). */\na.ds-row,\nbutton.ds-row {\n position: relative;\n width: 100%;\n line-height: var(--ds-type-lineheight-default);\n padding: 0 var(--ds-row-padding, calc(4px * var(--ds-sf)));\n border-radius: var(--ds-row-radius, 0);\n}\n\n.ds-row__target {\n padding: 0;\n}\n\n/* Each line of a tile one square, over the inherited font of a native link or button:\n a tile's lines wrap, so they stay on whole squares rather than the sixteen. */\n.ds-row.ds-row--stacked {\n line-height: var(--ds-row-height);\n}\n\n/* A row with a target inside: the target's layers cover the row. */\n.ds-row:has(.ds-row__target) {\n position: relative;\n isolation: isolate;\n}\n:where(.ds-row:has(.ds-row__target)):not(tr) {\n padding-inline: var(--ds-row-padding, calc(4px * var(--ds-sf)));\n}\n.ds-row__target::before,\n.ds-row__target::after {\n content: \"\";\n position: absolute;\n inset: 0;\n border-radius: var(--ds-row-radius, 0);\n}\n.ds-row__target::before { z-index: 1; }\n.ds-row__target::after { z-index: -1; }\n.ds-row:has(.ds-row__target) :where(a[href], button, input, select, textarea, label, summary, [tabindex]):not(.ds-row__target) {\n position: relative;\n z-index: 2;\n}\n\n/*\n * The pointer, the press, the current destination and the focus ring are one layer under the\n * row's content (Joachim, 19 October 2026). On a one-square row it is a square high and sits two\n * pixels around what the row holds: from two above the lower sixteen to two below the row's foot,\n * and two past the content at each side, its corners the icon tiles' 4px and those two more, so a\n * 16px icon stands in it with two all round. It is drawn over the row, never moving its words or\n * icons off the grid. An open row (`data-open`) wears the same layer. A taller row (a stacked\n * tile, `auto`) is filled whole.\n * Tokens: `--ds-row-fill-radius` (6px), `--ds-row-fill-overhang` (2px).\n */\na.ds-row,\nbutton.ds-row {\n isolation: isolate;\n}\na.ds-row::after,\nbutton.ds-row::after {\n content: \"\";\n position: absolute;\n z-index: -1;\n pointer-events: none;\n}\na.ds-row::after,\nbutton.ds-row::after,\n.ds-row__target::after {\n --ds-row-overhang: var(--ds-row-fill-overhang, calc(2px * var(--ds-sf)));\n inset:\n calc(var(--ds-row-height) - var(--ds-control-height) - var(--ds-row-overhang))\n calc(var(--ds-row-padding, calc(4px * var(--ds-sf))) - var(--ds-row-overhang))\n calc(0px - var(--ds-row-overhang));\n border-radius: var(--ds-row-radius, var(--ds-row-fill-radius, calc(6px * var(--ds-sf))));\n}\n:is(a, button).ds-row:is(.ds-row--stacked, .ds-row--auto)::after,\n:is(.ds-row--stacked, .ds-row--auto) .ds-row__target::after {\n inset: 0;\n}\na.ds-row[href]:hover::after,\nbutton.ds-row:hover:not(:disabled)::after,\n.ds-row__target:is(a[href], button:not(:disabled)):hover::after {\n background: var(--ds-row-fill-hover, var(--ds-fill));\n}\na.ds-row[href]:active::after,\nbutton.ds-row:active:not(:disabled)::after,\n.ds-row__target:is(a[href], button:not(:disabled)):active::after {\n background: var(--ds-row-fill-press, var(--ds-fill-hover));\n}\n.ds-row:is(a, button)[aria-current]:not([aria-current=\"false\"])::after,\n.ds-row__target[aria-current]:not([aria-current=\"false\"])::after {\n background: var(--ds-row-fill-current, var(--ds-fill-hover));\n}\n.ds-row:is(a, button)[aria-current]:not([aria-current=\"false\"]),\n.ds-row:has(.ds-row__target[aria-current]:not([aria-current=\"false\"])) {\n --ds-type-weight-default: var(--ds-row-current-weight, 500);\n font-weight: var(--ds-row-current-weight, 500);\n}\na.ds-row:focus-visible::after,\nbutton.ds-row:focus-visible::after,\n.ds-row__target:focus-visible::after {\n outline: 2px solid var(--ds-focus-ring);\n outline-offset: -2px;\n}\na.ds-row:not([href]),\na.ds-row[aria-disabled=\"true\"],\nbutton.ds-row:disabled,\nbutton.ds-row[aria-disabled=\"true\"],\n.ds-row:has(.ds-row__target:is(:disabled, [aria-disabled=\"true\"], a:not([href]))) {\n cursor: default;\n opacity: 0.5;\n}\n.ds-row__target:is(:disabled, [aria-disabled=\"true\"], a:not([href])) {\n cursor: default;\n}\na.ds-row[aria-disabled=\"true\"]:hover::after,\nbutton.ds-row[aria-disabled=\"true\"]:hover::after {\n background: none;\n}\n\n.ds-row--nav {\n --ds-row-radius: calc(2px * var(--ds-sf));\n}\n\n/* A sidebar of nested things: the tree. */\n\n.ds-sidebar {\n box-sizing: border-box;\n display: flex;\n flex-direction: column;\n min-width: 0;\n margin: 0;\n padding: 0;\n list-style: none;\n color: var(--ds-text-color);\n font-family: var(--ds-typeface-regular);\n font-feature-settings: var(--ds-font-features);\n font-size: var(--ds-type-size-default);\n font-weight: var(--ds-type-weight-default);\n line-height: var(--ds-type-lineheight-default);\n letter-spacing: var(--ds-type-letterspacing-default);\n}\n\n.ds-sidebar__item {\n box-sizing: border-box;\n display: flex;\n align-items: flex-end;\n height: var(--ds-row-height);\n min-width: 0;\n margin: 0;\n padding-block: 0;\n padding-inline: calc(var(--ds-sidebar-indent, 0) * var(--ds-unit)) var(--ds-row-padding, calc(4px * var(--ds-sf)));\n white-space: nowrap;\n cursor: pointer;\n user-select: none;\n outline: none;\n -webkit-tap-highlight-color: transparent;\n}\n.ds-sidebar__item[hidden] { display: none; }\n.ds-sidebar__item[aria-level=\"2\"] { --ds-sidebar-indent: 1; }\n.ds-sidebar__item[aria-level=\"3\"] { --ds-sidebar-indent: 2; }\n.ds-sidebar__item[aria-level=\"4\"] { --ds-sidebar-indent: 3; }\n.ds-sidebar__item[aria-level=\"5\"] { --ds-sidebar-indent: 4; }\n.ds-sidebar__item[aria-level=\"6\"] { --ds-sidebar-indent: 5; }\n.ds-sidebar__item[aria-level=\"7\"] { --ds-sidebar-indent: 6; }\n.ds-sidebar__item[aria-level=\"8\"] { --ds-sidebar-indent: 7; }\n.ds-sidebar__item[aria-level=\"9\"] { --ds-sidebar-indent: 8; }\n.ds-sidebar__item[aria-level=\"10\"] { --ds-sidebar-indent: 9; }\n.ds-sidebar__item[aria-level=\"11\"] { --ds-sidebar-indent: 10; }\n.ds-sidebar__item[aria-level=\"12\"] { --ds-sidebar-indent: 11; }\n.ds-sidebar__item:hover:not([aria-disabled=\"true\"]) { background: var(--ds-row-fill-hover, var(--ds-fill)); }\n.ds-sidebar__item:active:not([aria-disabled=\"true\"]) { background: var(--ds-row-fill-press, var(--ds-fill-hover)); }\n.ds-sidebar__item[aria-selected=\"true\"] {\n --ds-type-weight-default: var(--ds-row-current-weight, 500);\n background: var(--ds-row-fill-current, var(--ds-fill-hover));\n font-weight: var(--ds-row-current-weight, 500);\n}\n.ds-sidebar__item:focus-visible {\n outline: 2px solid var(--ds-focus-ring);\n outline-offset: -2px;\n}\n.ds-sidebar__item[aria-disabled=\"true\"] {\n cursor: default;\n opacity: 0.5;\n}\n\n/* The arrow and an icon each stand on a whole square, drawn on the row's sixteen (two\n pixels below the square's middle); a leaf keeps the arrow's square empty. */\n.ds-sidebar__disclosure,\n.ds-sidebar__item > .ds-icon {\n flex: 0 0 var(--ds-unit);\n width: var(--ds-unit);\n height: var(--ds-unit);\n -webkit-mask-size: var(--ds-icon-box, calc(14px * var(--ds-sf)));\n mask-size: var(--ds-icon-box, calc(14px * var(--ds-sf)));\n -webkit-mask-position: center calc(50% + 2px * var(--ds-sf));\n mask-position: center calc(50% + 2px * var(--ds-sf));\n}\n.ds-sidebar__disclosure {\n --ds-icon-box: calc(14px * var(--ds-sf));\n display: inline-block;\n color: var(--ds-text-color-muted);\n background-color: currentColor;\n -webkit-mask: var(--ds-sidebar-disclosure, url(\"data:image/svg+xml,%3Csvg xmlns='http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg' viewBox='0 0 16 16'%3E%3Cpath d='M13.1566 8.60594H0V9.61651L13.1562 9.61791L10.249 12.5251L10.9558 13.219L15.0636 9.11123L10.9524 5L10.245 5.70734L13.1566 8.60594Z'/%3E%3C/svg%3E\")) center calc(50% + 2px * var(--ds-sf)) / var(--ds-icon-box) no-repeat;\n mask: var(--ds-sidebar-disclosure, url(\"data:image/svg+xml,%3Csvg xmlns='http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg' viewBox='0 0 16 16'%3E%3Cpath d='M13.1566 8.60594H0V9.61651L13.1562 9.61791L10.249 12.5251L10.9558 13.219L15.0636 9.11123L10.9524 5L10.245 5.70734L13.1566 8.60594Z'/%3E%3C/svg%3E\")) center calc(50% + 2px * var(--ds-sf)) / var(--ds-icon-box) no-repeat;\n transform: rotate(0deg);\n transition: transform 120ms ease-out;\n}\n.ds-sidebar__item:not([aria-expanded]) > .ds-sidebar__disclosure {\n visibility: hidden;\n}\n.ds-sidebar__item[aria-expanded=\"true\"] > .ds-sidebar__disclosure {\n transform: rotate(90deg);\n}\n.ds-sidebar__label {\n flex: 1 1 auto;\n min-width: 0;\n padding-inline-start: calc(4px * var(--ds-sf));\n overflow: hidden;\n text-overflow: ellipsis;\n}\n.ds-sidebar__meta {\n flex: none;\n padding-inline-start: calc(4px * var(--ds-sf));\n color: var(--ds-text-color-muted);\n font-size: var(--ds-type-size-small);\n font-variant-numeric: tabular-nums;\n}\n\n@media (prefers-reduced-motion: reduce) {\n .ds-sidebar__disclosure { transition: none; }\n}\n\n@media (forced-colors: active) {\n .ds-row:is(a, button)[aria-current]:not([aria-current=\"false\"]),\n .ds-row__target[aria-current]:not([aria-current=\"false\"])::after,\n .ds-sidebar__item[aria-selected=\"true\"] {\n outline: 1px solid Highlight;\n outline-offset: -1px;\n }\n .ds-sidebar__disclosure {\n background-color: CanvasText;\n }\n}\n\n/* A controlled detail view: the caller marks its open row, and clears it on close.\n Navigation's current state and the text weight remain independent. */\n.ds-row[data-open]:not([data-open=\"false\"]) {\n position: relative;\n isolation: isolate;\n}\n.ds-row[data-open]:not([data-open=\"false\"])::after {\n content: \"\";\n position: absolute;\n z-index: -1;\n pointer-events: none;\n --ds-row-overhang: var(--ds-row-fill-overhang, calc(2px * var(--ds-sf)));\n inset: calc(var(--ds-row-height) - var(--ds-control-height) - var(--ds-row-overhang))\n calc(var(--ds-row-padding, calc(4px * var(--ds-sf))) - var(--ds-row-overhang))\n calc(0px - var(--ds-row-overhang));\n border-radius: var(--ds-row-radius, var(--ds-row-fill-radius, calc(6px * var(--ds-sf))));\n background: var(--ds-row-fill-current, var(--ds-fill-hover));\n}\n/* A plain row (no press target inside) has no padding of its own: its words and icons stand on\n the row's edges, so the layer reaches two past them, as a flush row's does. */\n.ds-row[data-open]:not([data-open=\"false\"]):not(a, button, .ds-row--stacked, .ds-row--auto, :has(.ds-row__target))::after {\n inset: calc(var(--ds-row-height) - var(--ds-control-height) - var(--ds-row-overhang))\n calc(0px - var(--ds-row-overhang))\n calc(0px - var(--ds-row-overhang));\n}\n.ds-row[data-open]:is(.ds-row--stacked, .ds-row--auto)::after { inset: 0; }\n@media (forced-colors: active) {\n .ds-row[data-open]:not([data-open=\"false\"])::after { outline: 1px solid Highlight; outline-offset: -1px; }\n}\n/*\n * `.ds-context` is the `ds-context` element's look on a native menu, for a page\n * without Lit or a menu a library draws: Ezo's gap face. The rows carry the\n * colour and the menu only cuts the outer silhouette, so the page shows\n * through a pixel between rows and two between groups. The rows are black\n * with white words in both themes, as Ezo's menus always were (the slate in\n * dark, darker than the page). Every row is 19px with the pixel under it, a square's pitch, its words\n * on the sixteen and an icon at its end. A Select's menu is the light face,\n * `.ds-menu`; a Context's is this dark one.\n *\n * ds-context the menu (`role=\"menu\"`); its rows are its buttons,\n * links and menu items, or `ds-context__item`\n * ds-context__item a row; `--danger` (or `data-danger`) in red\n * ds-context__label a heading row, muted\n * ds-context__shortcut a shortcut at the row's end, muted\n * ds-context__separator a group gap (or an `hr`, or `role=\"separator\"`):\n * never a line; first, last or doubled it is quiet\n * [data-ds-refused] a refused change: the row turns red\n *\n * The page places and opens it (a popover at the pointer, say) and owns its\n * keys; the faces of hover, focus, disabled and the wait of a pending menu\n * (`aria-busy=\"true\"`) are here. Tokens as the element's: --ds-context-fill,\n * --ds-context-ink, --ds-context-hover, --ds-context-danger,\n * --ds-context-refused, --ds-context-radius.\n */\n\n.ds-context {\n --ds-context-row: calc(var(--ds-row-height) - 1px);\n /* Black in both themes, as Ezo's menus always were: in dark the slate, darker than the page. */\n --ds-context-fill: light-dark(var(--ds-black, #2a2a2a), var(--ds-slate, #1e1e1e));\n --ds-context-ink: var(--ds-white, #ffffff);\n --ds-context-hover: color-mix(in srgb, var(--ds-context-fill) 78%, var(--ds-context-ink));\n --ds-context-danger: var(--ds-tuned-red);\n --ds-context-refused: var(--ds-tuned-red);\n box-sizing: border-box;\n display: flex;\n flex-direction: column;\n gap: 1px;\n width: var(--ds-menu-width, max-content);\n min-width: calc(4 * var(--ds-unit));\n max-height: var(--ds-menu-max-height, calc(16 * var(--ds-unit)));\n overflow-y: auto;\n margin: 0;\n padding: 0;\n border: 0;\n background: transparent;\n box-shadow: none;\n clip-path: inset(0 round var(--ds-context-radius, var(--ds-radius, 4px)));\n color: var(--ds-context-ink);\n font-family: var(--ds-typeface-regular);\n font-feature-settings: var(--ds-font-features);\n font-size: var(--ds-type-size-default);\n font-weight: var(--ds-type-weight-default);\n line-height: var(--ds-type-lineheight-default);\n letter-spacing: var(--ds-type-letterspacing-default);\n list-style: none;\n}\n\n.ds-context > [role=\"group\"] {\n display: contents;\n}\n\n/* A row: whatever the page or library styles its buttons with, one row on the sixteen. */\n.ds-context :is(.ds-context__item, :is(.ds-context, .ds-context > [role=\"group\"]) > :is(button, a, li, [role^=\"menuitem\"]):not(.ds-context__label, .ds-context__separator, [role=\"separator\"])) {\n box-sizing: border-box !important;\n display: flex !important;\n flex: 0 0 auto !important;\n align-items: flex-end !important;\n justify-content: space-between !important;\n gap: calc(4px * var(--ds-sf));\n width: 100%;\n height: var(--ds-context-row) !important;\n min-height: var(--ds-context-row) !important;\n max-height: var(--ds-context-row) !important;\n margin: 0 !important;\n padding: 0 calc(4px * var(--ds-sf)) !important;\n border: 0 !important;\n border-radius: 0 !important;\n background: var(--ds-context-fill) !important;\n color: var(--ds-context-ink) !important;\n font: inherit;\n line-height: var(--ds-type-lineheight-default) !important;\n letter-spacing: inherit;\n text-align: start;\n text-decoration: none;\n white-space: nowrap;\n cursor: pointer;\n outline: none;\n appearance: none;\n -webkit-tap-highlight-color: transparent;\n}\n\n.ds-context :is(.ds-context__item, :is(.ds-context, .ds-context > [role=\"group\"]) > :is(button, a, li, [role^=\"menuitem\"])):is(:hover, :focus-visible, [data-highlighted]):not(:disabled, [aria-disabled=\"true\"], [data-disabled]) {\n background: var(--ds-context-hover) !important;\n}\n\n.ds-context :is(.ds-context__item, :is(.ds-context, .ds-context > [role=\"group\"]) > :is(button, a, li, [role^=\"menuitem\"])):focus-visible {\n box-shadow: inset 0 0 0 2px var(--ds-focus-ring);\n}\n\n.ds-context :is(.ds-context__item, :is(.ds-context, .ds-context > [role=\"group\"]) > :is(button, a, li, [role^=\"menuitem\"])):is(:disabled, [aria-disabled=\"true\"], [data-disabled]) {\n cursor: default;\n opacity: 0.5;\n}\n\n.ds-context[aria-busy=\"true\"] > * {\n cursor: wait !important;\n}\n\n/* Danger is red, on either fill. */\n.ds-context :is(.ds-context__item, :is(.ds-context, .ds-context > [role=\"group\"]) > :is(button, a, li, [role^=\"menuitem\"])):is(.ds-context__item--danger, [data-danger], [data-variant=\"destructive\"]) {\n color: var(--ds-context-danger) !important;\n}\n\n/* A refused change: its row turns red a moment. */\n.ds-context :is(.ds-context__item, :is(.ds-context, .ds-context > [role=\"group\"]) > :is(button, a, li, [role^=\"menuitem\"]))[data-ds-refused] {\n background: var(--ds-context-refused) !important;\n}\n\n/* Groups are a gap, never a line: the separator takes nothing but the gap after it. */\n.ds-context > :is(hr, .ds-context__separator, [role=\"separator\"]) {\n flex: 0 0 0 !important;\n height: 0 !important;\n margin: 0 !important;\n padding: 0 !important;\n border: 0 !important;\n background: none !important;\n}\n\n/* A group left empty leaves no gap. */\n.ds-context > :is(hr, .ds-context__separator, [role=\"separator\"]):is(:first-child, :last-child),\n.ds-context > :is(hr, .ds-context__separator, [role=\"separator\"]) + :is(hr, .ds-context__separator, [role=\"separator\"]) {\n display: none !important;\n}\n\n.ds-context :is(.ds-context__label, [data-ds-menu-label]) {\n box-sizing: border-box;\n height: var(--ds-context-row);\n /* The spare three above the sixteen. */\n padding: calc(var(--ds-context-row) - var(--ds-type-lineheight-default)) calc(4px * var(--ds-sf)) 0;\n background: var(--ds-context-fill);\n color: color-mix(in srgb, var(--ds-context-ink) 60%, var(--ds-context-fill));\n line-height: var(--ds-type-lineheight-default);\n white-space: nowrap;\n}\n\n.ds-context__shortcut {\n margin-left: auto;\n color: color-mix(in srgb, var(--ds-context-ink) 60%, var(--ds-context-fill));\n}\n\n/*\n * Native controls in shared dress.\n *\n * DS one keeps a few components as plain classes on native elements. shared does\n * the same for everything a person types into or picks from: text fields,\n * selects and checkboxes stay `<input>` and `<select>`, so labels, form\n * semantics and React's controlled inputs work as they always have.\n *\n * `.ds-button` is the `ds-button` element's look on a native `<button>`,\n * for a button inside a drag handle. The drag library recognises only native\n * controls: inside a handle it would lift the row on Space where a\n * `ds-button` was meant to be pressed. Both read the same custom properties.\n * On an `<a href>` it is a link drawn as a button (see `a.ds-button` below).\n */\n\n.ds-button {\n appearance: none;\n box-sizing: border-box;\n display: inline-flex;\n /* At the foot of a line, so the 16px face takes the lower sixteen of the square. */\n vertical-align: bottom;\n flex: 0 0 auto;\n width: var(--ds-button-width, max-content);\n align-items: center;\n justify-content: var(--ds-button-align, flex-start);\n gap: var(--ds-button-gap, calc(4px * var(--ds-sf)));\n height: var(--ds-button-height, var(--ds-control-height));\n margin: 0;\n padding: var(--ds-button-padding, 0);\n border: 0;\n border-radius: var(--ds-radius);\n background: var(--ds-button-background, transparent);\n color: var(--ds-button-color, var(--ds-button-text-color));\n font-family: var(--ds-typeface-regular);\n font-feature-settings: var(--ds-font-features);\n font-size: var(--ds-type-size-default);\n line-height: var(--ds-type-lineheight-default);\n letter-spacing: var(--ds-type-letterspacing-default);\n white-space: nowrap;\n cursor: pointer;\n -webkit-tap-highlight-color: transparent;\n}\n\n.ds-button--icon {\n justify-content: center;\n width: var(--ds-button-height, var(--ds-control-height));\n padding: 0;\n color: var(--ds-button-color, var(--ds-text-color-muted));\n}\n\n.ds-button--icon:hover:not(:disabled, [aria-disabled=\"true\"]) {\n --ds-button-color: var(--ds-text-color);\n}\n\n.ds-button:focus-visible {\n outline: 2px solid var(--ds-focus-ring);\n outline-offset: 1px;\n}\n\n.ds-button:disabled,\n.ds-button[aria-disabled=\"true\"] {\n cursor: default;\n opacity: 0.5;\n}\n\n/*\n * one.css carries older button rules that dim a button on hover and nudge it\n * on press. The shared button does neither: these match their specificity, so\n * controls.css, loaded after one.css, wins.\n */\n.ds-button:hover:not(:disabled, [aria-disabled=\"true\"]) {\n filter: none;\n}\n\n.ds-button:active:not(:disabled, [aria-disabled=\"true\"]) {\n transform: none;\n}\n\n/*\n * `a.ds-button` is a link drawn as a button. The browser keeps the link:\n * middle-click, a new tab, Copy link and Enter. It never takes the link's\n * underline or colours, in any state, so every face (primary, secondary,\n * icon, tabs) looks as it does on a `<button>`. A disabled link has no `href`\n * and carries `aria-disabled=\"true\"` and `role=\"link\"`.\n */\na.ds-button,\na.ds-button:is(:hover, :focus, :active) {\n text-decoration: none;\n}\n\na.ds-button:is(:link, :visited) {\n color: var(--ds-button-color, var(--ds-button-text-color));\n}\n\na.ds-button.ds-button--icon:is(:link, :visited) {\n color: var(--ds-button-color, var(--ds-text-color-muted));\n}\n\na.ds-button[aria-disabled=\"true\"] {\n pointer-events: none;\n}\n\n/*\n * `.ds-link` is a link in running text: the text's ink, underlined by a\n * hairline 2px below the letters (as a toast's actions are), which turns to the full ink under\n * the pointer. A visited link is drawn in the muted ink. Words keep their\n * sentence case. Tokens: `--ds-link-color`, `--ds-link-visited-color`,\n * `--ds-link-line-color`, `--ds-link-hover-line-color`.\n */\n.ds-link {\n color: var(--ds-link-color, currentColor);\n text-decoration-line: underline;\n text-decoration-thickness: 1px;\n text-decoration-color: var(--ds-link-line-color, color-mix(in srgb, currentColor 40%, transparent));\n text-underline-offset: calc(2px * var(--ds-sf));\n cursor: pointer;\n}\n\n.ds-link:visited {\n color: var(--ds-link-visited-color, var(--ds-text-color-muted));\n}\n\n.ds-link:hover {\n text-decoration-color: var(--ds-link-hover-line-color, currentColor);\n}\n\n/* Quiet navigation and related-component lists: no underline in any state. */\n.ds-link.ds-link--plain {\n text-decoration: none;\n}\n\n.ds-link:focus-visible {\n outline: 2px solid var(--ds-focus-ring);\n outline-offset: 1px;\n}\n\n.ds-link[aria-disabled=\"true\"] {\n cursor: default;\n opacity: 0.5;\n pointer-events: none;\n}\n\n.ds-input,\n.ds-select {\n box-sizing: border-box;\n min-width: 0;\n height: var(--ds-input-height, var(--ds-control-height));\n margin: 0;\n padding: 0 calc(4px * var(--ds-sf));\n border: 0;\n border-radius: var(--ds-radius);\n background: var(--ds-fill);\n color: var(--ds-text-color);\n font-family: var(--ds-typeface-regular);\n font-feature-settings: var(--ds-font-features);\n font-size: var(--ds-type-size-default);\n line-height: var(--ds-type-lineheight-default);\n letter-spacing: var(--ds-type-letterspacing-default);\n outline: none;\n}\n\n.ds-input::placeholder {\n color: var(--ds-title-color);\n}\n\n.ds-input:focus-visible,\n.ds-select:focus-visible,\n.ds-checkbox:focus-visible,\n.ds-radio:focus-visible,\n.ds-switch:focus-visible {\n outline: 2px solid var(--ds-focus-ring);\n outline-offset: 1px;\n}\n\n.ds-input:disabled,\n.ds-select:disabled,\n.ds-checkbox:disabled,\n.ds-radio:disabled,\n.ds-switch:disabled {\n cursor: default;\n opacity: 0.5;\n}\n\n.ds-select {\n appearance: none;\n padding-right: calc(16px * var(--ds-sf));\n background-image:\n linear-gradient(45deg, transparent 50%, currentColor 50%),\n linear-gradient(135deg, currentColor 50%, transparent 50%);\n background-position:\n calc(100% - 9px) 50%,\n calc(100% - 6px) 50%;\n background-size:\n 3px 3px,\n 3px 3px;\n background-repeat: no-repeat;\n cursor: pointer;\n}\n\n/* A multiline field, `ds-input` on a <textarea>, spans whole rows: --ds-textarea-rows sets how many, three by default. */\ntextarea.ds-input {\n display: block;\n height: var(--ds-textarea-height, calc(var(--ds-textarea-rows, 3) * var(--ds-row-height)));\n min-height: var(--ds-row-height);\n padding: var(--ds-textarea-padding, calc(4px * var(--ds-sf)));\n border-radius: var(--ds-textarea-radius, calc(4px * var(--ds-sf)));\n resize: vertical;\n}\n\n/*\n * `.ds-checkbox` and `.ds-radio` are the `ds-checkbox` and `ds-radio` elements'\n * faces on a native `<input>`: a box one control (16px) square on the field's\n * ground with a 1px line, standing as an icon does, on the lower sixteen at the\n * start of its square, so it takes one square and the words begin on the next\n * (Joachim, 19 October 2026). The checkbox has the corners of a control and fills with the accent,\n * the check (`x-icon/check.svg`) in its ink; the radio is a circle with a dot\n * half a square across in the text colour.\n */\n.ds-checkbox,\n.ds-radio {\n appearance: none;\n box-sizing: border-box;\n display: inline-grid;\n flex: 0 0 auto;\n place-items: center;\n vertical-align: top;\n width: var(--ds-control-height);\n height: var(--ds-control-height);\n margin: 0;\n margin-block-start: calc(var(--ds-row-height) - var(--ds-control-height));\n margin-inline-end: calc(var(--ds-row-height) - var(--ds-control-height));\n padding: 0;\n border: 1px solid var(--ds-border-color);\n background: var(--ds-input-background);\n cursor: pointer;\n}\n\n.ds-checkbox {\n --ds-checkbox-mark: url(\"data:image/svg+xml,%3Csvg%20width%3D%2216%22%20height%3D%2216%22%20viewBox%3D%220%200%2016%2016%22%20fill%3D%22none%22%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%3E%0A%3Cpath%20d%3D%22M6.68649%2011.884L12.443%206.13601L11.736%205.42715L6.68835%2010.4827L4.26399%208.0501L3.55696%208.74525L6.68649%2011.884Z%22%20fill%3D%22currentColor%22%2F%3E%0A%3C%2Fsvg%3E\");\n border-radius: var(--ds-radius);\n corner-shape: var(--ds-corner-shape, round);\n color: var(--ds-button-text-color-on-accent);\n}\n\n.ds-checkbox:is(:checked, :indeterminate) {\n background: var(--ds-accent-color);\n}\n\n.ds-checkbox::before,\n.ds-radio::before {\n content: \"\";\n opacity: 0;\n background: currentColor;\n}\n\n.ds-checkbox::before {\n width: var(--ds-control-height);\n height: var(--ds-control-height);\n mask: var(--ds-checkbox-mark) center / contain no-repeat;\n}\n\n.ds-checkbox:indeterminate::before {\n width: calc(var(--ds-control-height) / 2);\n height: calc(2px * var(--ds-sf));\n mask: none;\n}\n\n.ds-radio {\n border-radius: 50%;\n color: var(--ds-text-color);\n}\n\n.ds-radio::before {\n width: calc(var(--ds-control-height) / 2);\n height: calc(var(--ds-control-height) / 2);\n border-radius: 50%;\n}\n\n.ds-checkbox:is(:checked, :indeterminate)::before,\n.ds-radio:checked::before {\n opacity: 1;\n}\n\n/*\n * `.ds-switch` is the `ds-switch` element's look on a native\n * `<button role=\"switch\" aria-checked>`: two control heights wide, its thumb\n * one control high less a 2px inset, travelling one control height. A pill with a white\n * round thumb, grey when off and the darker green when on, whatever the page's accent: the\n * one switch (Joachim, 19 October 2026).\n */\n\n.ds-switch {\n --ds-choice-unit: var(--ds-control-height);\n appearance: none;\n box-sizing: border-box;\n position: relative;\n display: inline-block;\n flex: 0 0 auto;\n vertical-align: middle;\n width: calc(2 * var(--ds-choice-unit));\n height: var(--ds-choice-unit);\n margin: 0;\n padding: calc(2px * var(--ds-sf));\n border: 0;\n border-radius: var(--ds-choice-unit);\n background: var(--ds-fill);\n color: var(--ds-white);\n cursor: pointer;\n touch-action: manipulation;\n}\n\n.ds-switch::after {\n content: \"\";\n display: block;\n width: calc(var(--ds-choice-unit) - 4px * var(--ds-sf));\n height: 100%;\n border-radius: 50%;\n background: var(--ds-white);\n transform: translateX(0);\n transition: transform 140ms ease;\n}\n\n.ds-switch[aria-checked=\"true\"] {\n background: var(--ds-switch-track-on);\n}\n\n.ds-switch[aria-checked=\"true\"]::after {\n transform: translateX(var(--ds-choice-unit));\n}\n\n@media (prefers-reduced-motion: reduce) {\n .ds-switch::after {\n transition: none;\n }\n}\n\n/*\n * `.ds-range` draws a native `<input type=\"range\">`: one control high,\n * standing on the lower sixteen of its square (the spare four above it as a\n * margin, so it takes one square alone and in a row), eight squares wide.\n * The track is a 1px line across the middle of the control, the thumb one\n * control high and half a control wide with the shared corners, in the ink.\n * The browser keeps the value, the keys, the form data and the events.\n *\n * Tokens: `--ds-range-width` (eight squares), `--ds-range-track` (the line,\n * the title grey), `--ds-range-thumb` (the ink) and `--ds-range-thumb-width`.\n * WebKit and Blink draw the parts as `::-webkit-slider-*`, Firefox as\n * `::-moz-range-*`; both get the same track and thumb.\n */\n\n.ds-range {\n -webkit-appearance: none;\n appearance: none;\n box-sizing: border-box;\n display: inline-block;\n vertical-align: bottom;\n width: var(--ds-range-width, calc(8 * var(--ds-unit)));\n min-width: 0;\n height: var(--ds-control-height);\n margin: calc(var(--ds-row-height) - var(--ds-control-height)) 0 0;\n padding: 0;\n border: 0;\n border-radius: var(--ds-radius);\n background: transparent;\n color: var(--ds-range-thumb, var(--ds-text-color));\n font: inherit;\n cursor: pointer;\n touch-action: pan-y;\n -webkit-tap-highlight-color: transparent;\n}\n\n.ds-range::-webkit-slider-runnable-track {\n box-sizing: border-box;\n height: var(--ds-control-height);\n border: 0;\n background: linear-gradient(var(--ds-range-track, var(--ds-title-color)) 0 0) 0 calc(var(--ds-control-height) / 2) / 100% 1px no-repeat;\n}\n\n.ds-range::-moz-range-track {\n box-sizing: border-box;\n height: var(--ds-control-height);\n border: 0;\n background: linear-gradient(var(--ds-range-track, var(--ds-title-color)) 0 0) 0 calc(var(--ds-control-height) / 2) / 100% 1px no-repeat;\n}\n\n.ds-range::-moz-range-progress {\n background: transparent;\n}\n\n.ds-range::-webkit-slider-thumb {\n -webkit-appearance: none;\n appearance: none;\n box-sizing: border-box;\n width: var(--ds-range-thumb-width, calc(var(--ds-control-height) / 2));\n height: var(--ds-control-height);\n border: 0;\n border-radius: var(--ds-radius);\n background: currentColor;\n}\n\n.ds-range::-moz-range-thumb {\n box-sizing: border-box;\n width: var(--ds-range-thumb-width, calc(var(--ds-control-height) / 2));\n height: var(--ds-control-height);\n border: 0;\n border-radius: var(--ds-radius);\n background: currentColor;\n}\n\n.ds-range:focus-visible {\n outline: 2px solid var(--ds-focus-ring);\n outline-offset: 1px;\n}\n\n.ds-range:disabled {\n cursor: default;\n opacity: 0.5;\n}\n\n/*\n * `.ds-tabs` is the `ds-tabs` element's row on native buttons. As an option\n * group (role=\"group\", a segmented control) its `.ds-button` choices are\n * grey and the chosen one, aria-pressed, aria-selected or aria-current, is in\n * the accent, as the primary and secondary buttons are.\n */\n\n.ds-tabs {\n box-sizing: border-box;\n display: flex;\n flex-direction: row;\n align-items: center;\n gap: calc(4px * var(--ds-sf));\n min-width: 0;\n height: var(--ds-row-height);\n}\n\n.ds-tabs--fill > * {\n flex: 1 1 0;\n justify-content: center;\n}\n\n.ds-tabs[role=\"group\"] > .ds-button {\n --ds-button-height: var(--ds-row-height);\n --ds-button-padding: 0 calc(4px * var(--ds-sf));\n --ds-button-background: var(--ds-button-background-color-secondary);\n min-width: 0;\n}\n\n.ds-tabs[role=\"group\"] > .ds-button:hover:not(:disabled, [aria-disabled=\"true\"]) {\n --ds-button-background: var(--ds-fill-hover);\n}\n\n.ds-tabs[role=\"group\"] > .ds-button:is([aria-pressed=\"true\"], [aria-selected=\"true\"], [aria-current]:not([aria-current=\"false\"])) {\n --ds-button-background: var(--ds-button-background-color-primary);\n --ds-button-color: var(--ds-button-text-color-on-accent);\n}\n\n/*\n * `.ds-overlay` is the `ds-overlay` element's frame on a native `<dialog>`, a\n * modal by default: twenty squares wide, a square of padding, square corners,\n * a hairline and the paper. `ds-overlay--sheet`, `ds-overlay--drawer` (with\n * `ds-overlay--start` for the start side) and `ds-overlay--screen` are its\n * other types (overlay.css). Its header, title, description, footer and close button are marked\n * with data-ds-overlay, as inside the element.\n */\n\ndialog.ds-overlay {\n box-sizing: border-box;\n position: fixed;\n inset: 0;\n width: var(--ds-overlay-width, calc(20 * var(--ds-unit)));\n max-width: var(--ds-overlay-max-width, calc(100vw - 2 * var(--ds-unit)));\n max-height: var(--ds-overlay-max-height, calc(100dvh - 2 * var(--ds-unit)));\n height: var(--ds-overlay-height, fit-content);\n margin: auto;\n padding: var(--ds-overlay-padding, var(--ds-unit));\n border: var(--ds-overlay-border, 1px solid var(--ds-border-color));\n border-radius: 0;\n background: var(--ds-overlay-paper, var(--ds-paper));\n color: var(--ds-text-color);\n box-shadow: none;\n overflow: auto;\n overscroll-behavior: contain;\n font-family: var(--ds-typeface-regular);\n font-feature-settings: var(--ds-font-features);\n font-size: var(--ds-type-size-default);\n font-weight: var(--ds-type-weight-default);\n line-height: var(--ds-type-lineheight-default);\n letter-spacing: var(--ds-type-letterspacing-default);\n}\n\ndialog.ds-overlay[open] {\n display: flex;\n flex-direction: column;\n gap: var(--ds-unit);\n}\n\ndialog.ds-overlay::backdrop {\n background: color-mix(in srgb, var(--ds-black) 40%, transparent);\n}\n\n.ds-overlay [data-ds-overlay=\"header\"] {\n display: flex;\n flex-direction: column;\n}\n\n/* The header keeps the last square of its row for the close button, only when it has one. */\ndialog.ds-overlay:has(> [data-ds-overlay=\"close\"]) [data-ds-overlay=\"header\"] {\n padding-inline-end: var(--ds-unit);\n}\n\n/* The title on its square's lower sixteen, as every row's words. */\n.ds-overlay [data-ds-overlay=\"title\"] {\n display: flex;\n align-items: flex-end;\n min-height: var(--ds-row-height);\n margin: 0;\n color: var(--ds-text-color);\n font: inherit;\n font-weight: var(--ds-type-weight-bold);\n line-height: var(--ds-type-lineheight-default);\n}\n\n.ds-overlay [data-ds-overlay=\"description\"] {\n margin: 0;\n color: var(--ds-text-color-muted);\n font: inherit;\n}\n\n.ds-overlay [data-ds-overlay=\"footer\"] {\n display: flex;\n flex-wrap: wrap;\n align-items: center;\n justify-content: flex-end;\n gap: calc(var(--ds-unit) / 2);\n min-height: var(--ds-row-height);\n}\n\n.ds-overlay [data-ds-overlay=\"close\"] {\n position: absolute;\n top: var(--ds-unit);\n right: var(--ds-unit);\n}\n\n/* A field in the frame, as a prompt has: its label one row high, the field\n * one row high beneath it and as wide as the frame, two squares in all. */\n.ds-overlay [data-ds-overlay=\"field\"] {\n display: flex;\n flex-direction: column;\n}\n\n.ds-overlay [data-ds-overlay=\"label\"] {\n min-height: var(--ds-row-height);\n line-height: var(--ds-row-height);\n}\n\n.ds-overlay [data-ds-overlay=\"field\"] > .ds-input {\n --ds-input-height: var(--ds-row-height);\n width: 100%;\n}\n\n/*\n * `.ds-button--primary` and `--secondary` are the element's variants on a\n * native button: a form's submit button stays native so Enter in a field\n * submits the form. `--danger` is its `danger` attribute.\n */\n\n.ds-button--primary,\n.ds-button--secondary {\n --ds-button-padding: 0 calc(4px * var(--ds-sf));\n}\n\n.ds-button--primary {\n --ds-button-background: var(--ds-button-background-color-primary);\n --ds-button-color: var(--ds-button-text-color-on-accent);\n}\n\n.ds-button--secondary {\n --ds-button-background: var(--ds-button-background-color-secondary);\n}\n\n.ds-button--secondary:hover:not(:disabled, [aria-disabled=\"true\"]) {\n --ds-button-background: var(--ds-fill-hover);\n}\n\n/* `.ds-button--danger` is the element's `danger`: a destructive action's words\n * in the danger colour, on the secondary face or none. */\n.ds-button--danger {\n --ds-button-color: var(--ds-danger-color, var(--ds-tuned-red));\n}\n\n.ds-button--fixed {\n width: var(--ds-button-width, calc(4 * var(--ds-unit)));\n}\n\n.ds-button--wide {\n justify-content: center;\n width: 100%;\n}\n\n/*\n * `.ds-menu` is the `ds-menu` element's look on a menu a library draws:\n * the context menu's items come from Radix, which owns their roles, focus and\n * keys, so they stay Radix's and take shared's paper, rows and type.\n * On whole squares, as the element: the line and the padding inside it make\n * half a square on each side, entries are one square each with nothing\n * between them, a separator is one square with its line, and there is no\n * shadow. n entries make a menu n + 1 squares high.\n */\n\n.ds-menu {\n box-sizing: border-box;\n display: flex;\n flex-direction: column;\n gap: 0;\n min-width: calc(8 * var(--ds-unit));\n max-width: calc(12 * var(--ds-unit));\n max-height: var(--ds-menu-max-height, calc(16 * var(--ds-unit)));\n overflow-y: auto;\n padding: calc(var(--ds-unit) / 2 - 1px);\n border: 1px solid var(--ds-border-color);\n border-radius: var(--ds-radius-card);\n background: var(--ds-paper);\n color: var(--ds-text-color);\n box-shadow: none;\n font-family: var(--ds-typeface-regular);\n font-feature-settings: var(--ds-font-features);\n font-size: var(--ds-type-size-default);\n font-weight: var(--ds-type-weight-default);\n line-height: var(--ds-type-lineheight-default);\n letter-spacing: var(--ds-type-letterspacing-default);\n}\n\n.ds-menu__item {\n position: relative;\n box-sizing: border-box;\n display: flex;\n align-items: center;\n gap: calc(4px * var(--ds-sf));\n width: 100%;\n min-height: var(--ds-row-height);\n padding: calc(2px * var(--ds-sf)) calc(6px * var(--ds-sf));\n border-radius: calc(4px * var(--ds-sf));\n color: var(--ds-text-color);\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n cursor: default;\n user-select: none;\n outline: none;\n}\n\n/* An entry a library draws as its own button or link is one square high too,\n * whatever that library's button styles say. */\n.ds-menu > :is(button, a, [role=\"option\"], [role^=\"menuitem\"]),\n.ds-menu > [role=\"group\"] > :is(button, a, [role=\"option\"], [role^=\"menuitem\"]) {\n box-sizing: border-box !important;\n flex: 0 0 auto !important;\n height: var(--ds-row-height) !important;\n min-height: var(--ds-row-height) !important;\n max-height: var(--ds-row-height) !important;\n margin-block: 0 !important;\n padding-block: 0 !important;\n line-height: var(--ds-type-lineheight-default) !important;\n}\n\n/* A menu item may be a native button: it keeps the row's look, not a button's. */\n:where(button).ds-menu__item {\n appearance: none;\n margin: 0;\n border: 0;\n background: transparent;\n font: inherit;\n letter-spacing: inherit;\n text-align: start;\n}\n\n.ds-menu__item--inset {\n padding-left: calc(var(--ds-unit) + calc(4px * var(--ds-sf)));\n}\n\n.ds-menu__item:hover,\n.ds-menu__item:focus-visible,\n.ds-menu__item[data-highlighted] {\n background: var(--ds-fill);\n}\n\n.ds-menu__item[data-variant=\"destructive\"] {\n color: var(--ds-danger-color, var(--ds-tuned-red));\n}\n\n.ds-menu__item[data-disabled],\n.ds-menu__item[aria-disabled=\"true\"] {\n opacity: 0.5;\n pointer-events: none;\n}\n\n.ds-menu__indicator {\n position: absolute;\n left: calc(6px * var(--ds-sf));\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: calc(12px * var(--ds-sf));\n height: calc(12px * var(--ds-sf));\n pointer-events: none;\n}\n\n.ds-menu__indicator svg {\n width: 100%;\n height: 100%;\n}\n\n.ds-menu__chevron {\n width: calc(12px * var(--ds-sf));\n height: calc(12px * var(--ds-sf));\n margin-left: auto;\n color: var(--ds-text-color-muted);\n}\n\n.ds-menu__label {\n box-sizing: border-box;\n min-height: var(--ds-row-height);\n padding: calc(2px * var(--ds-sf)) calc(6px * var(--ds-sf));\n color: var(--ds-title-color);\n font-size: var(--ds-type-size-small);\n}\n\n.ds-menu__separator {\n flex: 0 0 auto;\n height: 1px;\n /* One square with its line. */\n margin: calc(var(--ds-unit) / 2 - 1px) calc(6px * var(--ds-sf)) calc(var(--ds-unit) / 2);\n background: var(--ds-border-color);\n}\n\n.ds-menu__shortcut {\n margin-left: auto;\n padding-left: var(--ds-unit);\n color: var(--ds-title-color);\n font-size: var(--ds-type-size-small);\n}\n\n/*\n * Pieces the components draw, as classes on native elements: a field's label\n * row, an avatar, a badge, a toggle button, an icon and a file drop zone. Each\n * reads the same tokens as its element, so a page without Lit draws the same\n * look.\n */\n\n/*\n * `.ds-field` is the label row `ds-input` draws, around any native control:\n * the label (`.ds-field__label`) on a one-square line above it, then a hint\n * (`.ds-field__hint`) in the muted ink and an error (`.ds-field__error`) in\n * the danger colour, each on one-square lines. Every row is at least one\n * square high and a control lower than that stands centred on it, so the\n * field keeps to whole squares. `.ds-field--beside` sets the label beside the\n * control, in a column `--ds-field-label-width` wide (four squares), with the\n * hint and the error under the control. An empty hint or error takes no room,\n * so the error can stay in the page as a live region.\n */\n\n.ds-field {\n box-sizing: border-box;\n display: grid;\n grid-template-columns: minmax(0, 1fr);\n grid-auto-rows: minmax(var(--ds-row-height), auto);\n align-items: center;\n justify-items: start;\n min-width: 0;\n margin: 0;\n color: var(--ds-text-color);\n font-family: var(--ds-typeface-regular);\n font-feature-settings: var(--ds-font-features);\n font-size: var(--ds-type-size-default);\n font-weight: var(--ds-type-weight-default);\n line-height: var(--ds-unit);\n letter-spacing: var(--ds-type-letterspacing-default);\n}\n\n.ds-field > :is(.ds-input, .ds-select) {\n justify-self: stretch;\n}\n\n.ds-field__label,\n.ds-field__hint,\n.ds-field__error {\n display: block;\n min-width: 0;\n margin: 0;\n font: inherit;\n letter-spacing: inherit;\n}\n\n.ds-field__label {\n color: var(--ds-field-label-color, var(--ds-text-color));\n}\n\n.ds-field__hint {\n color: var(--ds-text-color-muted);\n}\n\n.ds-field__error {\n color: var(--ds-danger-color);\n}\n\n.ds-field__hint:empty,\n.ds-field__error:empty {\n display: none;\n}\n\n.ds-field--beside {\n grid-template-columns: var(--ds-field-label-width, calc(4 * var(--ds-unit))) minmax(0, 1fr);\n}\n\n.ds-field--beside > * {\n grid-column: 2;\n}\n\n.ds-field--beside > .ds-field__label {\n grid-column: 1;\n grid-row: 1;\n align-self: start;\n}\n\n/*\n * `.ds-avatar` is the `ds-avatar` element's mark: round and one control high,\n * an initial in small type on the neutral fill, or an `<img alt=\"\">` after the\n * initial, covering it. While the picture loads the initial shows; remove a\n * picture that fails (`onerror`), as the element does, or the browser draws\n * its broken-image mark. `--large` is two squares with type a square high,\n * `--pair` fits two characters between the hairline edges, `--square` gives it\n * a picture's corners, `--outlined` draws the hairline in its ink and\n * `--pending` greys out someone who has not accepted yet.\n * `--ds-avatar-background` fills it with a colour and `--ds-avatar-color`\n * letters it: on a fill, pick the black or white ink that reads on it\n * (`--ds-black`, `--ds-white`).\n */\n\n.ds-avatar {\n --ds-avatar-size: var(--ds-control-height);\n --ds-avatar-pair-type-size: var(--ds-type-size-small);\n box-sizing: border-box;\n position: relative;\n display: inline-grid;\n place-items: center;\n flex: 0 0 auto;\n vertical-align: middle;\n width: var(--ds-avatar-size);\n height: var(--ds-avatar-size);\n overflow: hidden;\n border-radius: 50%;\n corner-shape: round;\n background: var(--ds-avatar-background, var(--ds-fill));\n color: var(--ds-avatar-color, var(--ds-text-color));\n font: var(--ds-type-weight-default) var(--ds-type-size-small) / 1 var(--ds-typeface-regular);\n letter-spacing: normal;\n text-align: center;\n white-space: nowrap;\n user-select: none;\n -webkit-user-select: none;\n}\n\n.ds-avatar > img {\n position: absolute;\n inset: 0;\n display: block;\n width: 100%;\n height: 100%;\n object-fit: cover;\n}\n\n.ds-avatar--large {\n --ds-avatar-size: calc(2 * var(--ds-unit));\n --ds-avatar-pair-type-size: var(--ds-type-size-default);\n font-size: var(--ds-unit);\n}\n\n.ds-avatar--pair {\n font-size: min(var(--ds-avatar-pair-type-size), calc((var(--ds-avatar-size) - 2px) / 2));\n}\n\n.ds-avatar--square {\n border-radius: var(--ds-avatar-radius, var(--ds-radius));\n corner-shape: var(--ds-corner-shape, round);\n}\n\n.ds-avatar--outlined::after {\n content: \"\";\n position: absolute;\n inset: 0;\n border: 1px solid var(--ds-avatar-outline, currentColor);\n border-radius: inherit;\n pointer-events: none;\n}\n\n.ds-avatar--pending {\n background: var(--ds-fill);\n color: var(--ds-text-color-muted);\n}\n\n.ds-avatar--pending > img {\n filter: grayscale(1);\n opacity: 0.5;\n}\n\n/*\n * `.ds-badge` is the `ds-badge` element's status label: one square high on the\n * neutral fill, its words padded 4px and cut short with an ellipsis, never a\n * button. Where the browser can size to content in calc (calc-size), its width\n * rounds up to whole squares as the element's does; elsewhere it hugs the\n * words. An icon inside is a `.ds-icon` before the words. `--icon` shows the\n * icon alone, one square wide, and keeps the words for assistive technology:\n * put them in an element of their own. `--ds-badge-background` and\n * `--ds-badge-color` give a status a meaningful colour.\n */\n\n.ds-badge {\n box-sizing: border-box;\n display: inline-block;\n flex: 0 0 auto;\n vertical-align: middle;\n width: max-content;\n width: calc-size(max-content, round(up, size, var(--ds-unit)));\n min-width: var(--ds-row-height);\n max-width: 100%;\n height: var(--ds-row-height);\n padding: 0 calc(4px * var(--ds-sf));\n overflow: hidden;\n background: var(--ds-badge-background, var(--ds-fill));\n color: var(--ds-badge-color, var(--ds-text-color));\n font-family: var(--ds-typeface-regular);\n font-feature-settings: var(--ds-font-features);\n font-size: var(--ds-type-size-default);\n font-weight: var(--ds-type-weight-default);\n line-height: var(--ds-row-height);\n letter-spacing: var(--ds-type-letterspacing-default);\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n.ds-badge > .ds-icon {\n vertical-align: top;\n margin-top: calc((var(--ds-row-height) - var(--ds-icon-box, var(--ds-control-height))) / 2);\n margin-right: calc(4px * var(--ds-sf));\n}\n\n.ds-badge--icon {\n position: relative;\n width: var(--ds-row-height);\n padding: 0;\n text-align: center;\n}\n\n.ds-badge--icon > .ds-icon {\n margin-right: 0;\n}\n\n.ds-badge--icon > :not(.ds-icon) {\n position: absolute;\n width: 1px;\n height: 1px;\n overflow: hidden;\n clip-path: inset(50%);\n white-space: nowrap;\n}\n\n/*\n * `.ds-toggle` makes a `.ds-button` a toggle button, `<button aria-pressed>`:\n * the secondary button's grey while it is off, the primary button's accent\n * while it is on, as a chosen segment of `.ds-tabs[role=\"group\"]` is. Its\n * words stay the same in both states; the page toggles `aria-pressed`.\n * A setting that is on or off is a `.ds-switch`; one of several choices is a\n * `.ds-tabs[role=\"group\"]`.\n */\n\n.ds-toggle {\n --ds-button-padding: 0 calc(4px * var(--ds-sf));\n --ds-button-background: var(--ds-button-background-color-secondary);\n}\n\n.ds-toggle:hover:not(:disabled, [aria-disabled=\"true\"]) {\n --ds-button-background: var(--ds-fill-hover);\n}\n\n.ds-toggle[aria-pressed=\"true\"],\n.ds-toggle[aria-pressed=\"true\"]:hover:not(:disabled, [aria-disabled=\"true\"]) {\n --ds-button-background: var(--ds-button-background-color-primary);\n --ds-button-color: var(--ds-button-text-color-on-accent);\n}\n\n/*\n * `.ds-icon` is the `ds-icon` element's drawing without the element: a\n * Design system 1 icon file as a mask, painted in the text colour\n * (`--ds-icon-color`), 14px by default, 12px with `--small` and 16px with\n * `--large`, times the scale. `--ds-icon` names the file, as Sync 1's `icons`\n * export copies it: `style=\"--ds-icon: url(icons/close.svg)\"` (a path from the\n * page) or a rule per icon in the page's stylesheet. The mask takes only the\n * drawing's shape, so an icon with colours of its own is an `<img>`. These\n * rules have no specificity: a page that drew its own `.ds-icon` keeps its\n * rule until it removes it.\n */\n\n:where(.ds-icon) {\n --ds-icon-box: calc(var(--ds-icon-size, 14px) * var(--ds-sf));\n display: inline-block;\n flex: 0 0 auto;\n width: var(--ds-icon-box);\n height: calc(var(--ds-icon-box) / var(--ds-icon-ratio, 1));\n color: var(--ds-icon-color, currentColor);\n background-color: currentColor;\n -webkit-mask: var(--ds-icon) center / contain no-repeat;\n mask: var(--ds-icon) center / contain no-repeat;\n}\n\n:where(.ds-icon--small) {\n --ds-icon-size: 12px;\n}\n\n:where(.ds-icon--large) {\n --ds-icon-size: 16px;\n}\n\n/*\n * `.ds-drop` is `ds-file-picker`'s area on a `<label>` around a native\n * `<input type=\"file\">`: the secondary button's face, as wide as its row and\n * eight squares high (`--compact`: four), its words centred in a square of\n * padding. The input covers the zone unseen, so a click, the keyboard and a\n * dropped file all reach it, and the browser keeps labels, forms, `required`,\n * `multiple` and reset. Keyboard focus draws the focus ring. A page that also\n * handles drops on a larger surface sets `data-dragging` on the zone while\n * files are dragged over it, for the ring and the hover fill. A `.ds-button`\n * on a `<span>` inside draws a button face among the words.\n *\n * The same native input directly inside a `label.ds-button` is the file\n * picker's button: the button's face, one square high.\n */\n\n.ds-drop {\n box-sizing: border-box;\n position: relative;\n display: flex;\n flex-wrap: wrap;\n align-content: center;\n align-items: center;\n justify-content: center;\n gap: calc(var(--ds-unit) / 2);\n width: 100%;\n min-width: 0;\n height: calc(8 * var(--ds-unit));\n margin: 0;\n padding: var(--ds-unit);\n overflow: hidden;\n border-radius: var(--ds-radius);\n corner-shape: var(--ds-corner-shape, round);\n background: var(--ds-button-background-color-secondary);\n color: var(--ds-button-text-color);\n font-family: var(--ds-typeface-regular);\n font-feature-settings: var(--ds-font-features);\n font-size: var(--ds-type-size-default);\n font-weight: var(--ds-type-weight-default);\n line-height: var(--ds-type-lineheight-default);\n letter-spacing: var(--ds-type-letterspacing-default);\n text-align: center;\n cursor: pointer;\n user-select: none;\n -webkit-user-select: none;\n -webkit-tap-highlight-color: transparent;\n}\n\n.ds-drop--compact {\n height: calc(4 * var(--ds-unit));\n}\n\nlabel.ds-button:has(> input[type=\"file\"]) {\n --ds-button-height: var(--ds-row-height);\n position: relative;\n overflow: hidden;\n}\n\n:is(.ds-drop, label.ds-button) > input[type=\"file\"]:not([hidden]) {\n position: absolute;\n inset: 0;\n box-sizing: border-box;\n display: block;\n width: 100%;\n height: 100%;\n min-width: 0;\n margin: 0;\n padding: 0;\n border: 0;\n opacity: 0;\n cursor: pointer;\n}\n\n:is(.ds-drop, label.ds-button) > input[type=\"file\"]::file-selector-button {\n cursor: pointer;\n}\n\n.ds-drop:hover:not(:has(> input:disabled)),\n.ds-drop[data-dragging]:not(:has(> input:disabled)) {\n background: var(--ds-fill-hover);\n}\n\n.ds-drop:has(> input:focus-visible),\n.ds-drop[data-dragging]:not(:has(> input:disabled)),\nlabel.ds-button:has(> input[type=\"file\"]:focus-visible) {\n outline: 2px solid var(--ds-focus-ring);\n outline-offset: 1px;\n}\n\n.ds-drop:has(> input:disabled),\nlabel.ds-button:has(> input[type=\"file\"]:disabled) {\n cursor: default;\n opacity: 0.5;\n}\n\n:is(.ds-drop, label.ds-button) > input[type=\"file\"]:disabled {\n cursor: default;\n}\n";
8832
8832
  //#endregion
8833
8833
  //#region DS1/2-core/styles/ds-notice.css?inline
8834
8834
  var ds_notice_default = "/* ds-notice.css */\n/* The element only places the block; 1-root/notice.css draws it and\n controls.css its dismiss button. */\n\n:host {\n display: block;\n min-width: 0;\n}\n\n:host([hidden]),\n[hidden] {\n display: none !important;\n}\n\n/* The banner is placed by the host; its block then fills the host. */\n:host([banner]),\n:host([form=\"banner\"]) {\n position: absolute;\n top: 0;\n inset-inline: 0;\n z-index: 9999;\n}\n:host([banner]) .ds-notice--banner,\n:host([form=\"banner\"]) .ds-notice--banner {\n position: static;\n}\n\n/* The app banner stands in the flow, at the top of the page. */\n:host([form=\"app\"]) {\n display: block;\n}\n\n/* Slotted words take the notice's lines rather than their own margins. */\n::slotted([slot=\"heading\"]),\n::slotted(:not([slot])) {\n margin: 0;\n}\n\n/* The app's own picture in the icon slot fills its two squares. */\n::slotted(img[slot=\"icon\"]) {\n display: block;\n width: 100%;\n height: 100%;\n object-fit: cover;\n}\n";
@@ -10695,6 +10695,23 @@ function isoWeek(day) {
10695
10695
  const firstThursday = addDays(january4, 3 - (weekdayOf(january4) + 6) % 7);
10696
10696
  return 1 + Math.round((noon(thursday) - noon(firstThursday)) / 6048e5);
10697
10697
  }
10698
+ /**
10699
+ * How strongly each day is lit, as a contribution graph lights it: the
10700
+ * amounts of its events added up, in four steps of the busiest day (or of
10701
+ * `max`, for a scale that stays put from month to month). A day with nothing
10702
+ * has no level.
10703
+ */
10704
+ function heatLevels(byDay, max) {
10705
+ const amounts = /* @__PURE__ */ new Map();
10706
+ for (const [day, events] of byDay) {
10707
+ const amount = events.reduce((sum, event) => sum + (typeof event.count === "number" && Number.isFinite(event.count) ? Math.max(0, event.count) : 1), 0);
10708
+ if (amount > 0) amounts.set(day, amount);
10709
+ }
10710
+ const top = typeof max === "number" && Number.isFinite(max) && max > 0 ? max : Math.max(0, ...amounts.values());
10711
+ const levels = /* @__PURE__ */ new Map();
10712
+ for (const [day, amount] of amounts) levels.set(day, Math.min(4, Math.max(1, Math.ceil(amount / top * 4))));
10713
+ return levels;
10714
+ }
10698
10715
  /** The events that touch each day between `from` and `to`, in order: longest first, then by time. */
10699
10716
  function eventsByDay(events, from, to) {
10700
10717
  const days = /* @__PURE__ */ new Map();
@@ -10928,7 +10945,7 @@ _CalendarBase.properties = {
10928
10945
  };
10929
10946
  //#endregion
10930
10947
  //#region DS1/3-unit/styles/ds-calendar.css?inline
10931
- var ds_calendar_default = "/* ds-calendar.css\n * A month on whole squares. A day is --ds-calendar-day-squares wide (four,\n * one when compact) and, beside its date's square, holds --ds-calendar-lines\n * one-square lines of events and one square to spare. Every line of words\n * stands on the lower sixteen of its square. The boxes are hairlines centred\n * on the grid lines; today is a red disc nine tenths of a square across.\n *\n * A picker is the select's face: one control high at the foot of its square,\n * ten squares wide by default, the calendar icon at its start and the down\n * arrow at its end. Its month opens on the menu's frame, half a square from\n * the field: a 1px line, half a square inside it, no shadow, so eight squares\n * wide. Inside, on whole squares: the first and last day to type (each with\n * its time below when times are on), one square spare, the compact month one\n * square a day, then Include time and Clear, each one square, set off by\n * one-square separators with a line through them. */\n\n:host {\n --ds-calendar-day: calc(var(--ds-unit) * var(--ds-calendar-day-squares, 4));\n --ds-calendar-day-height: calc(var(--ds-unit) * (var(--ds-calendar-lines, 2) + 2));\n --ds-calendar-line: 1px solid var(--ds-border-color);\n --ds-calendar-today: var(--ds-red-for-blood);\n --ds-calendar-today-ink: var(--ds-white, #fff);\n --ds-calendar-selected: var(--ds-sharp-blue);\n --ds-calendar-selected-ink: var(--ds-white, #fff);\n --ds-calendar-band: color-mix(in srgb, var(--ds-calendar-selected) 16%, var(--ds-paper));\n --ds-calendar-mark: calc(var(--ds-unit) * 0.9);\n --ds-calendar-pad: calc(4px * var(--ds-sf, 1));\n box-sizing: border-box;\n display: inline-block;\n vertical-align: top;\n color: var(--ds-text-color);\n font-family: var(--ds-typeface-regular);\n font-feature-settings: var(--ds-font-features);\n font-size: var(--ds-type-size-default);\n font-weight: var(--ds-type-weight-default);\n line-height: var(--ds-type-lineheight-default);\n letter-spacing: var(--ds-type-letterspacing-default);\n}\n:host([hidden]) { display: none !important; }\n/* A compact day is square: one square, or two where the month has room. Its marks grow with it. */\n:host([compact]) {\n --ds-calendar-day-height: var(--ds-calendar-day);\n --ds-calendar-mark: calc(var(--ds-unit) * (var(--ds-calendar-day-squares, 1) * 0.75 + 0.15));\n}\n\n.calendar { width: calc(7 * var(--ds-calendar-day)); }\n\n/* The title and the arrows: one square, one square above the days (none when compact). */\n.header {\n box-sizing: border-box;\n display: flex;\n align-items: flex-end;\n gap: var(--ds-calendar-pad);\n height: var(--ds-unit);\n margin-block-end: var(--ds-unit);\n}\n:host([compact]) .header { margin-block-end: 0; }\n.title {\n flex: 1 1 auto;\n min-width: 0;\n overflow: hidden;\n font-family: var(--ds-typeface-medium, var(--ds-typeface-regular));\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n.controls {\n display: flex;\n flex: 0 0 auto;\n align-items: flex-end;\n gap: 0;\n}\n/* Each arrow is a chevron on its own square, one control high at the square's foot,\n * in the title grey; the pointer fills it with the system's corners and inks it. */\n.nav {\n flex: 0 0 auto;\n width: var(--ds-unit);\n height: var(--ds-control-height);\n border-radius: var(--ds-radius);\n color: var(--ds-title-color);\n}\n.nav:hover:not(:disabled) { background: var(--ds-fill); color: var(--ds-text-color); }\n:host(:dir(rtl)) .nav > ds-icon { transform: scaleX(-1); }\n\n.grid { outline: none; }\n.weekdays,\n.week {\n display: grid;\n grid-template-columns: repeat(7, var(--ds-calendar-day));\n}\n\n/* The weekday names: a block line in the title grey, at the start of a wide day, centred on a compact one. */\n.weekday {\n box-sizing: border-box;\n height: var(--ds-unit);\n padding: calc(4px * var(--ds-sf, 1)) var(--ds-calendar-pad) 0;\n overflow: hidden;\n color: var(--ds-title-color);\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n:host([compact]) .weekday { padding-inline: 0; text-align: center; }\n\n/* A day's box: hairlines on the grid lines, top and start; the last column\n * and the last week close it at the end and the foot. */\n.day {\n position: relative;\n box-sizing: border-box;\n min-width: 0;\n height: var(--ds-calendar-day-height);\n outline: none;\n}\n.day::after {\n position: absolute;\n inset: -0.5px;\n border-block-start: var(--ds-calendar-line);\n border-inline-start: var(--ds-calendar-line);\n content: \"\";\n pointer-events: none;\n}\n.day:nth-child(7)::after { border-inline-end: var(--ds-calendar-line); }\n.week:last-child .day::after { border-block-end: var(--ds-calendar-line); }\n:host([compact]) .day::after { content: none; }\n\n.day[data-day] { cursor: default; }\n:host([selectable]) .day[data-day]:not([aria-disabled=\"true\"]) { cursor: pointer; }\n:host([selectable]:not([compact])) .day[data-day]:not([aria-disabled=\"true\"]):hover { background: var(--ds-row-fill-hover, var(--ds-fill)); }\n.day:focus-visible { outline: 2px solid var(--ds-focus-ring); outline-offset: -2px; }\n:host([compact]) .day:focus-visible { outline: none; }\n:host([compact]) .day:focus-visible .date { outline: 2px solid var(--ds-focus-ring); outline-offset: -1px; }\n\n/* The date: on the first square, at the end of a wide day, in the title grey. */\n.date-line {\n box-sizing: border-box;\n display: flex;\n align-items: flex-end;\n justify-content: flex-end;\n gap: var(--ds-calendar-pad);\n height: var(--ds-unit);\n padding-inline: var(--ds-calendar-pad);\n}\n.date {\n color: var(--ds-title-color);\n font-variant-numeric: tabular-nums;\n}\n.week-number {\n margin-inline-end: auto;\n color: var(--ds-title-color);\n font-family: var(--ds-typeface-compressed);\n}\n\n/* A compact day: the date centred in its square, in the ink; with events,\n * the empty days fall back to the title grey and the busy ones keep the ink. */\n:host([compact]) .date-line { justify-content: center; padding: 0; }\n:host([compact]) .date { color: var(--ds-text-color); }\n:host([compact][data-events]) .day:not([data-busy]) .date { color: var(--ds-title-color); }\n:host([compact][selectable]) .day[data-day]:not([aria-disabled=\"true\"], [data-today], [data-selected]):hover .date { background: var(--ds-fill); }\n\n/* Today and the selected day: a disc nine tenths of a square, centred on the date's square. */\n.day:is([data-today], [data-selected]) .date-line { align-items: center; padding-inline-end: calc(var(--ds-unit) * 0.05); }\n:host([compact]) .day:is([data-today], [data-selected]) .date-line { padding: 0; }\n.date {\n box-sizing: border-box;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n min-width: var(--ds-calendar-mark);\n height: var(--ds-calendar-mark);\n border-radius: 999px;\n}\n.day:not([data-today], [data-selected]) .date { min-width: 0; height: auto; }\n:host([compact]) .day .date { min-width: var(--ds-calendar-mark); height: var(--ds-calendar-mark); }\n.day[data-today] .date { background: var(--ds-calendar-today); color: var(--ds-calendar-today-ink); letter-spacing: 0; }\n/* The selected day, and each end of a range: a square with the system's corners in the selection's blue. */\n.day[data-selected] .date { border-radius: var(--ds-radius); background: var(--ds-calendar-selected); color: var(--ds-calendar-selected-ink); letter-spacing: 0; }\n\n.day[aria-disabled=\"true\"] .date { color: var(--ds-title-color); opacity: 0.5; }\n\n/* Events: one square each, stacked edge to edge on the day's lines, drawn one pixel short. */\n.events {\n display: flex;\n flex-direction: column;\n}\n.event,\n.more {\n box-sizing: border-box;\n display: flex;\n align-items: flex-end;\n gap: var(--ds-calendar-pad);\n height: calc(var(--ds-unit) - 1px);\n margin: 0.5px;\n padding-inline: var(--ds-calendar-pad);\n overflow: hidden;\n white-space: nowrap;\n}\n.event {\n background: var(--ds-calendar-event-fill, var(--ds-fill));\n color: var(--ds-calendar-event-ink, var(--ds-text-color));\n cursor: pointer;\n}\n.event .name { min-width: 0; overflow: hidden; text-overflow: ellipsis; }\n.event .time { flex: 0 0 auto; opacity: 0.6; font-variant-numeric: tabular-nums; }\n.more { color: var(--ds-title-color); cursor: pointer; }\n.more:hover { color: var(--ds-text-color); }\n\n/* A day whose hidden events are unfolded lays them over the days below. */\n.day[data-open] { z-index: 1; }\n.day[data-open] .events {\n position: absolute;\n inset-block-start: var(--ds-unit);\n inset-inline: 0;\n background: var(--ds-paper);\n box-shadow: 0 0 0 1px var(--ds-border-color);\n}\n\n@media (prefers-reduced-motion: no-preference) {\n .event, .more { transition: opacity 120ms ease; }\n}\n\n/* A compact day's date stands in the middle of its square once the square is two or more wide. */\n:host([compact][data-roomy]) .date-line { align-items: center; height: var(--ds-calendar-day-height); }\n\n/* The days of the months before and after, in the title grey. */\n.day[data-outside] .date { color: var(--ds-title-color); }\n:host([compact]) .day[data-outside] .date { color: var(--ds-title-color); }\n\n/* A range: the days between its ends on a band of the selection's blue; the band runs into each end's square. */\n.day[data-inside] { background: var(--ds-calendar-band); }\n:host(:not([compact])) .day:is([data-first], [data-last]) { background: var(--ds-calendar-band); }\n:host([compact]) .day[data-first] { background: linear-gradient(to right, transparent 50%, var(--ds-calendar-band) 50%); }\n:host([compact]) .day[data-last] { background: linear-gradient(to left, transparent 50%, var(--ds-calendar-band) 50%); }\n:host([compact]:dir(rtl)) .day[data-first] { background: linear-gradient(to left, transparent 50%, var(--ds-calendar-band) 50%); }\n:host([compact]:dir(rtl)) .day[data-last] { background: linear-gradient(to right, transparent 50%, var(--ds-calendar-band) 50%); }\n:host([compact][selectable]) .day[data-inside]:hover .date { background: transparent; }\n\n/* Today, as words in the title grey beside the arrows. */\n.today-button {\n height: var(--ds-control-height);\n padding-inline: calc(4px * var(--ds-sf, 1));\n border: 0;\n background: transparent;\n color: var(--ds-title-color);\n}\n.today-button:hover { background: var(--ds-fill); color: var(--ds-text-color); }\n\n/* In a compact month the pointer's day and the chosen day take squares with the system's corners; today keeps its disc. */\n:host([compact]) .date { border-radius: var(--ds-radius); }\n:host([compact]) .day[data-today]:not([data-selected]) .date { border-radius: 999px; }\n\n/* The picker: a field that opens the small month. */\n:host([picker]) {\n --ds-calendar-picker-width: calc(10 * var(--ds-unit));\n display: inline-flex;\n align-items: flex-end;\n vertical-align: bottom;\n height: var(--ds-unit);\n}\n\n.trigger {\n display: inline-flex;\n align-items: flex-end;\n gap: calc(4px * var(--ds-sf, 1));\n width: var(--ds-calendar-picker-width);\n padding-inline: 0 calc(4px * var(--ds-sf, 1));\n text-align: start;\n cursor: pointer;\n}\n.trigger:disabled { cursor: default; }\n.trigger .icon,\n.trigger .arrow { flex: 0 0 auto; }\n.trigger .text {\n flex: 1 1 auto;\n min-width: 0;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n.trigger[data-empty] .text { color: var(--ds-title-color); }\n.trigger[aria-expanded=\"true\"] .arrow { transform: rotate(180deg); }\n\n/* The month's panel, on the menu's frame. */\n.popover {\n position: fixed;\n inset: auto;\n box-sizing: border-box;\n margin: 0;\n padding: calc(var(--ds-unit) / 2 - 1px);\n border: 1px solid var(--ds-border-color);\n border-radius: var(--ds-radius-card);\n background: var(--ds-paper);\n color: var(--ds-text-color);\n box-shadow: none;\n overflow: visible;\n}\n.popover:not(:popover-open) { display: none; }\n\n/* The days to type: a row of one square for each end, its time on the row below; one square spare after. */\n.fields { margin-block-end: var(--ds-unit); }\n.field-row {\n display: flex;\n align-items: flex-end;\n gap: calc(var(--ds-unit) / 2);\n height: var(--ds-unit);\n}\n.field { flex: 1 1 auto; min-width: 0; }\n.clock { flex: 1 1 auto; min-width: 0; }\n.fields, .options { width: calc(7 * var(--ds-unit)); }\n\n/* Include time and Clear, each one square, the words on the sixteen. */\n.option {\n box-sizing: border-box;\n display: flex;\n align-items: flex-end;\n justify-content: space-between;\n gap: var(--ds-unit);\n width: 100%;\n height: var(--ds-unit);\n margin: 0;\n padding: 0 calc(4px * var(--ds-sf, 1));\n border: 0;\n border-radius: var(--ds-radius);\n background: transparent;\n color: var(--ds-text-color);\n font: inherit;\n letter-spacing: inherit;\n text-align: start;\n cursor: pointer;\n}\n.option:hover:not(:disabled) { background: var(--ds-row-fill-hover, var(--ds-fill)); }\n.option:focus-visible { outline: 2px solid var(--ds-focus-ring); outline-offset: -2px; }\n.option:disabled { color: var(--ds-title-color); cursor: default; }\n.option .ds-switch { flex: 0 0 auto; }\n\n/* A separator: one square with a 1px line through its middle. */\n.separator {\n position: relative;\n height: var(--ds-unit);\n}\n.separator::after {\n position: absolute;\n inset-inline: 0;\n top: calc(50% - 0.5px);\n height: 1px;\n background: var(--ds-border-color);\n content: \"\";\n}\n\n@media (prefers-reduced-motion: no-preference) {\n .popover:popover-open {\n animation: ds-calendar-picker-in 140ms cubic-bezier(0.22, 1, 0.36, 1);\n }\n .trigger .arrow { transition: transform 140ms ease; }\n}\n@keyframes ds-calendar-picker-in {\n from { opacity: 0; transform: translateY(calc(-4px * var(--ds-sf, 1))); }\n to { opacity: 1; transform: none; }\n}\n";
10948
+ var ds_calendar_default = "/* ds-calendar.css\n * A month on whole squares. A day is --ds-calendar-day-squares wide (four,\n * one when compact) and, beside its date's square, holds --ds-calendar-lines\n * one-square lines of events and one square to spare. Every line of words\n * stands on the lower sixteen of its square. The boxes are hairlines centred\n * on the grid lines; today is a red disc nine tenths of a square across.\n *\n * A picker is a field's face: one control high at the foot of its square,\n * ten squares wide by default, its words 4px in and the chevron-down icon\n * (16px, 2px from the end) at its end; a range is one value. Its month opens on the menu's frame, half a square from\n * the field: a 1px line, half a square inside it, no shadow, so eight squares\n * wide. Inside, on whole squares: the first and last day to type (each with\n * its time below when times are on), one square spare, the compact month one\n * square a day, then Include time and Clear, each one square, set off by\n * one-square separators with a line through them. */\n\n:host {\n --ds-calendar-day: calc(var(--ds-unit) * var(--ds-calendar-day-squares, 4));\n --ds-calendar-day-height: calc(var(--ds-unit) * (var(--ds-calendar-lines, 2) + 2));\n --ds-calendar-line: 1px solid var(--ds-border-color);\n --ds-calendar-today: var(--ds-red-for-blood);\n --ds-calendar-today-ink: var(--ds-white, #fff);\n --ds-calendar-selected: var(--ds-sharp-blue);\n --ds-calendar-selected-ink: var(--ds-white, #fff);\n --ds-calendar-band: color-mix(in srgb, var(--ds-calendar-selected) 16%, var(--ds-paper));\n --ds-calendar-mark: calc(var(--ds-unit) * 0.9);\n --ds-calendar-pad: calc(4px * var(--ds-sf, 1));\n /* Heat, in four steps of the accent: its pastel, between, the colour, and\n past it (deepened with the ink on light paper, the full colour on dark).\n The words are the ink on every step but the two darkest on dark paper. */\n --ds-calendar-heat-1: var(--one-apple-green-pastel, color-mix(in srgb, var(--ds-apple-green) 40%, var(--ds-paper)));\n --ds-calendar-heat-3: var(--one-apple-green, var(--ds-apple-green));\n --ds-calendar-heat-2: color-mix(in srgb, var(--ds-calendar-heat-1), var(--ds-calendar-heat-3));\n --ds-calendar-heat-4: light-dark(color-mix(in srgb, var(--ds-apple-green) 60%, var(--ds-slate)), var(--ds-apple-green));\n --ds-calendar-heat-ink-1: light-dark(var(--ds-slate), var(--ds-white));\n --ds-calendar-heat-ink-2: light-dark(var(--ds-slate), var(--ds-white));\n --ds-calendar-heat-ink-3: var(--ds-slate);\n --ds-calendar-heat-ink-4: var(--ds-slate);\n box-sizing: border-box;\n display: inline-block;\n vertical-align: top;\n color: var(--ds-text-color);\n font-family: var(--ds-typeface-regular);\n font-feature-settings: var(--ds-font-features);\n font-size: var(--ds-type-size-default);\n font-weight: var(--ds-type-weight-default);\n line-height: var(--ds-type-lineheight-default);\n letter-spacing: var(--ds-type-letterspacing-default);\n}\n:host([hidden]) { display: none !important; }\n/* A compact day is square: one square, or two where the month has room. Its marks grow with it. */\n:host([compact]) {\n --ds-calendar-day-height: var(--ds-calendar-day);\n --ds-calendar-mark: calc(var(--ds-unit) * (var(--ds-calendar-day-squares, 1) * 0.75 + 0.15));\n}\n\n.calendar { width: calc(7 * var(--ds-calendar-day)); }\n\n/* The title and the arrows: one square, one square above the days (none when compact). */\n.header {\n box-sizing: border-box;\n display: flex;\n align-items: flex-end;\n gap: var(--ds-calendar-pad);\n height: var(--ds-unit);\n margin-block-end: var(--ds-unit);\n}\n:host([compact]) .header { margin-block-end: 0; }\n.title {\n flex: 1 1 auto;\n min-width: 0;\n overflow: hidden;\n font-family: var(--ds-typeface-medium, var(--ds-typeface-regular));\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n.controls {\n display: flex;\n flex: 0 0 auto;\n align-items: flex-end;\n gap: 0;\n}\n/* Each arrow is a chevron on its own square, one control high at the square's foot,\n * in the title grey; the pointer fills it with the system's corners and inks it. */\n.nav {\n flex: 0 0 auto;\n width: var(--ds-unit);\n height: var(--ds-control-height);\n border-radius: var(--ds-radius);\n color: var(--ds-title-color);\n}\n.nav:hover:not(:disabled) { background: var(--ds-fill); color: var(--ds-text-color); }\n:host(:dir(rtl)) .nav > ds-icon { transform: scaleX(-1); }\n\n.grid { outline: none; }\n.weekdays,\n.week {\n display: grid;\n grid-template-columns: repeat(7, var(--ds-calendar-day));\n}\n\n/* The weekday names: a block line in the title grey, at the start of a wide day, centred on a compact one. */\n.weekday {\n box-sizing: border-box;\n height: var(--ds-unit);\n padding: calc(4px * var(--ds-sf, 1)) var(--ds-calendar-pad) 0;\n overflow: hidden;\n color: var(--ds-title-color);\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n:host([compact]) .weekday { padding-inline: 0; text-align: center; }\n\n/* A day's box: hairlines on the grid lines, top and start; the last column\n * and the last week close it at the end and the foot. */\n.day {\n position: relative;\n box-sizing: border-box;\n min-width: 0;\n height: var(--ds-calendar-day-height);\n outline: none;\n}\n.day::after {\n position: absolute;\n inset: -0.5px;\n border-block-start: var(--ds-calendar-line);\n border-inline-start: var(--ds-calendar-line);\n content: \"\";\n pointer-events: none;\n}\n.day:nth-child(7)::after { border-inline-end: var(--ds-calendar-line); }\n.week:last-child .day::after { border-block-end: var(--ds-calendar-line); }\n:host([compact]) .day::after { content: none; }\n\n.day[data-day] { cursor: default; }\n:host([selectable]) .day[data-day]:not([aria-disabled=\"true\"]) { cursor: pointer; }\n:host([selectable]:not([compact])) .day[data-day]:not([aria-disabled=\"true\"]):hover { background: var(--ds-row-fill-hover, var(--ds-fill)); }\n.day:focus-visible { outline: 2px solid var(--ds-focus-ring); outline-offset: -2px; }\n:host([compact]) .day:focus-visible { outline: none; }\n:host([compact]) .day:focus-visible .date { outline: 2px solid var(--ds-focus-ring); outline-offset: -1px; }\n\n/* The date: on the first square, at the end of a wide day, in the title grey. */\n.date-line {\n box-sizing: border-box;\n display: flex;\n align-items: flex-end;\n justify-content: flex-end;\n gap: var(--ds-calendar-pad);\n height: var(--ds-unit);\n padding-inline: var(--ds-calendar-pad);\n}\n.date {\n color: var(--ds-title-color);\n font-variant-numeric: tabular-nums;\n}\n.week-number {\n margin-inline-end: auto;\n color: var(--ds-title-color);\n font-family: var(--ds-typeface-compressed);\n}\n\n/* A compact day: the date centred in its square, in the ink; with events,\n * the empty days fall back to the title grey and the busy ones keep the ink. */\n:host([compact]) .date-line { justify-content: center; padding: 0; }\n:host([compact]) .date { color: var(--ds-text-color); }\n:host([compact][data-events]) .day:not([data-busy]) .date { color: var(--ds-title-color); }\n:host([compact][selectable]) .day[data-day]:not([aria-disabled=\"true\"], [data-today], [data-selected]):hover .date { background: var(--ds-fill); }\n\n/* Today and the selected day: a disc nine tenths of a square, centred on the date's square. */\n.day:is([data-today], [data-selected]) .date-line { align-items: center; padding-inline-end: calc(var(--ds-unit) * 0.05); }\n:host([compact]) .day:is([data-today], [data-selected]) .date-line { padding: 0; }\n.date {\n box-sizing: border-box;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n min-width: var(--ds-calendar-mark);\n height: var(--ds-calendar-mark);\n border-radius: 999px;\n}\n.day:not([data-today], [data-selected]) .date { min-width: 0; height: auto; }\n:host([compact]) .day .date { min-width: var(--ds-calendar-mark); height: var(--ds-calendar-mark); }\n.day[data-today] .date { background: var(--ds-calendar-today); color: var(--ds-calendar-today-ink); letter-spacing: 0; }\n/* The selected day, and each end of a range: a square with the system's corners in the selection's blue. */\n.day[data-selected] .date { border-radius: var(--ds-radius); background: var(--ds-calendar-selected); color: var(--ds-calendar-selected-ink); letter-spacing: 0; }\n\n.day[aria-disabled=\"true\"] .date { color: var(--ds-title-color); opacity: 0.5; }\n\n/* Heat: the date's mark filled by its step, a picture's corners, inside the day's square; today and the selection draw over it. */\n.day[data-heat]:not([data-today], [data-selected]) .date-line { align-items: center; padding-inline-end: calc(var(--ds-unit) * 0.05); }\n.day[data-heat]:not([data-today], [data-selected]) .date {\n min-width: var(--ds-calendar-mark);\n height: var(--ds-calendar-mark);\n border-radius: var(--ds-radius);\n letter-spacing: 0;\n}\n.day[data-heat=\"1\"]:not([data-today], [data-selected]) .date { background: var(--ds-calendar-heat-1); color: var(--ds-calendar-heat-ink-1); }\n.day[data-heat=\"2\"]:not([data-today], [data-selected]) .date { background: var(--ds-calendar-heat-2); color: var(--ds-calendar-heat-ink-2); }\n.day[data-heat=\"3\"]:not([data-today], [data-selected]) .date { background: var(--ds-calendar-heat-3); color: var(--ds-calendar-heat-ink-3); }\n.day[data-heat=\"4\"]:not([data-today], [data-selected]) .date { background: var(--ds-calendar-heat-4); color: var(--ds-calendar-heat-ink-4); }\n:host([compact]) .day[data-heat]:not([data-today], [data-selected]) .date-line { padding: 0; }\n\n/* Events: one square each, stacked edge to edge on the day's lines, drawn one pixel short. */\n.events {\n display: flex;\n flex-direction: column;\n}\n.event,\n.more {\n box-sizing: border-box;\n display: flex;\n align-items: flex-end;\n gap: var(--ds-calendar-pad);\n height: calc(var(--ds-unit) - 1px);\n margin: 0.5px;\n padding-inline: var(--ds-calendar-pad);\n overflow: hidden;\n white-space: nowrap;\n}\n.event {\n background: var(--ds-calendar-event-fill, var(--ds-fill));\n color: var(--ds-calendar-event-ink, var(--ds-text-color));\n cursor: pointer;\n}\n.event .name { min-width: 0; overflow: hidden; text-overflow: ellipsis; }\n.event .time { flex: 0 0 auto; opacity: 0.6; font-variant-numeric: tabular-nums; }\n.more { color: var(--ds-title-color); cursor: pointer; }\n.more:hover { color: var(--ds-text-color); }\n\n/* A day whose hidden events are unfolded lays them over the days below. */\n.day[data-open] { z-index: 1; }\n.day[data-open] .events {\n position: absolute;\n inset-block-start: var(--ds-unit);\n inset-inline: 0;\n background: var(--ds-paper);\n box-shadow: 0 0 0 1px var(--ds-border-color);\n}\n\n@media (prefers-reduced-motion: no-preference) {\n .event, .more { transition: opacity 120ms ease; }\n}\n\n/* A compact day's date stands in the middle of its square once the square is two or more wide. */\n:host([compact][data-roomy]) .date-line { align-items: center; height: var(--ds-calendar-day-height); }\n\n/* The days of the months before and after, in the title grey. */\n.day[data-outside] .date { color: var(--ds-title-color); }\n:host([compact]) .day[data-outside] .date { color: var(--ds-title-color); }\n\n/* A range: the days between its ends on a band of the selection's blue; the band runs into each end's square. */\n.day[data-inside] { background: var(--ds-calendar-band); }\n:host(:not([compact])) .day:is([data-first], [data-last]) { background: var(--ds-calendar-band); }\n:host([compact]) .day[data-first] { background: linear-gradient(to right, transparent 50%, var(--ds-calendar-band) 50%); }\n:host([compact]) .day[data-last] { background: linear-gradient(to left, transparent 50%, var(--ds-calendar-band) 50%); }\n:host([compact]:dir(rtl)) .day[data-first] { background: linear-gradient(to left, transparent 50%, var(--ds-calendar-band) 50%); }\n:host([compact]:dir(rtl)) .day[data-last] { background: linear-gradient(to right, transparent 50%, var(--ds-calendar-band) 50%); }\n:host([compact][selectable]) .day[data-inside]:hover .date { background: transparent; }\n\n/* Today, as words in the title grey beside the arrows. */\n.today-button {\n height: var(--ds-control-height);\n padding-inline: calc(4px * var(--ds-sf, 1));\n border: 0;\n background: transparent;\n color: var(--ds-title-color);\n}\n.today-button:hover { background: var(--ds-fill); color: var(--ds-text-color); }\n\n/* In a compact month the pointer's day and the chosen day take squares with the system's corners; today keeps its disc. */\n:host([compact]) .date { border-radius: var(--ds-radius); }\n:host([compact]) .day[data-today]:not([data-selected]) .date { border-radius: 999px; }\n\n/* The picker: a field that opens the small month. */\n:host([picker]) {\n --ds-calendar-picker-width: calc(10 * var(--ds-unit));\n display: inline-flex;\n align-items: flex-end;\n vertical-align: bottom;\n height: var(--ds-unit);\n}\n\n.trigger {\n display: inline-flex;\n align-items: center;\n gap: calc(4px * var(--ds-sf, 1));\n width: var(--ds-calendar-picker-width);\n padding-inline: calc(4px * var(--ds-sf, 1)) calc(2px * var(--ds-sf, 1));\n text-align: start;\n cursor: pointer;\n}\n.trigger:disabled { cursor: default; }\n.trigger .arrow { flex: 0 0 auto; }\n.trigger .text {\n flex: 1 1 auto;\n min-width: 0;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n.trigger[data-empty] .text { color: var(--ds-title-color); }\n\n/* The month's panel, on the menu's frame. */\n.popover {\n position: fixed;\n inset: auto;\n box-sizing: border-box;\n margin: 0;\n padding: calc(var(--ds-unit) / 2 - 1px);\n border: 1px solid var(--ds-border-color);\n border-radius: var(--ds-radius-card);\n background: var(--ds-paper);\n color: var(--ds-text-color);\n box-shadow: none;\n overflow: visible;\n}\n.popover:not(:popover-open) { display: none; }\n\n/* The days to type: a row of one square for each end, its time on the row below; one square spare after. */\n.fields { margin-block-end: var(--ds-unit); }\n.field-row {\n display: flex;\n align-items: flex-end;\n gap: calc(var(--ds-unit) / 2);\n height: var(--ds-unit);\n}\n.field { flex: 1 1 auto; min-width: 0; }\n.clock { flex: 1 1 auto; min-width: 0; }\n.fields, .options { width: calc(7 * var(--ds-unit)); }\n\n/* Include time and Clear, each one square, the words on the sixteen. */\n.option {\n box-sizing: border-box;\n display: flex;\n align-items: flex-end;\n justify-content: space-between;\n gap: var(--ds-unit);\n width: 100%;\n height: var(--ds-unit);\n margin: 0;\n padding: 0 calc(4px * var(--ds-sf, 1));\n border: 0;\n border-radius: var(--ds-radius);\n background: transparent;\n color: var(--ds-text-color);\n font: inherit;\n letter-spacing: inherit;\n text-align: start;\n cursor: pointer;\n}\n.option:hover:not(:disabled) { background: var(--ds-row-fill-hover, var(--ds-fill)); }\n.option:focus-visible { outline: 2px solid var(--ds-focus-ring); outline-offset: -2px; }\n.option:disabled { color: var(--ds-title-color); cursor: default; }\n.option .ds-switch { flex: 0 0 auto; }\n\n/* A separator: one square with a 1px line through its middle. */\n.separator {\n position: relative;\n height: var(--ds-unit);\n}\n.separator::after {\n position: absolute;\n inset-inline: 0;\n top: calc(50% - 0.5px);\n height: 1px;\n background: var(--ds-border-color);\n content: \"\";\n}\n\n@media (prefers-reduced-motion: no-preference) {\n .popover:popover-open {\n animation: ds-calendar-picker-in 140ms cubic-bezier(0.22, 1, 0.36, 1);\n }\n}\n@keyframes ds-calendar-picker-in {\n from { opacity: 0; transform: translateY(calc(-4px * var(--ds-sf, 1))); }\n to { opacity: 1; transform: none; }\n}\n";
10932
10949
  //#endregion
10933
10950
  //#region DS1/3-unit/ds-calendar.ts
10934
10951
  var _Calendar;
@@ -10991,6 +11008,12 @@ var openPickers = /* @__PURE__ */ new Set();
10991
11008
  * @prop {boolean} fixed - Always draw six weeks, so the month keeps its height.
10992
11009
  * @prop {boolean} outsideDays - Draw the days of the months before and after
10993
11010
  * in the title grey (`outside-days`); pressing one moves there.
11011
+ * @prop {boolean} heat - Light each day by how much happens on it, as a
11012
+ * contribution graph does: the events' `count`s added up (one each by
11013
+ * default), in four steps of the busiest day shown.
11014
+ * @prop {number} heatMax - The amount that lights a day fully (`heat-max`),
11015
+ * for a scale that stays put from month to month; the busiest day shown
11016
+ * by default.
10994
11017
  * @prop {boolean} noHeader - Leave out the title and arrows (`no-header`).
10995
11018
  * @prop {boolean} noToday - Leave out the Today button (`no-today`).
10996
11019
  * @prop {string} min - The first day a person may choose.
@@ -11030,6 +11053,7 @@ var Calendar = class extends CalendarBase {
11030
11053
  super();
11031
11054
  this.weeksRun = "rows";
11032
11055
  this.byDay = /* @__PURE__ */ new Map();
11056
+ this.heatByDay = /* @__PURE__ */ new Map();
11033
11057
  this.internals = typeof this.attachInternals === "function" ? this.attachInternals() : null;
11034
11058
  this.initial = "";
11035
11059
  this.shown = false;
@@ -11169,6 +11193,7 @@ var Calendar = class extends CalendarBase {
11169
11193
  this.outsideDays = false;
11170
11194
  this.noHeader = false;
11171
11195
  this.noToday = false;
11196
+ this.heat = false;
11172
11197
  this.picker = false;
11173
11198
  this.time = false;
11174
11199
  this.required = false;
@@ -11291,13 +11316,15 @@ var Calendar = class extends CalendarBase {
11291
11316
  const unfolded = this.unfolded === day;
11292
11317
  const shown = unfolded || events.length <= lines ? events : events.slice(0, Math.max(0, lines - 1));
11293
11318
  const hidden = events.length - shown.length;
11319
+ const heat = this.heatByDay.get(day);
11294
11320
  return b$1`<div
11295
11321
  role="gridcell"
11296
11322
  class="day"
11297
11323
  part=${[
11298
11324
  "day",
11299
11325
  isToday ? "today" : "",
11300
- selected ? "selected" : ""
11326
+ selected ? "selected" : "",
11327
+ heat ? "heat" : ""
11301
11328
  ].filter(Boolean).join(" ")}
11302
11329
  data-day=${day}
11303
11330
  tabindex=${!outside && day === this.tabDay ? 0 : -1}
@@ -11312,6 +11339,7 @@ var Calendar = class extends CalendarBase {
11312
11339
  ?data-last=${last}
11313
11340
  ?data-outside=${outside}
11314
11341
  ?data-busy=${events.length > 0}
11342
+ data-heat=${heat ?? A}
11315
11343
  ?data-open=${unfolded}
11316
11344
  >
11317
11345
  <span class="date-line" aria-hidden="true">
@@ -11335,6 +11363,7 @@ var Calendar = class extends CalendarBase {
11335
11363
  const first = this.firstDay;
11336
11364
  const weeks = monthWeeks(month, first, this.fixed);
11337
11365
  this.byDay = eventsByDay(this.events ?? [], weeks[0][0], weeks.at(-1)[6]);
11366
+ this.heatByDay = this.heat ? heatLevels(new Map([...this.byDay].filter(([day]) => sameMonth(day, month))), this.heatMax) : /* @__PURE__ */ new Map();
11338
11367
  const short = this.compact ? this.squaresPerDay < 2 ? weekdayNames(first, "narrow") : weekdayNames(first, "short").map((name) => /^\p{Script=Latin}/u.test(name) ? name.replace(/\.$/, "").slice(0, 2) : name) : weekdayNames(first, "short");
11339
11368
  const long = weekdayNames(first, "long");
11340
11369
  return b$1`<div class="calendar" part="calendar" @focusout=${this.onFocusOut} @pointerover=${this.onPointerOver} @pointerleave=${() => this.hoverDay = void 0}>
@@ -11544,7 +11573,7 @@ var Calendar = class extends CalendarBase {
11544
11573
  const name = this.label ? this.pickerWords(this.label, this.label) : this.pickerWords(void 0, "Date");
11545
11574
  const days = start ? end ? `${start.day}/${end.day}` : start.day : "";
11546
11575
  return b$1`<button
11547
- class="ds-select trigger"
11576
+ class="ds-input trigger"
11548
11577
  part="trigger"
11549
11578
  type="button"
11550
11579
  aria-haspopup="dialog"
@@ -11555,9 +11584,8 @@ var Calendar = class extends CalendarBase {
11555
11584
  @click=${this.toggle}
11556
11585
  @keydown=${this.onTriggerKey}
11557
11586
  >
11558
- <ds-icon class="icon" type="calendar" aria-hidden="true"></ds-icon>
11559
11587
  <span class="text">${text}</span>
11560
- <ds-icon class="arrow" type="down" aria-hidden="true"></ds-icon>
11588
+ <ds-icon class="arrow" type="chevron-down" size="large" aria-hidden="true"></ds-icon>
11561
11589
  </button>
11562
11590
  <div
11563
11591
  class="popover"
@@ -11637,6 +11665,14 @@ _Calendar.properties = {
11637
11665
  attribute: "no-today",
11638
11666
  reflect: true
11639
11667
  },
11668
+ heat: {
11669
+ type: Boolean,
11670
+ reflect: true
11671
+ },
11672
+ heatMax: {
11673
+ type: Number,
11674
+ attribute: "heat-max"
11675
+ },
11640
11676
  picker: {
11641
11677
  type: Boolean,
11642
11678
  reflect: true
@@ -12013,11 +12049,16 @@ function bentoReach(places) {
12013
12049
  };
12014
12050
  });
12015
12051
  }
12016
- /** Places one squares bento's tiles: their squares and their reach, as custom properties. */
12052
+ /** A tile's place in the bento's layout: `data-place-<layout>` where the bento names one and the tile has it, else `data-place`. */
12053
+ function tilePlace(tile, layout = "") {
12054
+ return bentoPlace((layout ? tile.getAttribute(`data-place-${layout}`) : null) ?? tile.dataset.place);
12055
+ }
12056
+ /** Places one squares bento's tiles: their squares and their reach, as custom properties. The bento's `data-layout` (or `layout`) picks each tile's place for that layout. */
12017
12057
  function placeBento(bento) {
12058
+ const layout = bento.dataset.layout ?? bento.getAttribute("layout") ?? "";
12018
12059
  const placed = [...bento.children].filter((child) => child instanceof HTMLElement && !child.hidden).map((tile) => ({
12019
12060
  tile,
12020
- place: bentoPlace(tile.dataset.place)
12061
+ place: tilePlace(tile, layout)
12021
12062
  })).filter((entry) => !!entry.place);
12022
12063
  const reach = bentoReach(placed.map((entry) => entry.place));
12023
12064
  placed.forEach(({ tile, place: [x, y, w, h] }, index) => {
@@ -12036,7 +12077,7 @@ function placeBento(bento) {
12036
12077
  }
12037
12078
  //#endregion
12038
12079
  //#region DS1/3-unit/styles/ds-bento.css?inline
12039
- var ds_bento_default = "/* ds-bento.css */\n/* The element's bento: the same as 1-root/bento.css's .ds-bento, on the host and its slotted tiles. */\n\n:host {\n --ds-bento-gap: calc(var(--ds-unit) / 2);\n box-sizing: border-box;\n display: grid;\n grid-template-columns: repeat(var(--ds-bento-columns, 3), minmax(0, 1fr));\n grid-auto-rows: minmax(var(--ds-bento-row, calc(10 * var(--ds-unit))), auto);\n grid-auto-flow: row dense;\n gap: var(--ds-bento-gap);\n}\n:host([hidden]) { display: none !important; }\n\n::slotted(*) {\n --ds-card-width: auto;\n --ds-card-height: auto;\n box-sizing: border-box;\n min-width: 0;\n min-height: 0;\n grid-column: span var(--ds-bento-span, 1);\n grid-row: span var(--ds-bento-rows, 1);\n}\n::slotted([data-span=\"2\"]) { --ds-bento-span: 2; }\n::slotted([data-span=\"3\"]) { --ds-bento-span: 3; }\n::slotted([data-span=\"4\"]) { --ds-bento-span: 4; }\n::slotted([data-span=\"5\"]) { --ds-bento-span: 5; }\n::slotted([data-span=\"6\"]) { --ds-bento-span: 6; }\n::slotted([data-rows=\"2\"]) { --ds-bento-rows: 2; }\n::slotted([data-rows=\"3\"]) { --ds-bento-rows: 3; }\n::slotted([data-rows=\"4\"]) { --ds-bento-rows: 4; }\n::slotted([data-rows=\"5\"]) { --ds-bento-rows: 5; }\n::slotted([data-rows=\"6\"]) { --ds-bento-rows: 6; }\n\n@media (max-width: 600px) {\n :host(:not([squares])) { grid-template-columns: minmax(0, 1fr); }\n :host(:not([squares])) ::slotted(*) { grid-column: auto; }\n}\n\n:host([squares]) {\n --ds-bento-reach: calc(var(--ds-unit) / 4);\n /* Exactly its squares wide: each column one square. */\n width: calc(var(--ds-bento-columns, 48) * var(--ds-unit));\n max-width: none;\n grid-template-columns: repeat(var(--ds-bento-columns, 48), var(--ds-unit));\n grid-auto-rows: var(--ds-unit);\n grid-auto-flow: row;\n gap: 0;\n}\n:host([squares]) ::slotted(*) {\n --ds-bento-inset-top: calc(var(--ds-bento-reach) * var(--ds-bento-top, 0));\n --ds-bento-inset-end: calc(var(--ds-bento-reach) * var(--ds-bento-end, 0));\n --ds-bento-inset-bottom: calc(var(--ds-bento-reach) * var(--ds-bento-bottom, 0));\n --ds-bento-inset-start: calc(var(--ds-bento-reach) * var(--ds-bento-start, 0));\n grid-column: calc(var(--ds-bento-x, 0) + 1) / span var(--ds-bento-w, 4);\n grid-row: calc(var(--ds-bento-y, 0) + 1) / span var(--ds-bento-h, 4);\n margin: calc(-1 * var(--ds-bento-inset-top)) calc(-1 * var(--ds-bento-inset-end)) calc(-1 * var(--ds-bento-inset-bottom)) calc(-1 * var(--ds-bento-inset-start));\n}\n/* A card grows its own padding by the reach (card.css); any other tile is padded here, a square inside. */\n:host([squares]) ::slotted(:not(.ds-card, ds-card)) {\n padding:\n calc(var(--ds-unit) + var(--ds-bento-inset-top))\n calc(var(--ds-unit) + var(--ds-bento-inset-end))\n calc(var(--ds-unit) + var(--ds-bento-inset-bottom))\n calc(var(--ds-unit) + var(--ds-bento-inset-start));\n}\n";
12080
+ var ds_bento_default = "/* ds-bento.css */\n/* The element's bento: the same as 1-root/bento.css's .ds-bento, on the host and its slotted tiles. */\n\n:host {\n --ds-bento-unit: var(--ds-unit);\n --ds-bento-gap: calc(var(--ds-bento-unit) / 2);\n box-sizing: border-box;\n display: grid;\n grid-template-columns: repeat(var(--ds-bento-columns, 3), minmax(0, 1fr));\n grid-auto-rows: minmax(var(--ds-bento-row, calc(10 * var(--ds-bento-unit))), auto);\n grid-auto-flow: row dense;\n gap: var(--ds-bento-gap);\n}\n:host([hidden]) { display: none !important; }\n\n::slotted(*) {\n --ds-card-width: auto;\n --ds-card-height: auto;\n box-sizing: border-box;\n min-width: 0;\n min-height: 0;\n grid-column: span var(--ds-bento-span, 1);\n grid-row: span var(--ds-bento-rows, 1);\n}\n::slotted([data-span=\"2\"]) { --ds-bento-span: 2; }\n::slotted([data-span=\"3\"]) { --ds-bento-span: 3; }\n::slotted([data-span=\"4\"]) { --ds-bento-span: 4; }\n::slotted([data-span=\"5\"]) { --ds-bento-span: 5; }\n::slotted([data-span=\"6\"]) { --ds-bento-span: 6; }\n::slotted([data-rows=\"2\"]) { --ds-bento-rows: 2; }\n::slotted([data-rows=\"3\"]) { --ds-bento-rows: 3; }\n::slotted([data-rows=\"4\"]) { --ds-bento-rows: 4; }\n::slotted([data-rows=\"5\"]) { --ds-bento-rows: 5; }\n::slotted([data-rows=\"6\"]) { --ds-bento-rows: 6; }\n\n@media (max-width: 600px) {\n :host(:not([squares])) { grid-template-columns: minmax(0, 1fr); }\n :host(:not([squares])) ::slotted(*) { grid-column: auto; }\n}\n\n:host([squares]) {\n --ds-bento-reach: calc(var(--ds-bento-unit) / 4);\n /* Exactly its squares wide: each column one square. */\n width: calc(var(--ds-bento-columns, 48) * var(--ds-bento-unit));\n max-width: none;\n grid-template-columns: repeat(var(--ds-bento-columns, 48), var(--ds-bento-unit));\n grid-auto-rows: var(--ds-bento-unit);\n grid-auto-flow: row;\n gap: 0;\n}\n/* Fit: the columns share a measure narrower (or wider) than the squares, the rows still one square. */\n:host([squares][fit]) {\n width: auto;\n grid-template-columns: repeat(var(--ds-bento-columns, 48), minmax(0, 1fr));\n}\n:host([squares]) ::slotted(*) {\n --ds-bento-inset-top: calc(var(--ds-bento-reach) * var(--ds-bento-top, 0));\n --ds-bento-inset-end: calc(var(--ds-bento-reach) * var(--ds-bento-end, 0));\n --ds-bento-inset-bottom: calc(var(--ds-bento-reach) * var(--ds-bento-bottom, 0));\n --ds-bento-inset-start: calc(var(--ds-bento-reach) * var(--ds-bento-start, 0));\n grid-column: calc(var(--ds-bento-x, 0) + 1) / span var(--ds-bento-w, 4);\n grid-row: calc(var(--ds-bento-y, 0) + 1) / span var(--ds-bento-h, 4);\n margin: calc(-1 * var(--ds-bento-inset-top)) calc(-1 * var(--ds-bento-inset-end)) calc(-1 * var(--ds-bento-inset-bottom)) calc(-1 * var(--ds-bento-inset-start));\n}\n/* A card grows its own padding by the reach (card.css); any other tile is padded here, a square inside. */\n:host([squares]) ::slotted(:not(.ds-card, ds-card)) {\n padding:\n calc(var(--ds-bento-padding, var(--ds-bento-unit)) + var(--ds-bento-inset-top))\n calc(var(--ds-bento-padding, var(--ds-bento-unit)) + var(--ds-bento-inset-end))\n calc(var(--ds-bento-padding, var(--ds-bento-unit)) + var(--ds-bento-inset-bottom))\n calc(var(--ds-bento-padding, var(--ds-bento-unit)) + var(--ds-bento-inset-start));\n}\n";
12040
12081
  //#endregion
12041
12082
  //#region DS1/3-unit/ds-bento.ts
12042
12083
  var _Bento;
@@ -12044,6 +12085,7 @@ var Bento = class extends i$2 {
12044
12085
  constructor() {
12045
12086
  super();
12046
12087
  this.squares = false;
12088
+ this.fit = false;
12047
12089
  }
12048
12090
  connectedCallback() {
12049
12091
  super.connectedCallback();
@@ -12052,7 +12094,8 @@ var Bento = class extends i$2 {
12052
12094
  childList: true,
12053
12095
  subtree: true,
12054
12096
  attributes: true,
12055
- attributeFilter: ["data-place", "hidden"]
12097
+ attributeFilter: ["data-place", "hidden"],
12098
+ attributeOldValue: false
12056
12099
  });
12057
12100
  }
12058
12101
  disconnectedCallback() {
@@ -12080,6 +12123,14 @@ _Bento.properties = {
12080
12123
  squares: {
12081
12124
  type: Boolean,
12082
12125
  reflect: true
12126
+ },
12127
+ fit: {
12128
+ type: Boolean,
12129
+ reflect: true
12130
+ },
12131
+ layout: {
12132
+ type: String,
12133
+ reflect: true
12083
12134
  }
12084
12135
  };
12085
12136
  _Bento.styles = [r$3(component_metrics_default), r$3(ds_bento_default)];