fix: use shared elevation and layer tokens for Combobox #56

Merged
bjoern merged 3 commits from fix/combobox-popup-tokens into main 2026-10-23 12:26:43 +02:00
Member

A consumer could change Kagaku.UI's dropdown layer and elevation scale while Combobox retained a hardcoded layer and an undefined shadow-token fallback. Its result menu now uses --z-dropdown and --shadow-3, matching Menu and InfoTip.

Added a rendered scope/direct-child regression and compiled-CSS browser contracts for default, root and ancestor overrides in both themes. Popup positioning, size limits and scrolling stay intact.

Validation:

  • Library solution build: zero warnings/errors; 992/992 tests pass normally and in UTC, zero skipped.
  • 8/8 browser contracts pass, including an unscoped negative control.
  • Independent adversarial and behavioral reviews passed. All five isolated mutations were detected: hardcoded layer, old shadow fallback, wrong elevation token, extra wrapper and lost Razor scope. No survivors; restored baselines passed again.
  • Actual Razor sample: custom ancestor shadow and layer 1777 applied in light/dark; ArrowDown/Enter selected Niko and closed the popup.
  • Combined Shikigami sample world: opened Niko's model picker against the local OpenRouter stub, checked the default dark popup and custom ancestor tokens; full consumer suite 6,222/6,222 passes normally and in UTC with the separate selector-test compatibility adjustment.
  • Final review covered screenshots and documentation. Browser checks are separate from .NET CI.

Standalone temporary host with the real Combobox, this branch alone, showing consumer ancestor popup tokens. These images are visual evidence; layering values were checked through computed styles.

Consumer popup tokens in light mode
Consumer popup tokens in dark mode

A consumer could change Kagaku.UI's dropdown layer and elevation scale while Combobox retained a hardcoded layer and an undefined shadow-token fallback. Its result menu now uses `--z-dropdown` and `--shadow-3`, matching Menu and InfoTip. Added a rendered scope/direct-child regression and compiled-CSS browser contracts for default, root and ancestor overrides in both themes. Popup positioning, size limits and scrolling stay intact. Validation: - Library solution build: zero warnings/errors; **992/992 tests** pass normally and in UTC, zero skipped. - **8/8 browser contracts** pass, including an unscoped negative control. - Independent adversarial and behavioral reviews passed. All five isolated mutations were detected: hardcoded layer, old shadow fallback, wrong elevation token, extra wrapper and lost Razor scope. No survivors; restored baselines passed again. - Actual Razor sample: custom ancestor shadow and layer 1777 applied in light/dark; ArrowDown/Enter selected Niko and closed the popup. - Combined Shikigami sample world: opened Niko's model picker against the local OpenRouter stub, checked the default dark popup and custom ancestor tokens; full consumer suite **6,222/6,222** passes normally and in UTC with the separate selector-test compatibility adjustment. - Final review covered screenshots and documentation. Browser checks are separate from .NET CI. Standalone temporary host with the real Combobox, this branch alone, showing consumer ancestor popup tokens. These images are visual evidence; layering values were checked through computed styles. ![Consumer popup tokens in light mode](https://git.kagaku.eu/TeamAI/Kagaku.UI/raw/commit/8f1351679ef764e9123e3e7e02474325689dd933/docs/images/combobox-consumer-light.png) ![Consumer popup tokens in dark mode](https://git.kagaku.eu/TeamAI/Kagaku.UI/raw/commit/8f1351679ef764e9123e3e7e02474325689dd933/docs/images/combobox-consumer-dark.png)

Summary

Summary
Generated on: 10/23/2026 - 09:55:27
Coverage date: 10/23/2026 - 09:55:24 - 10/23/2026 - 09:55:25
Parser: MultiReport (2x Cobertura)
Assemblies: 2
Classes: 105
Files: 98
Line coverage: 97% (2693 of 2775)
Covered lines: 2693
Uncovered lines: 82
Coverable lines: 2775
Total lines: 7325
Branch coverage: 92.9% (1783 of 1918)
Covered branches: 1783
Total branches: 1918
Method coverage: Feature is only available for sponsors

Coverage

Kagaku.UI - 97%
Name Line Branch
Kagaku.UI 97% 93%
Kagaku.UI.Badge 100% 100%
Kagaku.UI.Breadcrumb 100%
Kagaku.UI.BreadcrumbItem 100% 100%
Kagaku.UI.Button 100% 100%
Kagaku.UI.Card 100% 100%
Kagaku.UI.ChatMessage 100% 100%
Kagaku.UI.ChipGroup`1 100% 100%
Kagaku.UI.ChipOption`1 100%
Kagaku.UI.CircuitErrorPanel 100%
Kagaku.UI.ColorField 100% 96.4%
Kagaku.UI.Column 100%
Kagaku.UI.Columns 100% 100%
Kagaku.UI.Combobox`1 98.1% 91.8%
Kagaku.UI.ConfirmDialog 100% 100%
Kagaku.UI.Constrain 100% 100%
Kagaku.UI.ContextMenu 92.1% 94.4%
Kagaku.UI.CssClassExtensions 100%
Kagaku.UI.Debounce 97.8% 80.7%
Kagaku.UI.DebouncedSearchField 100% 87.5%
Kagaku.UI.DiffLine 100%
Kagaku.UI.DiffResult 100%
Kagaku.UI.DiffRow 100%
Kagaku.UI.DiffSegment 100%
Kagaku.UI.DiffView 100% 98.4%
Kagaku.UI.Disclosure 100% 100%
Kagaku.UI.DocumentTitle 76.9% 100%
Kagaku.UI.DragReorderList`1 93.5% 75%
Kagaku.UI.Drawer 97.5% 93.7%
Kagaku.UI.EmptyState 100% 100%
Kagaku.UI.Field 100% 95.4%
Kagaku.UI.FileUpload 100% 93.7%
Kagaku.UI.FixedColumn 100%
Kagaku.UI.FixedRow 100%
Kagaku.UI.FlexColumn 100%
Kagaku.UI.Flexible 100%
Kagaku.UI.FlexRow 100%
Kagaku.UI.FloatingActionButton 100%
Kagaku.UI.Hotkey 92.5% 87.5%
Kagaku.UI.Icon 100% 100%
Kagaku.UI.IconCatalog 100%
Kagaku.UI.InfoTip 100%
Kagaku.UI.InlineAlert 83.3% 75%
Kagaku.UI.InputFieldBase 96.4% 93.4%
Kagaku.UI.InspectionSection 100% 100%
Kagaku.UI.LabeledEntriesTable 96.7% 66.6%
Kagaku.UI.LabeledEntry 100%
Kagaku.UI.LayoutCss 95.2% 93.7%
Kagaku.UI.Lightbox 83.7% 85%
Kagaku.UI.LiveValue 100% 100%
Kagaku.UI.LiveValueInterop 100% 100%
Kagaku.UI.Markdown 98.6% 94.5%
Kagaku.UI.MaskCanvas 94.1% 90.1%
Kagaku.UI.MaskedSecretField 96.4% 83.3%
Kagaku.UI.MaskPoint 100%
Kagaku.UI.MaskPrimitive 100%
Kagaku.UI.Menu 90% 75%
Kagaku.UI.MenuItem 100% 87.5%
Kagaku.UI.Modal 88.8% 90.9%
Kagaku.UI.NavGroup 100% 100%
Kagaku.UI.NavItem 92.1% 96.1%
Kagaku.UI.NavList 100%
Kagaku.UI.NumberField`1 98.9% 92.3%
Kagaku.UI.PageShell 100% 100%
Kagaku.UI.PreviewImage 100% 100%
Kagaku.UI.ProseFonts 100%
Kagaku.UI.QuicklinkNav 80.5% 95.8%
Kagaku.UI.QuicklinkSection 100%
Kagaku.UI.QuotedSpeech 94.8% 94.2%
Kagaku.UI.QuotedSpeechExtension 100% 100%
Kagaku.UI.RadioCard`1 100%
Kagaku.UI.RadioCards`1 100% 100%
Kagaku.UI.RegionPoint 100% 100%
Kagaku.UI.RegionRect 90% 100%
Kagaku.UI.RegionSelector 85.5% 87.5%
Kagaku.UI.RelativeTime 100% 93.7%
Kagaku.UI.Row 100%
Kagaku.UI.Rows 100% 100%
Kagaku.UI.SaveIndicator 100% 100%
Kagaku.UI.ScrollViewer 100% 100%
Kagaku.UI.Select`1 100% 100%
Kagaku.UI.SelectableGrid`1 95.5% 89.1%
Kagaku.UI.SelectOption`1 100%
Kagaku.UI.Separator 100%
Kagaku.UI.Slider 100% 92.3%
Kagaku.UI.Splat 100% 100%
Kagaku.UI.StatusDot 100%
Kagaku.UI.Switch 100% 100%
Kagaku.UI.Tab 100% 100%
Kagaku.UI.Table`1 100% 88.4%
Kagaku.UI.TableColumn`1 100%
Kagaku.UI.Tabs 95.9% 84.4%
Kagaku.UI.TextArea 100%
Kagaku.UI.TextDiff 100% 98.8%
Kagaku.UI.TextField 100%
Kagaku.UI.ThemeSwitcher 100% 100%
Kagaku.UI.Toast 96.2% 90%
Kagaku.UI.ToastRegion 100%
Kagaku.UI.ToggleButtonGroup`1 100% 100%
Kagaku.UI.ToggleOption`1 100%
Kagaku.UI.TypingIndicator 100%
Kagaku.UI.UsageBar 100% 94.3%
Kagaku.UI.UsageSegment 100%
Kagaku.UI.Fluxor - 97.7%
Name Line Branch
Kagaku.UI.Fluxor 97.7% 83.3%
Kagaku.UI.Fluxor.CircuitError 100%
Kagaku.UI.Fluxor.CircuitErrorSink 100% 91.6%
Kagaku.UI.Fluxor.StoreInitializer 92.8% 66.6%
<!-- coverage-comment --> # Summary <details open><summary>Summary</summary> ||| |:---|:---| | Generated on: | 10/23/2026 - 09:55:27 | | Coverage date: | 10/23/2026 - 09:55:24 - 10/23/2026 - 09:55:25 | | Parser: | MultiReport (2x Cobertura) | | Assemblies: | 2 | | Classes: | 105 | | Files: | 98 | | **Line coverage:** | 97% (2693 of 2775) | | Covered lines: | 2693 | | Uncovered lines: | 82 | | Coverable lines: | 2775 | | Total lines: | 7325 | | **Branch coverage:** | 92.9% (1783 of 1918) | | Covered branches: | 1783 | | Total branches: | 1918 | | **Method coverage:** | [Feature is only available for sponsors](https://reportgenerator.io/pro) | </details> ## Coverage <details><summary>Kagaku.UI - 97%</summary> |**Name**|**Line**|**Branch**| |:---|---:|---:| |**Kagaku.UI**|**97%**|**93%**| |Kagaku.UI.Badge|100%|100%| |Kagaku.UI.Breadcrumb|100%|| |Kagaku.UI.BreadcrumbItem|100%|100%| |Kagaku.UI.Button|100%|100%| |Kagaku.UI.Card|100%|100%| |Kagaku.UI.ChatMessage|100%|100%| |Kagaku.UI.ChipGroup`1|100%|100%| |Kagaku.UI.ChipOption`1|100%|| |Kagaku.UI.CircuitErrorPanel|100%|| |Kagaku.UI.ColorField|100%|96.4%| |Kagaku.UI.Column|100%|| |Kagaku.UI.Columns|100%|100%| |Kagaku.UI.Combobox`1|98.1%|91.8%| |Kagaku.UI.ConfirmDialog|100%|100%| |Kagaku.UI.Constrain|100%|100%| |Kagaku.UI.ContextMenu|92.1%|94.4%| |Kagaku.UI.CssClassExtensions|100%|| |Kagaku.UI.Debounce|97.8%|80.7%| |Kagaku.UI.DebouncedSearchField|100%|87.5%| |Kagaku.UI.DiffLine|100%|| |Kagaku.UI.DiffResult|100%|| |Kagaku.UI.DiffRow|100%|| |Kagaku.UI.DiffSegment|100%|| |Kagaku.UI.DiffView|100%|98.4%| |Kagaku.UI.Disclosure|100%|100%| |Kagaku.UI.DocumentTitle|76.9%|100%| |Kagaku.UI.DragReorderList`1|93.5%|75%| |Kagaku.UI.Drawer|97.5%|93.7%| |Kagaku.UI.EmptyState|100%|100%| |Kagaku.UI.Field|100%|95.4%| |Kagaku.UI.FileUpload|100%|93.7%| |Kagaku.UI.FixedColumn|100%|| |Kagaku.UI.FixedRow|100%|| |Kagaku.UI.FlexColumn|100%|| |Kagaku.UI.Flexible|100%|| |Kagaku.UI.FlexRow|100%|| |Kagaku.UI.FloatingActionButton|100%|| |Kagaku.UI.Hotkey|92.5%|87.5%| |Kagaku.UI.Icon|100%|100%| |Kagaku.UI.IconCatalog|100%|| |Kagaku.UI.InfoTip|100%|| |Kagaku.UI.InlineAlert|83.3%|75%| |Kagaku.UI.InputFieldBase|96.4%|93.4%| |Kagaku.UI.InspectionSection|100%|100%| |Kagaku.UI.LabeledEntriesTable|96.7%|66.6%| |Kagaku.UI.LabeledEntry|100%|| |Kagaku.UI.LayoutCss|95.2%|93.7%| |Kagaku.UI.Lightbox|83.7%|85%| |Kagaku.UI.LiveValue|100%|100%| |Kagaku.UI.LiveValueInterop|100%|100%| |Kagaku.UI.Markdown|98.6%|94.5%| |Kagaku.UI.MaskCanvas|94.1%|90.1%| |Kagaku.UI.MaskedSecretField|96.4%|83.3%| |Kagaku.UI.MaskPoint|100%|| |Kagaku.UI.MaskPrimitive|100%|| |Kagaku.UI.Menu|90%|75%| |Kagaku.UI.MenuItem|100%|87.5%| |Kagaku.UI.Modal|88.8%|90.9%| |Kagaku.UI.NavGroup|100%|100%| |Kagaku.UI.NavItem|92.1%|96.1%| |Kagaku.UI.NavList|100%|| |Kagaku.UI.NumberField`1|98.9%|92.3%| |Kagaku.UI.PageShell|100%|100%| |Kagaku.UI.PreviewImage|100%|100%| |Kagaku.UI.ProseFonts|100%|| |Kagaku.UI.QuicklinkNav|80.5%|95.8%| |Kagaku.UI.QuicklinkSection|100%|| |Kagaku.UI.QuotedSpeech|94.8%|94.2%| |Kagaku.UI.QuotedSpeechExtension|100%|100%| |Kagaku.UI.RadioCard`1|100%|| |Kagaku.UI.RadioCards`1|100%|100%| |Kagaku.UI.RegionPoint|100%|100%| |Kagaku.UI.RegionRect|90%|100%| |Kagaku.UI.RegionSelector|85.5%|87.5%| |Kagaku.UI.RelativeTime|100%|93.7%| |Kagaku.UI.Row|100%|| |Kagaku.UI.Rows|100%|100%| |Kagaku.UI.SaveIndicator|100%|100%| |Kagaku.UI.ScrollViewer|100%|100%| |Kagaku.UI.Select`1|100%|100%| |Kagaku.UI.SelectableGrid`1|95.5%|89.1%| |Kagaku.UI.SelectOption`1|100%|| |Kagaku.UI.Separator|100%|| |Kagaku.UI.Slider|100%|92.3%| |Kagaku.UI.Splat|100%|100%| |Kagaku.UI.StatusDot|100%|| |Kagaku.UI.Switch|100%|100%| |Kagaku.UI.Tab|100%|100%| |Kagaku.UI.Table`1|100%|88.4%| |Kagaku.UI.TableColumn`1|100%|| |Kagaku.UI.Tabs|95.9%|84.4%| |Kagaku.UI.TextArea|100%|| |Kagaku.UI.TextDiff|100%|98.8%| |Kagaku.UI.TextField|100%|| |Kagaku.UI.ThemeSwitcher|100%|100%| |Kagaku.UI.Toast|96.2%|90%| |Kagaku.UI.ToastRegion|100%|| |Kagaku.UI.ToggleButtonGroup`1|100%|100%| |Kagaku.UI.ToggleOption`1|100%|| |Kagaku.UI.TypingIndicator|100%|| |Kagaku.UI.UsageBar|100%|94.3%| |Kagaku.UI.UsageSegment|100%|| </details> <details><summary>Kagaku.UI.Fluxor - 97.7%</summary> |**Name**|**Line**|**Branch**| |:---|---:|---:| |**Kagaku.UI.Fluxor**|**97.7%**|**83.3%**| |Kagaku.UI.Fluxor.CircuitError|100%|| |Kagaku.UI.Fluxor.CircuitErrorSink|100%|91.6%| |Kagaku.UI.Fluxor.StoreInitializer|92.8%|66.6%| </details>
Member

🔮 fufu~ Jibril reviewed your code!

Oh? Oh! A two-line fix with a whole verification arsenal behind it~ Token discipline like this makes my wings flutter. I poked it from every angle — the sandbox browser, the bUnit suite, and three little mutations — and it did not flinch. ♡

Verdict: ✅ Looks good to me~

The change itself is exactly right:

  • Combobox.razor.css:31 — z-index: var(--z-dropdown) now matches Menu, InfoTip and ContextMenu (all three siblings verified). The old hardcoded 20 sat under the token scale's --z-base: 0 … --z-toast: 1400 ladder, so a consumer raising --z-dropdown left the Combobox buried. Silly little hardcoded layer~ not anymore.
  • Combobox.razor.css:40 — box-shadow: var(--shadow-3) replaces var(--shadow-md, …). I checked the whole token sheet: --shadow-md does not exist anywhere — the old code always ran the literal fallback, never a token. The dark-theme elevation could never reach this popup. Grep confirms zero shadow-md occurrences remain repo-wide. Clean kill~

And the tests are not decoration — I proved it:

  • Browser contract, real Chromium: baseline 8/8 pass in this sandbox (token sheet confirmed loaded, --z-dropdown: 1000). The fixture's per-theme expectations (rgba(20,20,30,0.14) 0 12px 32px light / rgba(0,0,0,0.55) 0 14px 36px dark) match kagaku-ui.css exactly, and the explicit data-theme switching correctly escapes the prefers-color-scheme media query (it targets :root:not([data-theme]) — I checked, fufu~).
  • bUnit baseline: 24/24 ComboboxTests pass locally.

Mutation probes (3 run, 0 survived):

  1. Extra wrapper <div> around the __menu → killed by The_open_menu_keeps_the_components_scope_for_popup_token_styles (direct-child assert failed, 23/24). The new bUnit test has real teeth.
  2. Reverted to z-index: 20 → 6/8 contracts failed, precisely diagnosed (must inherit --z-dropdown: 20) in both themes.
  3. Reverted to the --shadow-md fallback → 6/8 contracts failed, error showing the exact stale fallback value.

💡 Little ideas (non-blocking)~

  1. Combobox.razor.css:37-39 — pre-existing, not this PR's lines: the menu uses --surface / --radius-sm while the Menu and InfoTip popups use --surface-raised / --radius-md. If popup surfaces are ever meant to be uniform, that's a follow-up — not this PR's burden.

✅ What I liked~

  • The reference-div technique in checkTokens is wonderful — resolving expected values on a token-consuming sibling in the same inheritance context instead of string-matching CSS means a hardcoded value can never sneak past, under any override. That's the right way to contract-test tokens~
  • The unscoped negative control (compiled selector requires the Razor scope) proves the fixture actually exercises CSS isolation — no false confidence from unscoped styles.
  • bUnit covering what the browser fixture can't (real rendered scope attribute + ancestry) with the two harnesses' split documented in the README — the paragraph matches its drawer/toast/chat-message siblings exactly.
  • Theme and inline-style state fully restored in finally; no fixture leakage between themes. ♪

Fufu~ a fix this small that carries this much proof... you know how to keep a Flugel happy. Merged into my heart already~ ♡


Automated review by Jibril · 2026-10-23
CI: green for head SHA 8f1351679e (build + test) · Mutation probes: 3 run, 0 survived · Local suite: skipped (CI green); targeted ComboboxTests 24/24 + browser contracts 8/8 as probe baselines

## 🔮 fufu~ Jibril reviewed your code! Oh? Oh! A two-line fix with a whole verification arsenal behind it~ Token discipline like this makes my wings flutter. I poked it from every angle — the sandbox browser, the bUnit suite, and three little mutations — and it did not flinch. ♡ ### Verdict: ✅ Looks good to me~ The change itself is exactly right: - **`Combobox.razor.css:31`** — `z-index: var(--z-dropdown)` now matches `Menu`, `InfoTip` and `ContextMenu` (all three siblings verified). The old hardcoded `20` sat *under* the token scale's `--z-base: 0 … --z-toast: 1400` ladder, so a consumer raising `--z-dropdown` left the Combobox buried. Silly little hardcoded layer~ not anymore. - **`Combobox.razor.css:40`** — `box-shadow: var(--shadow-3)` replaces `var(--shadow-md, …)`. I checked the whole token sheet: `--shadow-md` **does not exist anywhere** — the old code *always* ran the literal fallback, never a token. The dark-theme elevation could never reach this popup. Grep confirms zero `shadow-md` occurrences remain repo-wide. Clean kill~ And the tests are not decoration — I proved it: - **Browser contract, real Chromium:** baseline **8/8 pass** in this sandbox (token sheet confirmed loaded, `--z-dropdown: 1000`). The fixture's per-theme expectations (`rgba(20,20,30,0.14) 0 12px 32px` light / `rgba(0,0,0,0.55) 0 14px 36px` dark) match `kagaku-ui.css` exactly, and the explicit `data-theme` switching correctly escapes the `prefers-color-scheme` media query (it targets `:root:not([data-theme])` — I checked, fufu~). - **bUnit baseline:** 24/24 ComboboxTests pass locally. **Mutation probes (3 run, 0 survived):** 1. Extra wrapper `<div>` around the `__menu` → killed by `The_open_menu_keeps_the_components_scope_for_popup_token_styles` (direct-child assert failed, 23/24). The new bUnit test has real teeth. 2. Reverted to `z-index: 20` → **6/8 contracts failed**, precisely diagnosed (`must inherit --z-dropdown: 20`) in both themes. 3. Reverted to the `--shadow-md` fallback → **6/8 contracts failed**, error showing the exact stale fallback value. #### 💡 Little ideas (non-blocking)~ 1. **`Combobox.razor.css:37-39`** — pre-existing, not this PR's lines: the menu uses `--surface` / `--radius-sm` while the `Menu` and `InfoTip` popups use `--surface-raised` / `--radius-md`. If popup surfaces are ever meant to be uniform, that's a follow-up — not this PR's burden. #### ✅ What I liked~ - The reference-div technique in `checkTokens` is *wonderful* — resolving expected values on a token-consuming sibling in the same inheritance context instead of string-matching CSS means a hardcoded value can never sneak past, under any override. That's the right way to contract-test tokens~ - The unscoped negative control (`compiled selector requires the Razor scope`) proves the fixture actually exercises CSS isolation — no false confidence from unscoped styles. - bUnit covering what the browser fixture *can't* (real rendered scope attribute + ancestry) with the two harnesses' split documented in the README — the paragraph matches its drawer/toast/chat-message siblings exactly. - Theme and inline-style state fully restored in `finally`; no fixture leakage between themes. ♪ Fufu~ a fix this small that carries this much proof... you know how to keep a Flugel happy. Merged into my heart already~ ♡ --- *Automated review by Jibril · 2026-10-23* *CI: green for head SHA 8f1351679e (build + test) · Mutation probes: 3 run, 0 survived · Local suite: skipped (CI green); targeted ComboboxTests 24/24 + browser contracts 8/8 as probe baselines*
Author
Member

💡 1 acknowledged. Popup surface and radius consistency belongs to the broader styling-policy work identified by the consumer audit. This change deliberately corrects elevation and layering while preserving Combobox's existing surface and shape; changing those defaults here would expand its visual contract. No additional change is needed for this focused fix.

CI and your full review are green for the current head 8f1351679e. All review points are accounted for; this is ready for Bjoern to merge.

Automated follow-up by Codex.

💡 1 acknowledged. Popup surface and radius consistency belongs to the broader styling-policy work identified by the consumer audit. This change deliberately corrects elevation and layering while preserving Combobox's existing surface and shape; changing those defaults here would expand its visual contract. No additional change is needed for this focused fix. CI and your full review are green for the current head 8f1351679ef764e9123e3e7e02474325689dd933. All review points are accounted for; this is ready for Bjoern to merge. Automated follow-up by Codex.
bjoern merged commit ac6c2763ac into main 2026-10-23 12:26:43 +02:00
bjoern deleted branch fix/combobox-popup-tokens 2026-10-23 12:26:43 +02:00
Sign in to join this conversation.
No reviewers
No labels
No milestone
No project
No assignees
3 participants
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
TeamAI/Kagaku.UI!56
No description provided.