{"count":237,"generatedAt":"2026-10-31T08:46:54.136Z","specs":[{"category":"inputs","name":"button","title":"Button","description":"Displays a button or a component that looks like a button.","variants":{"keys":["default","destructive","outline","secondary","ghost","link","primary","info","success","warning"],"default":"default"},"styling":{"baseClasses":"inline-flex items-center h-9 py-2 px-4 gap-2 rounded-lg text-sm font-medium","baseColorHint":"fill=#0c0c12 | text=#f8fafc","perVariant":[{"key":"default","classes":"inline-flex items-center h-9 py-2 px-4 gap-2 rounded-lg text-sm font-medium","colorHint":"fill=#0c0c12 | text=#f8fafc"},{"key":"destructive","classes":"inline-flex items-center h-9 py-2 px-4 gap-2 rounded-lg text-sm font-medium","colorHint":"fill=#ef4444 | text=#f8fafc"},{"key":"outline","classes":"inline-flex items-center h-9 py-2 px-4 gap-2 rounded-lg border text-sm font-medium","colorHint":"fill=#ffffff | stroke=#6c819d@1px | text=#0c0c12"},{"key":"secondary","classes":"inline-flex items-center h-9 py-2 px-4 gap-2 rounded-lg text-sm font-medium","colorHint":"fill=#f1f5f9 | text=#18181b"},{"key":"ghost","classes":"inline-flex items-center h-9 py-2 px-4 gap-2 rounded-lg bg-transparent text-sm font-medium","colorHint":"fill=transparent | text=#0c0c12"},{"key":"link","classes":"inline-flex items-center h-9 py-2 px-4 gap-2 rounded-lg bg-transparent text-sm font-medium","colorHint":"fill=transparent | text=#0c0c12"},{"key":"primary","classes":"inline-flex items-center h-9 py-2 px-4 gap-2 rounded-lg text-sm font-medium","colorHint":"fill=#394794 | text=#f8fafc"},{"key":"info","classes":"inline-flex items-center h-9 py-2 px-4 gap-2 rounded-lg text-sm font-medium","colorHint":"fill=#1d4ed8 | text=#f8fafc"},{"key":"success","classes":"inline-flex items-center h-9 py-2 px-4 gap-2 rounded-lg text-sm font-medium","colorHint":"fill=#15803d | text=#f8fafc"},{"key":"warning","classes":"inline-flex items-center h-9 py-2 px-4 gap-2 rounded-lg text-sm font-medium","colorHint":"fill=#b45309 | text=#f8fafc"}]},"slots":[],"sourceFile":"src/components/inputs/Button.tsx","specSource":"design/inputs.pen","docsUrl":"https://gunjo.dev/docs/components/button","stability":"beta"},{"category":"inputs","name":"calendar","title":"Calendar","description":"A date field component that allows users to enter and edit date.","variants":{"keys":["default"],"default":"default"},"styling":{"baseClasses":"flex flex-col w-[320px] p-4 rounded-lg border","baseColorHint":"fill=#FFFFFF | stroke=#e2e8f0@1px","perVariant":[{"key":"default","classes":"flex flex-col w-[320px] p-4 rounded-lg border","colorHint":"fill=#FFFFFF | stroke=#e2e8f0@1px"}]},"slots":["calendarHeader","calendarGrid"],"sourceFile":"src/components/inputs/Calendar.tsx","specSource":"design/inputs.pen","docsUrl":"https://gunjo.dev/docs/components/calendar","stability":"experimental"},{"category":"inputs","name":"chatComposer","title":"ChatComposer","description":"Container that composes ChatInput with prompt choices, workspace context, usage status, footer context, or an accessory.","variants":{"keys":["default","context","prompt"],"default":"default"},"styling":{"baseClasses":"inline-flex items-center w-full p-0 gap-3","baseColorHint":null,"perVariant":[{"key":"default","classes":"inline-flex items-center w-full p-0 gap-3","colorHint":null},{"key":"context","classes":"inline-flex items-center w-full p-0 gap-3","colorHint":null},{"key":"prompt","classes":"inline-flex items-center w-full p-0 gap-3","colorHint":null}]},"slots":[],"sourceFile":"src/components/inputs/ChatComposer.tsx","specSource":"design/inputs.pen","docsUrl":"https://gunjo.dev/docs/components/chat-composer","stability":"experimental"},{"category":"inputs","name":"chatInput","title":"ChatInput","description":"Message composer with multiline input, attachment action, send/stop controls, and disabled-state feedback.","variants":{"keys":["default","processing"],"default":"default"},"styling":{"baseClasses":"inline-flex items-center w-full p-3 gap-2","baseColorHint":"fill=#ffffff","perVariant":[{"key":"default","classes":"inline-flex items-center w-full p-3 gap-2","colorHint":"fill=#ffffff"},{"key":"processing","classes":"inline-flex items-center w-full p-3 gap-2","colorHint":"fill=#ffffff"}]},"slots":[],"sourceFile":"src/components/inputs/ChatInput.tsx","specSource":"design/inputs.pen","docsUrl":"https://gunjo.dev/docs/components/chat-input","stability":"experimental"},{"category":"inputs","name":"checkbox","title":"Checkbox","description":"A control that allows the user to toggle between checked and not checked.","variants":{"keys":["unchecked","checked","disabled"],"default":"unchecked"},"styling":{"baseClasses":"w-5 h-5 rounded border","baseColorHint":"fill=#ffffff | stroke=#6c819d@1px","perVariant":[{"key":"unchecked","classes":"w-5 h-5 rounded border","colorHint":"fill=#ffffff | stroke=#6c819d@1px"},{"key":"checked","classes":"inline-flex items-center w-5 h-5 rounded text-xs font-semibold","colorHint":"fill=#0c0c12 | text=#f8fafc"},{"key":"disabled","classes":"w-5 h-5 rounded border","colorHint":"fill=#f1f5f9 | stroke=#e2e8f0@1px"}]},"slots":[],"sourceFile":"src/components/inputs/Checkbox.tsx","specSource":"design/inputs.pen","docsUrl":"https://gunjo.dev/docs/components/checkbox","stability":"beta"},{"category":"inputs","name":"combobox","title":"Combobox","description":"Searchable select. Combines Popover + Command for filterable option lists.","variants":{"keys":[],"default":null},"styling":{"baseClasses":"","baseColorHint":null,"perVariant":[]},"slots":[],"sourceFile":"src/components/inputs/Combobox.tsx","specSource":"design/inputs.pen","docsUrl":"https://gunjo.dev/docs/components/combobox","stability":"experimental"},{"category":"inputs","name":"copyButton","title":"CopyButton","description":"Clipboard action button with tooltip feedback and copied-state icon or label.","variants":{"keys":["default","label"],"default":"default"},"styling":{"baseClasses":"","baseColorHint":null,"perVariant":[{"key":"default","classes":"","colorHint":null},{"key":"label","classes":"","colorHint":null}]},"slots":[],"sourceFile":"src/components/inputs/CopyButton.tsx","specSource":"design/inputs.pen","docsUrl":"https://gunjo.dev/docs/components/copy-button","stability":"experimental"},{"category":"inputs","name":"coSign","title":"CoSign","description":"Two-person verification (2人確認 / ダブルチェック / co-sign): a second actor enters their id (guarded to differ from the primary), ticks the required attestations, and signs — producing a timestamped signed value the consumer reads to gate an action. For medication double-checks, controlled substances, transfusion, surgical time-outs, and finance maker-checker approvals.","variants":{"keys":["default"],"default":"default"},"styling":{"baseClasses":"w-full","baseColorHint":null,"perVariant":[{"key":"default","classes":"w-full","colorHint":null}]},"slots":[],"sourceFile":"src/components/inputs/CoSign.tsx","specSource":"design/inputs.pen","docsUrl":"https://gunjo.dev/docs/components/co-sign","stability":"beta"},{"category":"inputs","name":"currencyInput","title":"CurrencyInput","description":"Money editor: a currency-symbol-prefixed, thousands-grouped, right-aligned amount input that formats while typing and emits a numeric value. JPY-first; for invoices, payroll, expenses, and any fintech amount field.","variants":{"keys":["default"],"default":"default"},"styling":{"baseClasses":"w-full","baseColorHint":null,"perVariant":[{"key":"default","classes":"w-full","colorHint":null}]},"slots":[],"sourceFile":"src/components/inputs/CurrencyInput.tsx","specSource":"design/inputs.pen","docsUrl":"https://gunjo.dev/docs/components/currency-input","stability":"experimental"},{"category":"inputs","name":"datePicker","title":"DatePicker","description":"Date input with popup Calendar. Wraps Popover + Calendar primitives.","variants":{"keys":[],"default":null},"styling":{"baseClasses":"","baseColorHint":null,"perVariant":[]},"slots":[],"sourceFile":"src/components/inputs/DatePicker.tsx","specSource":"design/inputs.pen","docsUrl":"https://gunjo.dev/docs/components/date-picker","stability":"beta"},{"category":"inputs","name":"dateRangePicker","title":"DateRangePicker","description":"Pick a date range with two-month Calendar in popover.","variants":{"keys":[],"default":null},"styling":{"baseClasses":"","baseColorHint":null,"perVariant":[]},"slots":[],"sourceFile":"src/components/inputs/DateRangePicker.tsx","specSource":"design/inputs.pen","docsUrl":"https://gunjo.dev/docs/components/date-range-picker","stability":"experimental"},{"category":"inputs","name":"dayBand","title":"DayBand","description":"The one-day band: a single horizontal surface that shows where you are inside a day. Coloured stretches (night / twilight / day, off-shift / handover / on-shift, closed / open) drawn as phases, named marks at the moments that matter (sunrise, a shift change), the live edge, and a thumb that can be scrubbed. The generalisation of 'show a position inside a day as a surface' — duty rosters, operating windows, opening hours, and the day/night band it was extracted from. Computes NOTHING about the day: sunrise and sunset are times the caller passes as marks, phases are stretches the caller passes, and `now` is a number the caller reads from its own clock — no astronomy, no timers, no locale assumptions inside (the TimeTransport / Stringline rule). Phase tones resolve to the SUBTLE surface tokens because a phase is a background that marks and the thumb are drawn on top of; a raw CSS colour is accepted when the ramp is artwork. Pointer scrubbing is `absolute` (press is position) or `relative` (drag by distance, which can roll past midnight and expects the caller to re-base the day). Real role=slider with arrow / shift-arrow / Page / Home / End keys and an aria-valuetext that names the clock time AND the phase it falls in, so a colour never carries meaning alone. Touch height is 44px. Drops into TimeTransport's `scrubber` slot. Distinct from Slider (a plain value with no day), SegmentTimelineCard (an ARBITRARY window, not one day) and WeekView / ScheduleGrid (more than one day).","variants":{"keys":["default"],"default":"default"},"styling":{"baseClasses":"w-full","baseColorHint":null,"perVariant":[{"key":"default","classes":"w-full","colorHint":null}]},"slots":[],"sourceFile":"src/components/inputs/DayBand.tsx","specSource":"design/inputs.pen","docsUrl":"https://gunjo.dev/docs/components/day-band","stability":"experimental"},{"category":"inputs","name":"editableField","title":"Editable Field","description":"Labelled field that switches between read-only display and explicit save/cancel editing.","variants":{"keys":["default"],"default":"default"},"styling":{"baseClasses":"w-full p-0","baseColorHint":null,"perVariant":[{"key":"default","classes":"w-full p-0","colorHint":null}]},"slots":[],"sourceFile":"src/components/inputs/EditableField.tsx","specSource":"design/inputs.pen","docsUrl":"https://gunjo.dev/docs/components/editable-field","stability":"experimental"},{"category":"inputs","name":"fileUploader","title":"File Uploader","description":"Drag-and-drop file intake with compact list rendering.","variants":{"keys":["default"],"default":"default"},"styling":{"baseClasses":"flex flex-col items-center w-[640px] gap-4","baseColorHint":null,"perVariant":[{"key":"default","classes":"flex flex-col items-center w-[640px] gap-4","colorHint":null}]},"slots":["fileUploaderDropzone","fileUploaderItem"],"sourceFile":"src/components/inputs/FileUploader.tsx","specSource":"design/inputs.pen","docsUrl":"https://gunjo.dev/docs/components/file-uploader","stability":"experimental"},{"category":"inputs","name":"filterButton","title":"FilterButton","description":"Filter trigger with dashed border, count badge, and command popover list.","variants":{"keys":["default","selected","popover"],"default":"default"},"styling":{"baseClasses":"flex flex-row items-center h-9 py-2 px-3 gap-2 rounded-md border","baseColorHint":"stroke=#e2e8f0@1px","perVariant":[{"key":"default","classes":"flex flex-row items-center h-9 py-2 px-3 gap-2 rounded-md border","colorHint":"stroke=#e2e8f0@1px"},{"key":"selected","classes":"flex flex-row items-center h-9 py-2 px-3 gap-2 rounded-md border","colorHint":"stroke=#e2e8f0@1px"},{"key":"popover","classes":"flex flex-row items-center h-9 py-2 px-3 gap-2 rounded-md border","colorHint":"fill=#ffffff | stroke=#e2e8f0@1px"}]},"slots":["filterButtonIcon","filterButtonLabel"],"sourceFile":"src/components/inputs/FilterButton.tsx","specSource":"design/inputs.pen","docsUrl":"https://gunjo.dev/docs/components/filter-button","stability":"experimental"},{"category":"inputs","name":"form","title":"Form","description":"Compound form primitives for vertical field composition, labels, descriptions, messages, and full-width controls.","variants":{"keys":[],"default":null},"styling":{"baseClasses":"","baseColorHint":null,"perVariant":[]},"slots":[],"sourceFile":"src/components/inputs/Form.tsx","specSource":"design/inputs.pen","docsUrl":"https://gunjo.dev/docs/components/form","stability":"beta"},{"category":"inputs","name":"input","title":"Input","description":"Displays a form input field or a component that looks like an input field.","variants":{"keys":["default","placeholder","disabled"],"default":"default"},"styling":{"baseClasses":"inline-flex items-center w-full h-9 py-2 px-3 rounded-lg border text-sm font-normal","baseColorHint":"fill=#ffffff | stroke=#6c819d@1px | text=#0c0c12","perVariant":[{"key":"default","classes":"inline-flex items-center w-full h-9 py-2 px-3 rounded-lg border text-sm font-normal","colorHint":"fill=#ffffff | stroke=#6c819d@1px | text=#0c0c12"},{"key":"placeholder","classes":"inline-flex items-center w-full h-9 py-2 px-3 rounded-lg border text-sm font-normal","colorHint":"fill=#ffffff | stroke=#6c819d@1px | text=#64748b"},{"key":"disabled","classes":"inline-flex items-center w-full h-9 py-2 px-3 rounded-lg border text-sm font-normal","colorHint":"fill=#f1f5f9 | stroke=#e2e8f0@1px | text=#94a3b8"}]},"slots":[],"sourceFile":"src/components/inputs/Input.tsx","specSource":"design/inputs.pen","docsUrl":"https://gunjo.dev/docs/components/input","stability":"beta"},{"category":"inputs","name":"inputOTP","title":"InputOTP","description":"One-time-password input with per-digit slots and optional separator.","variants":{"keys":[],"default":null},"styling":{"baseClasses":"","baseColorHint":null,"perVariant":[]},"slots":[],"sourceFile":"src/components/inputs/InputOTP.tsx","specSource":"design/inputs.pen","docsUrl":"https://gunjo.dev/docs/components/input-otp","stability":"experimental"},{"category":"inputs","name":"label","title":"Label","description":"Renders an accessible label associated with controls.","variants":{"keys":[],"default":null},"styling":{"baseClasses":"","baseColorHint":null,"perVariant":[]},"slots":[],"sourceFile":"src/components/inputs/Label.tsx","specSource":"design/inputs.pen","docsUrl":"https://gunjo.dev/docs/components/label","stability":"beta"},{"category":"inputs","name":"layerMenu","title":"LayerMenu","description":"Choose what is drawn on top of a map — clouds, rain, borders, tracked objects — from a round map button: layers in labelled groups, each a toggle row with a mark, and an 'All' row first. A TAP opens the menu and a LONG PRESS (450ms, configurable, off with 0) hides every layer and a second one brings the previous set back: the action that repaints the whole picture goes on the gesture that cannot happen by accident, because a tap is how people find out what a button does. The 'All' row does the same for readers who never find the long press, keyboard included. 'All' has three states — all on, all off, some (a dash, aria-pressed='mixed') — and keeps the same mark as the other rows, since a row without a mark reads as a different kind of thing. A layer that cannot be switched now (`disabledReason`) keeps its row and its state, says why in a few words, and is left alone by 'All'. Rows stay open after a press so the marks can be seen changing. Group headings and notes use the canvas type tier. Controlled (`value` / `onValueChange`); `layerMenuAllState()` is exported for callers that mirror the state elsewhere. The same shape serves a chart's series. Distinct from DropdownMenu (actions, closes on select, no long press), CheckboxGroup (a form field on a page) and FilterChips (filters a list).","variants":{"keys":["default"],"default":"default"},"styling":{"baseClasses":"","baseColorHint":null,"perVariant":[{"key":"default","classes":"","colorHint":null}]},"slots":[],"sourceFile":"src/components/inputs/LayerMenu.tsx","specSource":"design/inputs.pen","docsUrl":"https://gunjo.dev/docs/components/layer-menu","stability":"experimental"},{"category":"inputs","name":"mapControlButton","title":"MapControlButton","description":"The round, icon-only button that floats on a map or a canvas: zoom in, zoom out, go to the picked place, go to my location. Its surface is its own (translucent background, blurred backdrop, hairline border) because the thing behind it is imagery, not a page — which is why it is a component and not a Button variant. States: `pressed` (a toggle that is on, aria-pressed), `disabled` with a `disabledReason` tooltip reachable by keyboard, `status='busy'` (the glyph pulses, aria-busy; the pulse stops under prefers-reduced-motion) and `status='error'` (a warning ring plus a `!` mark — never colour alone; brief, and cleared by the caller because the button holds no timer). `label` is both the accessible name and the tooltip. Sizes: `default` 44px (the GunjoUI touch line), `sm` 40px (the floor for a dense phone column — never smaller), `lg` 48px (tablet). The glyph carries meaning: 'my location' is a pin and 'the place I picked' is a ring with a dot; one glyph for both makes the reader guess where the map will jump. Distinct from Button / TooltipButton (on a page, not on imagery) and ToggleGroup (several exclusive choices). LayerMenu uses it as its trigger.","variants":{"keys":["default","sm","lg"],"default":"default"},"styling":{"baseClasses":"","baseColorHint":null,"perVariant":[{"key":"default","classes":"","colorHint":null},{"key":"sm","classes":"","colorHint":null},{"key":"lg","classes":"","colorHint":null}]},"slots":[],"sourceFile":"src/components/inputs/MapControlButton.tsx","specSource":"design/inputs.pen","docsUrl":"https://gunjo.dev/docs/components/map-control-button","stability":"experimental"},{"category":"inputs","name":"mention","title":"Mention","description":"Textarea with @mention picker — autocompletes user names from a list.","variants":{"keys":[],"default":null},"styling":{"baseClasses":"","baseColorHint":null,"perVariant":[]},"slots":[],"sourceFile":"src/components/inputs/Mention.tsx","specSource":"design/inputs.pen","docsUrl":"https://gunjo.dev/docs/components/mention","stability":"experimental"},{"category":"inputs","name":"numberInput","title":"NumberInput","description":"Numeric input with up/down stepper buttons.","variants":{"keys":[],"default":null},"styling":{"baseClasses":"","baseColorHint":null,"perVariant":[]},"slots":[],"sourceFile":"src/components/inputs/NumberInput.tsx","specSource":"design/inputs.pen","docsUrl":"https://gunjo.dev/docs/components/number-input","stability":"beta"},{"category":"inputs","name":"passwordGroup","title":"PasswordGroup","description":"Password field composition with visibility control, requirement checklist, strength meter, error message, and disabled feedback.","variants":{"keys":[],"default":null},"styling":{"baseClasses":"","baseColorHint":null,"perVariant":[]},"slots":[],"sourceFile":"src/components/inputs/PasswordGroup.tsx","specSource":"design/inputs.pen","docsUrl":"https://gunjo.dev/docs/components/password-group","stability":"experimental"},{"category":"inputs","name":"passwordInput","title":"PasswordInput","description":"Password field with show/hide toggle button.","variants":{"keys":[],"default":null},"styling":{"baseClasses":"","baseColorHint":null,"perVariant":[]},"slots":[],"sourceFile":"src/components/inputs/PasswordInput.tsx","specSource":"design/inputs.pen","docsUrl":"https://gunjo.dev/docs/components/password-input","stability":"experimental"},{"category":"inputs","name":"passwordRequirementList","title":"PasswordRequirementList","description":"Password requirement checklist that can be used standalone or inside PasswordGroup.","variants":{"keys":[],"default":null},"styling":{"baseClasses":"","baseColorHint":null,"perVariant":[]},"slots":[],"sourceFile":"src/components/inputs/PasswordRequirementList.tsx","specSource":"design/inputs.pen","docsUrl":"https://gunjo.dev/docs/components/password-requirement-list","stability":"experimental"},{"category":"inputs","name":"passwordStrengthMeter","title":"PasswordStrengthMeter","description":"Password strength meter that displays a caller-provided score, label, and helper text.","variants":{"keys":[],"default":null},"styling":{"baseClasses":"","baseColorHint":null,"perVariant":[]},"slots":[],"sourceFile":"src/components/inputs/PasswordStrengthMeter.tsx","specSource":"design/inputs.pen","docsUrl":"https://gunjo.dev/docs/components/password-strength-meter","stability":"experimental"},{"category":"inputs","name":"phoneInput","title":"PhoneInput","description":"Telephone input with country calling-code affordance and caller-provided formatting hook.","variants":{"keys":[],"default":null},"styling":{"baseClasses":"","baseColorHint":null,"perVariant":[]},"slots":[],"sourceFile":"src/components/inputs/PhoneInput.tsx","specSource":"design/inputs.pen","docsUrl":"https://gunjo.dev/docs/components/phone-input","stability":"experimental"},{"category":"inputs","name":"postalCodeInput","title":"PostalCodeInput","description":"Postal-code input with prefix affordance and caller-provided formatting hook.","variants":{"keys":[],"default":null},"styling":{"baseClasses":"","baseColorHint":null,"perVariant":[]},"slots":[],"sourceFile":"src/components/inputs/PostalCodeInput.tsx","specSource":"design/inputs.pen","docsUrl":"https://gunjo.dev/docs/components/postal-code-input","stability":"experimental"},{"category":"inputs","name":"radioGroup","title":"RadioGroup","description":"A set of checkable buttons—known as radio buttons—where no more than one of the buttons can be checked at a time.","variants":{"keys":["unchecked","checked"],"default":"unchecked"},"styling":{"baseClasses":"w-4 h-4 rounded-lg border","baseColorHint":"fill=#ffffff | stroke=#6c819d@1px","perVariant":[{"key":"unchecked","classes":"w-4 h-4 rounded-lg border","colorHint":"fill=#ffffff | stroke=#6c819d@1px"},{"key":"checked","classes":"w-4 h-4 rounded-lg border bg-transparent","colorHint":"fill=transparent | stroke=#0c0c12@1px"}]},"slots":[],"sourceFile":"src/components/inputs/RadioGroup.tsx","specSource":"design/inputs.pen","docsUrl":"https://gunjo.dev/docs/components/radio-group","stability":"beta"},{"category":"inputs","name":"rangeSlider","title":"RangeSlider","description":"Selects a minimum and maximum value within a bounded range.","variants":{"keys":["default"],"default":"default"},"styling":{"baseClasses":"w-[240px] h-7","baseColorHint":null,"perVariant":[{"key":"default","classes":"w-[240px] h-7","colorHint":null}]},"slots":[],"sourceFile":"src/components/inputs/RangeSlider.tsx","specSource":"design/inputs.pen","docsUrl":"https://gunjo.dev/docs/components/range-slider","stability":"experimental"},{"category":"inputs","name":"scanGate","title":"ScanGate","description":"Staged barcode scan flow: ordered ScanInput stages (e.g. location→item, carton→item) where each stage resolves a confirmed context the next stage reads, auto-advancing and re-focusing between steps. For WMS picking, put-away and packing where you scan-to-confirm before scan-to-count.","variants":{"keys":["default"],"default":"default"},"styling":{"baseClasses":"w-full","baseColorHint":null,"perVariant":[{"key":"default","classes":"w-full","colorHint":null}]},"slots":[],"sourceFile":"src/components/inputs/ScanGate.tsx","specSource":"design/inputs.pen","docsUrl":"https://gunjo.dev/docs/components/scan-gate","stability":"experimental"},{"category":"inputs","name":"scanInput","title":"ScanInput","description":"Barcode / QR scan field: a scan gun (or hand entry) types a code then Enter; it fires `onScan`, announces the result, auto-clears and re-focuses for the next scan, and keeps an optional running feed. For POS, stocktake, returns and goods-receiving — scan → match → tick up.","variants":{"keys":["default"],"default":"default"},"styling":{"baseClasses":"w-full","baseColorHint":null,"perVariant":[{"key":"default","classes":"w-full","colorHint":null}]},"slots":[],"sourceFile":"src/components/inputs/ScanInput.tsx","specSource":"design/inputs.pen","docsUrl":"https://gunjo.dev/docs/components/scan-input","stability":"experimental"},{"category":"inputs","name":"searchInput","title":"SearchInput","description":"Input with leading search icon for search bars.","variants":{"keys":[],"default":null},"styling":{"baseClasses":"","baseColorHint":null,"perVariant":[]},"slots":[],"sourceFile":"src/components/inputs/SearchInput.tsx","specSource":"design/inputs.pen","docsUrl":"https://gunjo.dev/docs/components/search-input","stability":"beta"},{"category":"inputs","name":"segmentedControl","title":"SegmentedControl","description":"The small inline single-select toggle: 2–4 equal-width segments on a recessed track, the active one raised (the iOS/Android segmented look). For the compact either/or choices a B2C form is full of — 旅客区分 (大人/小児), 支払い (現金/IC/QR), 片道/往復, 出発/到着, 個人/法人, 日/週/月. A real role=radiogroup with role=radio segments, roving tabindex + arrow-key nav (WAI-ARIA), and a colour-safe selected state (raised surface, not colour alone); onValueChange is always a single string. Distinct from ToggleGroup (the general, content-fit, single-OR-multi toggle for desktop filters/formatting) and RadioCard (the large, priced choice CARD) — this is the small equal-width mode/segment switch. options[] of {value,label,icon?,disabled?}; controlled (value) or uncontrolled (defaultValue).","variants":{"keys":["default"],"default":"default"},"styling":{"baseClasses":"w-full","baseColorHint":null,"perVariant":[{"key":"default","classes":"w-full","colorHint":null}]},"slots":[],"sourceFile":"src/components/inputs/SegmentedControl.tsx","specSource":"design/inputs.pen","docsUrl":"https://gunjo.dev/docs/components/segmented-control","stability":"experimental"},{"category":"inputs","name":"select","title":"Select","description":"Displays a list of options for the user to pick from.","variants":{"keys":["default"],"default":"default"},"styling":{"baseClasses":"inline-flex items-center w-full h-9 py-2 px-3 rounded-lg border text-sm font-normal","baseColorHint":"fill=#ffffff | stroke=#6c819d@1px | text=#64748b","perVariant":[{"key":"default","classes":"inline-flex items-center w-full h-9 py-2 px-3 rounded-lg border text-sm font-normal","colorHint":"fill=#ffffff | stroke=#6c819d@1px | text=#64748b"}]},"slots":[],"sourceFile":"src/components/inputs/Select.tsx","specSource":"design/inputs.pen","docsUrl":"https://gunjo.dev/docs/components/select","stability":"beta"},{"category":"inputs","name":"slider","title":"Slider","description":"An input where the user selects a value from within a given range.","variants":{"keys":["default"],"default":"default"},"styling":{"baseClasses":"w-full h-5 rounded-[10px]","baseColorHint":"fill=#e2e8f0","perVariant":[{"key":"default","classes":"w-full h-5 rounded-[10px]","colorHint":"fill=#e2e8f0"}]},"slots":[],"sourceFile":"src/components/inputs/Slider.tsx","specSource":"design/inputs.pen","docsUrl":"https://gunjo.dev/docs/components/slider","stability":"experimental"},{"category":"inputs","name":"sortButton","title":"SortButton","description":"Three-state sort trigger (none, asc, desc) with icon + text.","variants":{"keys":["none","asc","desc"],"default":"none"},"styling":{"baseClasses":"flex flex-row items-center h-9 py-2 px-3 gap-2 rounded-md","baseColorHint":null,"perVariant":[{"key":"none","classes":"flex flex-row items-center h-9 py-2 px-3 gap-2 rounded-md","colorHint":null},{"key":"asc","classes":"flex flex-row items-center h-9 py-2 px-3 gap-2 rounded-md","colorHint":"fill=#eef2ff"},{"key":"desc","classes":"flex flex-row items-center h-9 py-2 px-3 gap-2 rounded-md","colorHint":"fill=#fff7ed"}]},"slots":["sortButtonIcon","sortButtonLabel"],"sourceFile":"src/components/inputs/SortButton.tsx","specSource":"design/inputs.pen","docsUrl":"https://gunjo.dev/docs/components/sort-button","stability":"experimental"},{"category":"inputs","name":"switch","title":"Switch","description":"A control that allows the user to toggle between checked and not checked.","variants":{"keys":["unchecked","checked"],"default":"unchecked"},"styling":{"baseClasses":"w-11 h-6 p-0.5 rounded-full","baseColorHint":"fill=#f1f5f9","perVariant":[{"key":"unchecked","classes":"w-11 h-6 p-0.5 rounded-full","colorHint":"fill=#f1f5f9"},{"key":"checked","classes":"w-11 h-6 p-0.5 rounded-full","colorHint":"fill=#0c0c12"}]},"slots":[],"sourceFile":"src/components/inputs/Switch.tsx","specSource":"design/inputs.pen","docsUrl":"https://gunjo.dev/docs/components/switch","stability":"beta"},{"category":"inputs","name":"tagInput","title":"TagInput","description":"Multi-tag input with Enter to add and × to remove.","variants":{"keys":[],"default":null},"styling":{"baseClasses":"","baseColorHint":null,"perVariant":[]},"slots":[],"sourceFile":"src/components/inputs/TagInput.tsx","specSource":"design/inputs.pen","docsUrl":"https://gunjo.dev/docs/components/tag-input","stability":"experimental"},{"category":"inputs","name":"textarea","title":"Textarea","description":"Displays a form textarea or a component that looks like a textarea.","variants":{"keys":["default","disabled"],"default":"default"},"styling":{"baseClasses":"w-full h-20 py-2 px-3 rounded-lg border","baseColorHint":"fill=#ffffff | stroke=#6c819d@1px","perVariant":[{"key":"default","classes":"w-full h-20 py-2 px-3 rounded-lg border","colorHint":"fill=#ffffff | stroke=#6c819d@1px"},{"key":"disabled","classes":"w-full h-20 py-2 px-3 rounded-lg border","colorHint":"fill=#f1f5f9 | stroke=#e2e8f0@1px"}]},"slots":[],"sourceFile":"src/components/inputs/Textarea.tsx","specSource":"design/inputs.pen","docsUrl":"https://gunjo.dev/docs/components/textarea","stability":"beta"},{"category":"inputs","name":"timelineScrubber","title":"TimelineScrubber","description":"One scale that runs from the past into the future — radar frames from two hours ago to twelve hours ahead, a log's recent snapshots, a forecast run — with the selected moment FIXED in the middle and the scale sliding under it. Dragging slides the ticks (relative drag, touch-action pan-y so the page still scrolls), so the moment you are looking at stays where your eye already is; the ends fade out to say there is more; a tap on a tick jumps to it. `lastObservedIndex` splits measured from forecast, told apart three ways and never by colour alone: the header names the side (Badge 'Observed' / 'Forecast'), the boundary is a dashed line, and the ticks and the centre marker change tone (success / warning). Play steps forward every `stepInterval` ms and stops at the end (controlled `playing` or its own); it owns that timer only and never reads the clock, so what 'now' is stays the caller's decision (the TimeTransport rule). Dragging or a key pauses it. role='slider' with arrows, PageUp / PageDown and Home / End; aria-valuetext reads the step and its side ('11:05 · Forecast'). Major ticks carry labels, thinned so none sit closer than 44px; pending (not yet loaded) steps are drawn faint. HTML/CSS. Distinct from Slider (a value on a fixed track, thumb moves), DayBand (one day with phases, thumb moves) and TimeTransport (a continuous clock with speeds and jumps; this is its frame-by-frame sibling).","variants":{"keys":["default"],"default":"default"},"styling":{"baseClasses":"","baseColorHint":null,"perVariant":[{"key":"default","classes":"","colorHint":null}]},"slots":[],"sourceFile":"src/components/inputs/TimelineScrubber.tsx","specSource":"design/inputs.pen","docsUrl":"https://gunjo.dev/docs/components/timeline-scrubber","stability":"experimental"},{"category":"inputs","name":"timePicker","title":"TimePicker","description":"Hour + minute select with optional 12 / 24 hour mode.","variants":{"keys":[],"default":null},"styling":{"baseClasses":"","baseColorHint":null,"perVariant":[]},"slots":[],"sourceFile":"src/components/inputs/TimePicker.tsx","specSource":"design/inputs.pen","docsUrl":"https://gunjo.dev/docs/components/time-picker","stability":"experimental"},{"category":"inputs","name":"timeTransport","title":"TimeTransport","description":"The playback / scrub transport for a continuous value: a large readout of where you are, play-pause, named speed steps, signed jump buttons, a live-vs-detached state and a one-press return to now. The generalisation of 'move a continuous value in graded steps, and get back to live' — log replay, rewinding a monitoring board, stepping a simulation clock, scrubbing a recording, and the map/globe time controls it was extracted from. Holds NO clock of its own: `value` comes in and `onValueChange` goes out, so the caller owns the ticking and SSR renders the same frame twice (the Stringline rule). Speeds are caller-named steps (`speeds[]`), never a raw multiplier range, because a design system cannot know whether 1× means a second or a day. Live-vs-detached is resolved from `now` (or forced with `live`) and is never carried by colour alone — a labelled LiveBadge states it in words and the readout is not recoloured at all. Distinct from Slider / RangeSlider (a value picker with no playback), TimePicker / DatePicker / Calendar (pick an ABSOLUTE instant, no relative motion), SegmentedControl (the speed steps alone) and Timeline / Stringline / Gantt / SegmentTimelineCard (which DISPLAY time and take no input). Pass a scrubber (DayBand) through the `scrubber` slot. Touch targets are ≥44px.","variants":{"keys":["default"],"default":"default"},"styling":{"baseClasses":"w-full","baseColorHint":null,"perVariant":[{"key":"default","classes":"w-full","colorHint":null}]},"slots":[],"sourceFile":"src/components/inputs/TimeTransport.tsx","specSource":"design/inputs.pen","docsUrl":"https://gunjo.dev/docs/components/time-transport","stability":"experimental"},{"category":"inputs","name":"toggle","title":"Toggle","description":"Two-state pressable button (icon-style toggle).","variants":{"keys":[],"default":null},"styling":{"baseClasses":"","baseColorHint":null,"perVariant":[]},"slots":[],"sourceFile":"src/components/inputs/Toggle.tsx","specSource":"design/inputs.pen","docsUrl":"https://gunjo.dev/docs/components/toggle","stability":"experimental"},{"category":"inputs","name":"toggleGroup","title":"ToggleGroup","description":"A set of two-state buttons that can be toggled on or off.","variants":{"keys":["default","outline"],"default":"default"},"styling":{"baseClasses":"inline-flex items-center h-9 py-0 px-3 rounded-lg text-sm font-medium","baseColorHint":"fill=#f1f5f9 | text=#0c0c12","perVariant":[{"key":"default","classes":"inline-flex items-center h-9 py-0 px-3 rounded-lg text-sm font-medium","colorHint":"fill=#f1f5f9 | text=#0c0c12"},{"key":"outline","classes":"inline-flex items-center h-9 py-0 px-3 rounded-lg border text-sm font-medium","colorHint":"fill=#ffffff | stroke=#6c819d@1px | text=#0c0c12"}]},"slots":[],"sourceFile":"src/components/inputs/ToggleGroup.tsx","specSource":"design/inputs.pen","docsUrl":"https://gunjo.dev/docs/components/toggle-group","stability":"beta"},{"category":"inputs","name":"tooltipButton","title":"TooltipButton","description":"Button composition that pairs an action with a GunjoUI Tooltip for icon, compact, or explanatory controls.","variants":{"keys":["default"],"default":"default"},"styling":{"baseClasses":"","baseColorHint":null,"perVariant":[{"key":"default","classes":"","colorHint":null}]},"slots":[],"sourceFile":"src/components/inputs/TooltipButton.tsx","specSource":"design/inputs.pen","docsUrl":"https://gunjo.dev/docs/components/tooltip-button","stability":"experimental"},{"category":"display","name":"accordion","title":"Accordion","description":"A vertically stacked set of interactive headings that each reveal a section of content.","variants":{"keys":["collapsed","expanded"],"default":"collapsed"},"styling":{"baseClasses":"flex flex-col w-full border","baseColorHint":"stroke=#e2e8f0@1px","perVariant":[{"key":"collapsed","classes":"flex flex-col w-full border","colorHint":"stroke=#e2e8f0@1px"},{"key":"expanded","classes":"flex flex-col w-full border","colorHint":"stroke=#e2e8f0@1px"}]},"slots":["LQCc9"],"sourceFile":"src/components/display/Accordion.tsx","specSource":"design/display.pen","docsUrl":"https://gunjo.dev/docs/components/accordion","stability":"experimental"},{"category":"display","name":"accordionGroup","title":"AccordionGroup","description":"Labeled accordion composition with a single expand-all/collapse-all toggle control for FAQ, settings, and grouped disclosure lists.","variants":{"keys":["default","withDescription","withoutControls"],"default":"default"},"styling":{"baseClasses":"w-full p-0","baseColorHint":null,"perVariant":[{"key":"default","classes":"w-full p-0","colorHint":null},{"key":"withDescription","classes":"w-full p-0","colorHint":null},{"key":"withoutControls","classes":"w-full p-0","colorHint":null}]},"slots":[],"sourceFile":"src/components/display/AccordionGroup.tsx","specSource":"design/display.pen","docsUrl":"https://gunjo.dev/docs/components/accordion-group","stability":"experimental"},{"category":"display","name":"actionDataTable","title":"ActionDataTable","description":"Selectable data table composition with bulk actions, row actions, and disabled-action feedback.","variants":{"keys":["default","selection","rowActions"],"default":"default"},"styling":{"baseClasses":"w-full p-0","baseColorHint":null,"perVariant":[{"key":"default","classes":"w-full p-0","colorHint":null},{"key":"selection","classes":"w-full p-0","colorHint":null},{"key":"rowActions","classes":"w-full p-0","colorHint":null}]},"slots":[],"sourceFile":"src/components/display/ActionDataTable.tsx","specSource":"design/display.pen","docsUrl":"https://gunjo.dev/docs/components/action-data-table","stability":"experimental"},{"category":"display","name":"actionQueue","title":"ActionQueue","description":"The severity-sorted 'action-needed' worklist: the triage surface every back-office / dispatch / ops / CRM home screen opens with (失効防止 / 更新 / 満期 / 誕生日, ダイヤ乱れ・遅延・運休, アラート対応). Each row carries a severity (critical/warning/info/neutral → icon + tone, never colour alone, with an sr-only severity label), a category chip (kind), a headline + detail, trailing meta (due / time / count) and optional action buttons; rows sort critical → neutral. The other half of the morning dashboard alongside StatGroup (the KPI strip). For a single notice use Alert; for an ambient bell tray use NotificationCenter; this is the inline, act-now list. Presentational by default — onSelect makes a row's body activatable.","variants":{"keys":["default"],"default":"default"},"styling":{"baseClasses":"w-full","baseColorHint":null,"perVariant":[{"key":"default","classes":"w-full","colorHint":null}]},"slots":[],"sourceFile":"src/components/display/ActionQueue.tsx","specSource":"design/display.pen","docsUrl":"https://gunjo.dev/docs/components/action-queue","stability":"beta"},{"category":"display","name":"activityTimelineCard","title":"Activity Timeline Card","description":"HTML/CSS timeline card for activity, sleep, and operations dashboards with editable slots, segments, metrics, and hover/focus tooltips.","variants":{"keys":["default","compact"],"default":"default"},"styling":{"baseClasses":"w-full p-0","baseColorHint":null,"perVariant":[{"key":"default","classes":"w-full p-0","colorHint":null},{"key":"compact","classes":"w-full p-0","colorHint":null}]},"slots":[],"sourceFile":"src/components/display/ActivityTimelineCard.tsx","specSource":"design/display.pen","docsUrl":"https://gunjo.dev/docs/components/activity-timeline-card","stability":"experimental"},{"category":"display","name":"amountBreakdown","title":"AmountBreakdown","description":"The read-only money-derivation ledger: labeled line items, signed deductions, optional per-section subtotals, and an emphasized derived total, with an optional formula caption. The 'labeled lines → ± adjustments → total' block every 請求 / 見積 / 査定 / 支払 / 精算 / 控除 / 給与明細 screen needs (認定損害額 − 過失相殺 − 免責 − 既払金 = 今回支払額 / 基本保険料 ＋ 特約 − 各割引 = 年間保険料). Deductions render as a −|amount| glyph (sign never colour-only) with an sr-only 控除 label. Read-only by design — for an editable line-item grid with column totals use EditableDataTable; for a single signed delta use Statistic/Delta; for the back-office KPI strip use StatGroup. RSC-safe by default (formatValue defaults to formatCurrency); pass a custom formatValue only from a client boundary.","variants":{"keys":["default"],"default":"default"},"styling":{"baseClasses":"w-full","baseColorHint":null,"perVariant":[{"key":"default","classes":"w-full","colorHint":null}]},"slots":[],"sourceFile":"src/components/display/AmountBreakdown.tsx","specSource":"design/display.pen","docsUrl":"https://gunjo.dev/docs/components/amount-breakdown","stability":"beta"},{"category":"display","name":"analyticsCard","title":"AnalyticsCard","description":"Composable metric card shell for chart previews, deltas, and supporting context.","variants":{"keys":["default","positive","riskIncrease","flatWithFooter"],"default":"default"},"styling":{"baseClasses":"w-full p-0","baseColorHint":null,"perVariant":[{"key":"default","classes":"w-full p-0","colorHint":null},{"key":"positive","classes":"w-full p-0","colorHint":null},{"key":"riskIncrease","classes":"w-full p-0","colorHint":null},{"key":"flatWithFooter","classes":"w-full p-0","colorHint":null}]},"slots":[],"sourceFile":"src/components/display/AnalyticsCard.tsx","specSource":"design/display.pen","docsUrl":"https://gunjo.dev/docs/components/analytics-card","stability":"experimental"},{"category":"display","name":"approvalSteps","title":"ApprovalSteps","description":"Approval-route timeline: each step's state (pending / current / approved / rejected / skipped) maps to a tone, icon, and accessible label, with actor, timestamp, and comment. For expense, ringi, and review approval workflows. Built on Timeline.","variants":{"keys":["default","compact"],"default":"default"},"styling":{"baseClasses":"w-full","baseColorHint":null,"perVariant":[{"key":"default","classes":"w-full","colorHint":null},{"key":"compact","classes":"w-full","colorHint":null}]},"slots":[],"sourceFile":"src/components/display/ApprovalSteps.tsx","specSource":"design/display.pen","docsUrl":"https://gunjo.dev/docs/components/approval-steps","stability":"beta"},{"category":"display","name":"approvalWorkflow","title":"ApprovalWorkflow","description":"Interactive approval / review workflow: drives an ordered pipeline of stages through advance→next, send-back (to a prior stage with a reason, rolling back later records) and reject (terminal), recording an actor + timestamp on each transition, and renders the result with ApprovalSteps (state never colour-only). Controlled via value + onChange; advancing is gated by canAdvance. For case management, benefit/application screening, ringi/expense approval, onboarding and any staged back-office review.","variants":{"keys":["default"],"default":"default"},"styling":{"baseClasses":"w-full","baseColorHint":null,"perVariant":[{"key":"default","classes":"w-full","colorHint":null}]},"slots":[],"sourceFile":"src/components/display/ApprovalWorkflow.tsx","specSource":"design/display.pen","docsUrl":"https://gunjo.dev/docs/components/approval-workflow","stability":"experimental"},{"category":"display","name":"assetCard","title":"AssetCard","description":"Selectable media asset card for image libraries, files, and generated creative results with favorite, score, and preview affordances.","variants":{"keys":["default","compact"],"default":"default"},"styling":{"baseClasses":"w-full p-0 rounded-lg","baseColorHint":null,"perVariant":[{"key":"default","classes":"w-full p-0 rounded-lg","colorHint":null},{"key":"compact","classes":"w-full p-0 rounded-md","colorHint":null}]},"slots":[],"sourceFile":"src/components/display/AssetCard.tsx","specSource":"design/display.pen","docsUrl":"https://gunjo.dev/docs/components/asset-card","stability":"experimental"},{"category":"display","name":"assetGrid","title":"AssetGrid","description":"Responsive grouped media grid that renders AssetCard items with empty state, selection state, and preview hooks.","variants":{"keys":["default","compact"],"default":"default"},"styling":{"baseClasses":"w-full p-0","baseColorHint":null,"perVariant":[{"key":"default","classes":"w-full p-0","colorHint":null},{"key":"compact","classes":"w-full p-0","colorHint":null}]},"slots":[],"sourceFile":"src/components/display/AssetGrid.tsx","specSource":"design/display.pen","docsUrl":"https://gunjo.dev/docs/components/asset-grid","stability":"experimental"},{"category":"display","name":"avatar","title":"Avatar","description":"An image element with a fallback for representing the user.","variants":{"keys":["fallback","image"],"default":"fallback"},"styling":{"baseClasses":"inline-flex items-center w-10 h-10 rounded-full text-sm font-medium","baseColorHint":"fill=#f1f5f9 | text=#64748b","perVariant":[{"key":"fallback","classes":"inline-flex items-center w-10 h-10 rounded-full text-sm font-medium","colorHint":"fill=#f1f5f9 | text=#64748b"},{"key":"image","classes":"w-10 h-10 rounded-full","colorHint":null}]},"slots":[],"sourceFile":"src/components/display/Avatar.tsx","specSource":"design/display.pen","docsUrl":"https://gunjo.dev/docs/components/avatar","stability":"beta"},{"category":"display","name":"avatarGroup","title":"AvatarGroup","description":"Stack of overlapping avatars with optional +N overflow indicator.","variants":{"keys":[],"default":null},"styling":{"baseClasses":"","baseColorHint":null,"perVariant":[]},"slots":[],"sourceFile":"src/components/display/AvatarGroup.tsx","specSource":"design/display.pen","docsUrl":"https://gunjo.dev/docs/components/avatar-group","stability":"experimental"},{"category":"display","name":"badge","title":"Badge","description":"Displays a badge or a component that looks like a badge.","variants":{"keys":["default","secondary","destructive","outline","info","success","warning"],"default":"default"},"styling":{"baseClasses":"inline-flex items-center h-5 py-1 px-2 rounded-full text-xs font-semibold","baseColorHint":"fill=#0c0c12 | text=#f8fafc","perVariant":[{"key":"default","classes":"inline-flex items-center h-5 py-1 px-2 rounded-full text-xs font-semibold","colorHint":"fill=#0c0c12 | text=#f8fafc"},{"key":"secondary","classes":"inline-flex items-center h-5 py-1 px-2 rounded-full text-xs font-semibold","colorHint":"fill=#f1f5f9 | text=#18181b"},{"key":"destructive","classes":"inline-flex items-center h-5 py-1 px-2 rounded-full text-xs font-semibold","colorHint":"fill=#ef4444 | text=#f8fafc"},{"key":"outline","classes":"inline-flex items-center h-5 py-1 px-2 rounded-full border text-xs font-semibold","colorHint":"fill=#ffffff | stroke=#6c819d@1px | text=#0c0c12"},{"key":"info","classes":"inline-flex items-center h-5 py-1 px-2 rounded-full border text-xs font-semibold","colorHint":"fill=#EFF6FF | stroke=#BFDBFE@1px | text=#1D4ED8"},{"key":"success","classes":"inline-flex items-center h-5 py-1 px-2 rounded-full border text-xs font-semibold","colorHint":"fill=#ECFDF5 | stroke=#BBF7D0@1px | text=#15803D"},{"key":"warning","classes":"inline-flex items-center h-5 py-1 px-2 rounded-full border text-xs font-semibold","colorHint":"fill=#FFFBEB | stroke=#FCD34D@1px | text=#B45309"}]},"slots":[],"sourceFile":"src/components/display/Badge.tsx","specSource":"design/display.pen","docsUrl":"https://gunjo.dev/docs/components/badge","stability":"beta"},{"category":"display","name":"barChart","title":"BarChart","description":"Token-driven vertical or horizontal bar chart with optional average marker and hover/focus value tooltips.","variants":{"keys":["vertical","horizontal"],"default":"vertical"},"styling":{"baseClasses":"w-full h-[192px] p-0","baseColorHint":null,"perVariant":[{"key":"vertical","classes":"w-full h-[192px] p-0","colorHint":null},{"key":"horizontal","classes":"w-full h-[192px] p-0","colorHint":null}]},"slots":[],"sourceFile":"src/components/display/BarChart.tsx","specSource":"design/display.pen","docsUrl":"https://gunjo.dev/docs/components/bar-chart","stability":"experimental"},{"category":"display","name":"bottomActionBar","title":"BottomActionBar","description":"The sticky mobile action dock every transactional / real-time consumer screen ends with: a running summary on the left (合計金額 / 到着まで○分 / 選択件数) and the primary CTA on the right (呼ぶ / 支払う / 予約する), pinned to the bottom with a top border and safe-area-inset padding (home indicator). The bottom bookend to PageHeader (the top app bar) — for checkout, ride-hailing, booking, food-order, seat-select. children = the summary slot, actions = the CTA slot; set stack for a full-width CTA above the summary, maxWidth to centre on tablet. RSC-safe (no client deps).","variants":{"keys":["default"],"default":"default"},"styling":{"baseClasses":"w-full","baseColorHint":null,"perVariant":[{"key":"default","classes":"w-full","colorHint":null}]},"slots":[],"sourceFile":"src/components/display/BottomActionBar.tsx","specSource":"design/display.pen","docsUrl":"https://gunjo.dev/docs/components/bottom-action-bar","stability":"beta"},{"category":"display","name":"card","title":"Card","description":"Displays a card with header, content, and footer.","variants":{"keys":["default"],"default":"default"},"styling":{"baseClasses":"flex flex-col w-full rounded-lg border","baseColorHint":"fill=#FFFFFF | stroke=#e2e8f0@1px","perVariant":[{"key":"default","classes":"flex flex-col w-full rounded-lg border","colorHint":"fill=#FFFFFF | stroke=#e2e8f0@1px"}]},"slots":["cardHeader","cardContent","cardFooter"],"sourceFile":"src/components/display/Card.tsx","specSource":"design/display.pen","docsUrl":"https://gunjo.dev/docs/components/card","stability":"beta"},{"category":"display","name":"carousel","title":"Carousel","description":"Embla-powered slider with keyboard and arrow controls.","variants":{"keys":["default"],"default":"default"},"styling":{"baseClasses":"flex flex-col w-[640px]","baseColorHint":null,"perVariant":[{"key":"default","classes":"flex flex-col w-[640px]","colorHint":null}]},"slots":["carouselContent","carouselPrevButton","carouselNextButton"],"sourceFile":"src/components/display/Carousel.tsx","specSource":"design/display.pen","docsUrl":"https://gunjo.dev/docs/components/carousel","stability":"experimental"},{"category":"display","name":"chartLegend","title":"ChartLegend","description":"Legend rows for chart series, values, and token-driven markers.","variants":{"keys":["horizontal","vertical"],"default":"horizontal"},"styling":{"baseClasses":"inline-flex items-center w-full p-0 gap-2","baseColorHint":null,"perVariant":[{"key":"horizontal","classes":"inline-flex items-center w-full p-0 gap-2","colorHint":null},{"key":"vertical","classes":"inline-flex items-center w-full p-0 gap-2","colorHint":null}]},"slots":[],"sourceFile":"src/components/display/ChartLegend.tsx","specSource":"design/display.pen","docsUrl":"https://gunjo.dev/docs/components/chart-legend","stability":"experimental"},{"category":"display","name":"chatMessage","title":"ChatMessage","description":"Single chat transcript row for assistant, user, system, and typing states.","variants":{"keys":["assistant","user","system","typing"],"default":"assistant"},"styling":{"baseClasses":"inline-flex items-center w-full p-4 gap-4","baseColorHint":null,"perVariant":[{"key":"assistant","classes":"inline-flex items-center w-full p-4 gap-4","colorHint":null},{"key":"user","classes":"inline-flex items-center w-full p-4 gap-4","colorHint":null},{"key":"system","classes":"w-full p-4","colorHint":null},{"key":"typing","classes":"inline-flex items-center w-full p-4 gap-4","colorHint":null}]},"slots":[],"sourceFile":"src/components/display/ChatMessage.tsx","specSource":"design/display.pen","docsUrl":"https://gunjo.dev/docs/components/chat-message","stability":"experimental"},{"category":"display","name":"checkboxCard","title":"CheckboxCard","description":"Multi-select choice cards with independent checkbox semantics, square check indicators, rich card content slots, form values, and disabled-reason tooltips.","variants":{"keys":["default"],"default":"default"},"styling":{"baseClasses":"flex w-full p-4 rounded-lg border","baseColorHint":"fill=#ffffff | stroke=#0c0c12@1px","perVariant":[{"key":"default","classes":"flex w-full p-4 rounded-lg border","colorHint":"fill=#ffffff | stroke=#0c0c12@1px"}]},"slots":["NeTD1","B2L3y6"],"sourceFile":"src/components/display/CheckboxCard.tsx","specSource":"design/display.pen","docsUrl":"https://gunjo.dev/docs/components/checkbox-card","stability":"experimental"},{"category":"display","name":"checkList","title":"CheckList","description":"A checklist / confirmable list: rows of a leading checkbox + label + description with a trailing slot (status badge, action, amount), bordered and divider-separated, each checkbox carrying the row label as its accessible name. Rows with no checked render as plain display rows. For document checklists, required-step / associated-procedure lists, recall/return scope confirmation, batch-approval pick lists and any 'tick these, see their status' surface. (For single/multi selection with roving keyboard nav — inbox / master-detail — that's a separate ListBox primitive.)","variants":{"keys":["default"],"default":"default"},"styling":{"baseClasses":"w-full","baseColorHint":null,"perVariant":[{"key":"default","classes":"w-full","colorHint":null}]},"slots":[],"sourceFile":"src/components/display/CheckList.tsx","specSource":"design/display.pen","docsUrl":"https://gunjo.dev/docs/components/check-list","stability":"experimental"},{"category":"display","name":"choroplethMap","title":"ChoroplethMap","description":"HTML/CSS region density map for GeoJSON-style boundaries, markers, and ranked locations with hover/focus tooltips.","variants":{"keys":["default","compact"],"default":"default"},"styling":{"baseClasses":"w-full p-0","baseColorHint":null,"perVariant":[{"key":"default","classes":"w-full p-0","colorHint":null},{"key":"compact","classes":"w-full p-0","colorHint":null}]},"slots":[],"sourceFile":"src/components/display/ChoroplethMap.tsx","specSource":"design/display.pen","docsUrl":"https://gunjo.dev/docs/components/choropleth-map","stability":"experimental"},{"category":"display","name":"code","title":"Code","description":"Inline code style for monospaced text content.","variants":{"keys":[],"default":null},"styling":{"baseClasses":"","baseColorHint":null,"perVariant":[]},"slots":[],"sourceFile":"src/components/display/Code.tsx","specSource":"design/display.pen","docsUrl":"https://gunjo.dev/docs/components/code","stability":"experimental"},{"category":"display","name":"codeBlock","title":"CodeBlock","description":"Syntax-highlighted code block with optional filename and copy button.","variants":{"keys":[],"default":null},"styling":{"baseClasses":"","baseColorHint":null,"perVariant":[]},"slots":[],"sourceFile":"src/components/display/CodeBlock.tsx","specSource":"design/display.pen","docsUrl":"https://gunjo.dev/docs/components/code-block","stability":"experimental"},{"category":"display","name":"colorSwatch","title":"ColorSwatch","description":"Color preview chip with copyable hex/rgb value.","variants":{"keys":[],"default":null},"styling":{"baseClasses":"","baseColorHint":null,"perVariant":[]},"slots":[],"sourceFile":"src/components/display/ColorSwatch.tsx","specSource":"design/display.pen","docsUrl":"https://gunjo.dev/docs/components/color-swatch","stability":"experimental"},{"category":"display","name":"companyCell","title":"CompanyCell","description":"The organization / entity identity cell: a SQUARE logo tile (or an initial fallback) + name + a secondary line (業種 / 所在地 / 制度区分). The org analogue of PersonCell (a ROUND avatar + person name) — use this for companies, programs, vendors, accounts, any non-person entity, so a card or a MatchCard side isn't forced into a person's avatar/presence model. name + secondary?/logo?/size?. RSC-safe.","variants":{"keys":["default"],"default":"default"},"styling":{"baseClasses":"","baseColorHint":null,"perVariant":[{"key":"default","classes":"","colorHint":null}]},"slots":[],"sourceFile":"src/components/display/CompanyCell.tsx","specSource":"design/display.pen","docsUrl":"https://gunjo.dev/docs/components/company-cell","stability":"experimental"},{"category":"display","name":"concentricProgressCard","title":"Concentric Progress Card","description":"HTML/CSS card for storage, quota, and multi-ring progress widgets with selectable concentric rings, metrics, and hover/focus tooltips.","variants":{"keys":["default","compact"],"default":"default"},"styling":{"baseClasses":"w-full p-0","baseColorHint":null,"perVariant":[{"key":"default","classes":"w-full p-0","colorHint":null},{"key":"compact","classes":"w-full p-0","colorHint":null}]},"slots":[],"sourceFile":"src/components/display/ConcentricProgressCard.tsx","specSource":"design/display.pen","docsUrl":"https://gunjo.dev/docs/components/concentric-progress-card","stability":"experimental"},{"category":"display","name":"dataTable","title":"DataTable","description":"Table + sort + filter + pagination integrated. Wraps @tanstack/react-table.","variants":{"keys":[],"default":null},"styling":{"baseClasses":"","baseColorHint":null,"perVariant":[]},"slots":[],"sourceFile":"src/components/display/DataTable.tsx","specSource":"design/display.pen","docsUrl":"https://gunjo.dev/docs/components/data-table","stability":"beta"},{"category":"display","name":"delta","title":"Delta","description":"Inline signed-change atom: a value with a directional arrow, a sign-driven tone, and a screen-reader (or visible) label — for gain/loss, variance (差異), and cash over/short (過不足). Fits inside a table cell, unlike the card-shaped Statistic.","variants":{"keys":["default"],"default":"default"},"styling":{"baseClasses":"","baseColorHint":null,"perVariant":[{"key":"default","classes":"","colorHint":null}]},"slots":[],"sourceFile":"src/components/display/Delta.tsx","specSource":"design/display.pen","docsUrl":"https://gunjo.dev/docs/components/delta","stability":"beta"},{"category":"display","name":"desktopPageHeader","title":"DesktopPageHeader","description":"A dense per-screen title bar for desktop consoles, with optional eyebrow, subtitle, and trailing actions.","variants":{"keys":["default"],"default":"default"},"styling":{"baseClasses":"flex flex-row items-center w-full pt-0 pb-4 px-0 gap-6 border","baseColorHint":"fill=#ffffff | stroke=#e2e8f0@1px","perVariant":[{"key":"default","classes":"flex flex-row items-center w-full pt-0 pb-4 px-0 gap-6 border","colorHint":"fill=#ffffff | stroke=#e2e8f0@1px"}]},"slots":["KW6GQ","zJQ5E"],"sourceFile":"src/components/display/DesktopPageHeader.tsx","specSource":"design/display.pen","docsUrl":"https://gunjo.dev/docs/components/desktop-page-header","stability":"experimental"},{"category":"display","name":"distributionBar","title":"DistributionBar","description":"Stacked percentage distribution bar for segments, channels, and allocation data with hover/focus segment tooltips.","variants":{"keys":["default"],"default":"default"},"styling":{"baseClasses":"w-full h-9 p-0 rounded-full","baseColorHint":null,"perVariant":[{"key":"default","classes":"w-full h-9 p-0 rounded-full","colorHint":null}]},"slots":[],"sourceFile":"src/components/display/DistributionBar.tsx","specSource":"design/display.pen","docsUrl":"https://gunjo.dev/docs/components/distribution-bar","stability":"experimental"},{"category":"display","name":"docNote","title":"DocNote","description":"Supplemental note block for explanatory copy, references, and non-urgent documentation callouts.","variants":{"keys":["default","reference","note","warning","tip"],"default":"default"},"styling":{"baseClasses":"inline-flex items-center w-full py-3 px-4 gap-1 rounded-md","baseColorHint":"fill=#f1f5f9","perVariant":[{"key":"default","classes":"inline-flex items-center w-full py-3 px-4 gap-1 rounded-md","colorHint":"fill=#f1f5f9"},{"key":"reference","classes":"inline-flex items-center w-full py-3 px-4 gap-1 rounded-md","colorHint":"fill=#f8fafc"},{"key":"note","classes":"inline-flex items-center w-full py-3 px-4 gap-1 rounded-md border","colorHint":"fill=#eff6ff | stroke=#bfdbfe@1px"},{"key":"warning","classes":"inline-flex items-center w-full py-3 px-4 gap-1 rounded-md border","colorHint":"fill=#fef3c7 | stroke=#fcd34d@1px"},{"key":"tip","classes":"inline-flex items-center w-full py-3 px-4 gap-1 rounded-md border","colorHint":"fill=#f0fdf4 | stroke=#bbf7d0@1px"}]},"slots":[],"sourceFile":"src/components/display/DocNote.tsx","specSource":"design/display.pen","docsUrl":"https://gunjo.dev/docs/components/doc-note","stability":"experimental"},{"category":"display","name":"documentRow","title":"DocumentRow","description":"The downloadable document / file row: a leading control slot (a Checkbox for bulk-select), a file-type icon, the document name + meta (format / size / 発行日), and a trailing INDEPENDENT action button (download). The spine of every 帳票 / 明細 / 書類 / 添付 / download surface. Unlike ListCard (whose onSelect makes the WHOLE card one button, so a nested download button is invalid HTML), DocumentRow keeps MULTIPLE independent hit targets — select, open-to-preview (onOpen), and the trailing download action. Group rows with SectionList (by year / type) for headings + subtotals. title + description?/meta?/icon?/control?/status?/actions?/onOpen?. RSC-safe except the opt-in onOpen / action handlers.","variants":{"keys":["default"],"default":"default"},"styling":{"baseClasses":"w-full","baseColorHint":null,"perVariant":[{"key":"default","classes":"w-full","colorHint":null}]},"slots":[],"sourceFile":"src/components/display/DocumentRow.tsx","specSource":"design/display.pen","docsUrl":"https://gunjo.dev/docs/components/document-row","stability":"experimental"},{"category":"display","name":"donutChart","title":"DonutChart","description":"HTML/CSS donut chart for proportional segments with optional center labels and pointer-aware segment tooltips.","variants":{"keys":["default","compact"],"default":"default"},"styling":{"baseClasses":"w-full p-0 rounded-full","baseColorHint":null,"perVariant":[{"key":"default","classes":"w-full p-0 rounded-full","colorHint":null},{"key":"compact","classes":"w-full p-0 rounded-full","colorHint":null}]},"slots":[],"sourceFile":"src/components/display/DonutChart.tsx","specSource":"design/display.pen","docsUrl":"https://gunjo.dev/docs/components/donut-chart","stability":"experimental"},{"category":"display","name":"editableDataTable","title":"EditableDataTable","description":"Editable line-item grid: rows of consumer-rendered editor cells with add/remove row, a totals/footer row, per-cell accessible labels, and a desktop table that stacks into mobile cards. For invoices, journals, estimates, and timesheets.","variants":{"keys":["default","compact"],"default":"default"},"styling":{"baseClasses":"w-full","baseColorHint":null,"perVariant":[{"key":"default","classes":"w-full","colorHint":null},{"key":"compact","classes":"w-full","colorHint":null}]},"slots":[],"sourceFile":"src/components/display/EditableDataTable.tsx","specSource":"design/display.pen","docsUrl":"https://gunjo.dev/docs/components/editable-data-table","stability":"beta"},{"category":"display","name":"emptyState","title":"EmptyState","description":"Placeholder for lists / panels with no data, with optional CTA.","variants":{"keys":[],"default":null},"styling":{"baseClasses":"","baseColorHint":null,"perVariant":[]},"slots":[],"sourceFile":"src/components/display/EmptyState.tsx","specSource":"design/display.pen","docsUrl":"https://gunjo.dev/docs/components/empty-state","stability":"beta"},{"category":"display","name":"eventCalendar","title":"EventCalendar","description":"Month calendar with events: a 週×曜日 day-cell grid for a month with events placed as chips on their date (capped per day with a '＋N' overflow), today marked, out-of-month days de-emphasised, role=grid semantics (weekday columnheaders, day gridcells with a composed accessible name) and roving-tabindex keyboard nav (arrows ±1 day / ±1 week, Home/End, Enter to select). Owns the month math (pass month + events); today is injectable (SSR-safe). For editorial / content calendars, schedules, bookings and any events-on-dates view.","variants":{"keys":["default"],"default":"default"},"styling":{"baseClasses":"w-full","baseColorHint":null,"perVariant":[{"key":"default","classes":"w-full","colorHint":null}]},"slots":[],"sourceFile":"src/components/display/EventCalendar.tsx","specSource":"design/display.pen","docsUrl":"https://gunjo.dev/docs/components/event-calendar","stability":"experimental"},{"category":"display","name":"expiryBadge","title":"ExpiryBadge","description":"The date-vs-deadline currency indicator: classifies an expiry date against today into 有効 / 期限間近 / 失効 / 未登録 and shows a colour-safe state chip (icon + label, never colour alone), the date, and a 残N日 / N日超過 readout. ExpiryState is deliberately a domain-state API, not a tone API; its internal canonical mapping is valid→success, expiring→warning, expired→destructive, missing→muted. The date-domain sibling of Meter (value vs a capacity) and ReferenceValue (value vs a numeric range) — this is value vs a DEADLINE. For licence / 資格 / 適性診断 / 健診 / 車検 / 保険 / 認証 / 点検 currency across crew, asset and compliance consoles. Pairs with the pure classifyExpiry() helper (value → {state, days}), mirroring how ReferenceValue pairs with flagValue(). RSC-safe; pass today in for SSR determinism (defaults to new Date()).","variants":{"keys":["default"],"default":"default"},"styling":{"baseClasses":"","baseColorHint":null,"perVariant":[{"key":"default","classes":"","colorHint":null}]},"slots":[],"sourceFile":"src/components/display/ExpiryBadge.tsx","specSource":"design/display.pen","docsUrl":"https://gunjo.dev/docs/components/expiry-badge","stability":"experimental"},{"category":"display","name":"fileTree","title":"FileTree","description":"File and folder tree composition with metadata, row actions, and single or multiple selection.","variants":{"keys":["single","multiple","actions"],"default":"single"},"styling":{"baseClasses":"w-full p-0","baseColorHint":null,"perVariant":[{"key":"single","classes":"w-full p-0","colorHint":null},{"key":"multiple","classes":"w-full p-0","colorHint":null},{"key":"actions","classes":"w-full p-0","colorHint":null}]},"slots":[],"sourceFile":"src/components/display/FileTree.tsx","specSource":"design/display.pen","docsUrl":"https://gunjo.dev/docs/components/file-tree","stability":"experimental"},{"category":"display","name":"filterChips","title":"FilterChips","description":"The horizontally-scrollable, single-select category chip bar: the navigation every consumer place / list finder opens with (空港・駅の施設, 食べログ, retail, transit, food delivery). A scroll-snapping row of pill chips (icon + label + optional count) that does NOT center-wrap on a phone, with a fully-filled active chip, roving tabindex + arrow keys, and a hidden scrollbar. value + onValueChange single-select. For 2–3 equal-width segments use ToggleGroup; for a faceted popover filter use FilterButton; this is the many-category scannable rail.","variants":{"keys":["default"],"default":"default"},"styling":{"baseClasses":"w-full","baseColorHint":null,"perVariant":[{"key":"default","classes":"w-full","colorHint":null}]},"slots":[],"sourceFile":"src/components/display/FilterChips.tsx","specSource":"design/display.pen","docsUrl":"https://gunjo.dev/docs/components/filter-chips","stability":"beta"},{"category":"display","name":"gallery","title":"Gallery","description":"Main image plus a selectable thumbnail strip with click and keyboard swap, for product detail and media galleries.","variants":{"keys":["bottom","start"],"default":"bottom"},"styling":{"baseClasses":"w-full","baseColorHint":null,"perVariant":[{"key":"bottom","classes":"w-full","colorHint":null},{"key":"start","classes":"w-full","colorHint":null}]},"slots":[],"sourceFile":"src/components/display/Gallery.tsx","specSource":"design/display.pen","docsUrl":"https://gunjo.dev/docs/components/gallery","stability":"experimental"},{"category":"display","name":"gantt","title":"Gantt","description":"Gantt / resource timeline: resource rows × a horizontal time axis with bars positioned by start/end and lane-packed within a row so overlapping bars stack instead of covering each other. A bar can carry internal segments[] (sub-spans tinted per segment — an aircraft rotation 便→折返し→便→整備, a crew duty 出区→乗務→入区, a shop visit 入場→検修→出場), with gaps showing as the bar's track. Day-column gridlines + date headers, a sticky row-label gutter, an optional today line, and a contained horizontal scroll. Owns the time math (pass startDate/endDate + rows + items); today is injectable (SSR-safe). Bars are focusable buttons with a composed accessible name. For project schedules, production lines, room/equipment timelines, crew/aircraft rotations, delivery/route plans and any rows-over-time view.","variants":{"keys":["default"],"default":"default"},"styling":{"baseClasses":"w-full","baseColorHint":null,"perVariant":[{"key":"default","classes":"w-full","colorHint":null}]},"slots":[],"sourceFile":"src/components/display/Gantt.tsx","specSource":"design/display.pen","docsUrl":"https://gunjo.dev/docs/components/gantt","stability":"experimental"},{"category":"display","name":"gaugeChart","title":"GaugeChart","description":"HTML/CSS semi-circle gauge for scores, progress, and capacity readings with hover/focus value tooltip.","variants":{"keys":["default","compact"],"default":"default"},"styling":{"baseClasses":"w-full h-[144px] p-0","baseColorHint":null,"perVariant":[{"key":"default","classes":"w-full h-[144px] p-0","colorHint":null},{"key":"compact","classes":"w-full h-[112px] p-0","colorHint":null}]},"slots":[],"sourceFile":"src/components/display/GaugeChart.tsx","specSource":"design/display.pen","docsUrl":"https://gunjo.dev/docs/components/gauge-chart","stability":"experimental"},{"category":"display","name":"heatmapChart","title":"HeatmapChart","description":"HTML/CSS density heatmap for day, time, and cohort intensity patterns with hover/focus cell tooltips.","variants":{"keys":["default","compact"],"default":"default"},"styling":{"baseClasses":"w-full p-0","baseColorHint":null,"perVariant":[{"key":"default","classes":"w-full p-0","colorHint":null},{"key":"compact","classes":"w-full p-0","colorHint":null}]},"slots":[],"sourceFile":"src/components/display/HeatmapChart.tsx","specSource":"design/display.pen","docsUrl":"https://gunjo.dev/docs/components/heatmap-chart","stability":"experimental"},{"category":"display","name":"icon","title":"Icon","description":"Normalizes icon size, stroke, and accessibility behavior across GunjoUI.","variants":{"keys":["sm","xs","md","lg","xl"],"default":"sm"},"styling":{"baseClasses":"w-4 h-4 p-0","baseColorHint":"fill=#64748b","perVariant":[{"key":"sm","classes":"w-4 h-4 p-0","colorHint":"fill=#64748b"},{"key":"xs","classes":"w-3 h-3 p-0","colorHint":"fill=#64748b"},{"key":"md","classes":"w-5 h-5 p-0","colorHint":"fill=#64748b"},{"key":"lg","classes":"w-6 h-6 p-0","colorHint":"fill=#64748b"},{"key":"xl","classes":"w-8 h-8 p-0","colorHint":"fill=#64748b"}]},"slots":[],"sourceFile":"src/components/display/Icon.tsx","specSource":"design/display.pen","docsUrl":"https://gunjo.dev/docs/components/icon","stability":"beta"},{"category":"display","name":"imagePreview","title":"ImagePreview","description":"Framed image preview surface for asset cards, pickers, and media inspection.","variants":{"keys":["default","contain","empty"],"default":"default"},"styling":{"baseClasses":"w-full p-0 rounded-lg","baseColorHint":"fill=#f8fafc","perVariant":[{"key":"default","classes":"w-full p-0 rounded-lg","colorHint":"fill=#f8fafc"},{"key":"contain","classes":"w-full p-0 rounded-lg","colorHint":"fill=#f8fafc"},{"key":"empty","classes":"w-full p-0 rounded-lg","colorHint":"fill=#f8fafc"}]},"slots":[],"sourceFile":"src/components/display/ImagePreview.tsx","specSource":"design/display.pen","docsUrl":"https://gunjo.dev/docs/components/image-preview","stability":"experimental"},{"category":"display","name":"img","title":"Img","description":"An enhanced image component with loading skeleton and error fallback.","variants":{"keys":["loading","loaded","error"],"default":"loading"},"styling":{"baseClasses":"w-full h-fit rounded-lg","baseColorHint":"fill=#f1f5f9","perVariant":[{"key":"loading","classes":"w-full h-fit rounded-lg","colorHint":"fill=#f1f5f9"},{"key":"loaded","classes":"w-full h-fit rounded-lg","colorHint":null},{"key":"error","classes":"inline-flex items-center w-full gap-2 rounded-lg text-xs font-normal","colorHint":"fill=#f1f5f9 | text=#94a3b8"}]},"slots":[],"sourceFile":"src/components/display/Img.tsx","specSource":"design/display.pen","docsUrl":"https://gunjo.dev/docs/components/img","stability":"experimental"},{"category":"display","name":"itinerary","title":"Itinerary","description":"The day-grouped, mixed-kind trip/journey timeline: a vertical sequence of items (flight / hotel / activity / transit leg …), each with a per-kind icon+tone marker, a time, a title + secondary, an optional rich content slot, and an opt-in tappable row (≥44px + chevron). Group by day (days[] with day headers + place sublabels) or pass flat items[]. The traveller-facing trip-plan / 乗換経路 / journey view — richer than Timeline (per-item kind + content + tap) and the right call over RouteStops, whose status/予実 (未配/配送中/遅れ) vocabulary is delivery-locked and wrong for a forward plan. RSC-safe except the opt-in onSelect.","variants":{"keys":["default"],"default":"default"},"styling":{"baseClasses":"w-full","baseColorHint":null,"perVariant":[{"key":"default","classes":"w-full","colorHint":null}]},"slots":[],"sourceFile":"src/components/display/Itinerary.tsx","specSource":"design/display.pen","docsUrl":"https://gunjo.dev/docs/components/itinerary","stability":"experimental"},{"category":"display","name":"kanbanBoard","title":"KanbanBoard","description":"A kanban / status board: ordered columns (lanes) of cards, grouped from a flat items list by getColumnId, with per-column count badges, a card render-prop, optional activatable cards, empty-column placeholders, header accent dots, and a contained horizontal scroll that doesn't push the page on mobile. Each column is a labelled region and cards are real buttons when selectable (keyboard-operable). Drag-and-drop is bring-your-own. For editorial boards, CRM pipelines, support queues, task boards and any column-of-cards workflow.","variants":{"keys":["default"],"default":"default"},"styling":{"baseClasses":"w-full","baseColorHint":null,"perVariant":[{"key":"default","classes":"w-full","colorHint":null}]},"slots":[],"sourceFile":"src/components/display/KanbanBoard.tsx","specSource":"design/display.pen","docsUrl":"https://gunjo.dev/docs/components/kanban-board","stability":"experimental"},{"category":"display","name":"kbd","title":"Kbd","description":"Displays a keyboard shortcut key.","variants":{"keys":["key"],"default":"key"},"styling":{"baseClasses":"h-5 p-1 rounded border","baseColorHint":"fill=#f1f5f9 | stroke=#e2e8f0@1px","perVariant":[{"key":"key","classes":"h-5 p-1 rounded border","colorHint":"fill=#f1f5f9 | stroke=#e2e8f0@1px"}]},"slots":[],"sourceFile":"src/components/display/Kbd.tsx","specSource":"design/display.pen","docsUrl":"https://gunjo.dev/docs/components/kbd","stability":"experimental"},{"category":"display","name":"labeledDonutCard","title":"Labeled Donut Card","description":"HTML/CSS donut chart card for segment comparison with central summary, external callout rows, and hover/focus segment tooltips.","variants":{"keys":["default","compact"],"default":"default"},"styling":{"baseClasses":"w-full p-0","baseColorHint":null,"perVariant":[{"key":"default","classes":"w-full p-0","colorHint":null},{"key":"compact","classes":"w-full p-0","colorHint":null}]},"slots":[],"sourceFile":"src/components/display/LabeledDonutCard.tsx","specSource":"design/display.pen","docsUrl":"https://gunjo.dev/docs/components/labeled-donut-card","stability":"experimental"},{"category":"display","name":"leaderboard","title":"Leaderboard","description":"The ranking / leaderboard list: a PRE-ORDERED list of entities, each with a numbered rank chip, a label (+ sublabel), an optional value bar normalised against the max, and an optional Delta for period-over-period change. The caller orders the items (best-first for a top-N 売上/人気, worst-first for 'worst performers / 要対応' — 事故率の高い営業所, 赤字系統, 苦情多発), so rank = array position is an explicit caller decision; the component never re-sorts. The ranked-list primitive a BarChart and StatGroup can't be — BarChart is a chart with no rank/order semantics, StatGroup is an UNORDERED KPI cluster. For best/worst dashboards across sales, ops and safety. Use deltaTones={{positive:'destructive',negative:'success'}} for 'up is bad' rankings (事故率/コスト/苦情). items[] of {id,label,value,sublabel?,valueLabel?,fraction?,delta?,tone?,icon?,trailing?,onSelect?}. RSC-safe except the opt-in onSelect.","variants":{"keys":["default"],"default":"default"},"styling":{"baseClasses":"w-full","baseColorHint":null,"perVariant":[{"key":"default","classes":"w-full","colorHint":null}]},"slots":[],"sourceFile":"src/components/display/Leaderboard.tsx","specSource":"design/display.pen","docsUrl":"https://gunjo.dev/docs/components/leaderboard","stability":"experimental"},{"category":"display","name":"limitMonitor","title":"LimitMonitor","description":"Value against a NAMED regulatory limit (soft + optional hard) with near/over/critical states and a bar that shows how close — or how far past — the value sits, with the limit drawn as a line. The 'value vs a named limit' sibling of ExpiryBadge (value vs a deadline), ReferenceValue (value vs a range) and Meter (value vs a capacity): limits are in the value's OWN units and the breach tone is DERIVED from them (unlike Meter's fraction-of-max thresholds + reference-only target which does not drive tone). For 改善基準告示 (拘束時間/連続運転/休息期間), SLA budgets, quotas, 過積載, 残業, rate limits. direction=\"floor\" for must-stay-above limits (休息期間). Pairs with the pure classifyLimit() helper (value → {state, over}), mirroring ExpiryBadge↔classifyExpiry and ReferenceValue↔flagValue. RSC-safe.","variants":{"keys":["default"],"default":"default"},"styling":{"baseClasses":"w-full","baseColorHint":null,"perVariant":[{"key":"default","classes":"w-full","colorHint":null}]},"slots":[],"sourceFile":"src/components/display/LimitMonitor.tsx","specSource":"design/display.pen","docsUrl":"https://gunjo.dev/docs/components/limit-monitor","stability":"experimental"},{"category":"display","name":"lineageGraph","title":"LineageGraph","description":"Lineage / dependency graph: a layered, directed-acyclic node-link graph that handles multi-parent and multi-child edges (the fan-in / fan-out a tree can't draw). Nodes are auto-assigned to layers by longest-path depth and laid out along a flow axis (horizontal or vertical); edges are drawn as SVG connectors with arrowheads. Nodes are focusable buttons whose accessible name names their upstream/downstream neighbours. For lot genealogy / traceability (recall blast-radius), data lineage, build/dependency graphs, ETL pipelines and approval routing with joins.","variants":{"keys":["default"],"default":"default"},"styling":{"baseClasses":"w-full","baseColorHint":null,"perVariant":[{"key":"default","classes":"w-full","colorHint":null}]},"slots":[],"sourceFile":"src/components/display/LineageGraph.tsx","specSource":"design/display.pen","docsUrl":"https://gunjo.dev/docs/components/lineage-graph","stability":"experimental"},{"category":"display","name":"lineChart","title":"LineChart","description":"HTML/CSS multi-series line or area chart for time-series comparison with reference lines, legends, and hover/focus point tooltips.","variants":{"keys":["line","area"],"default":"line"},"styling":{"baseClasses":"w-full h-[260px] p-0","baseColorHint":null,"perVariant":[{"key":"line","classes":"w-full h-[260px] p-0","colorHint":null},{"key":"area","classes":"w-full h-[260px] p-0","colorHint":null}]},"slots":[],"sourceFile":"src/components/display/LineChart.tsx","specSource":"design/display.pen","docsUrl":"https://gunjo.dev/docs/components/line-chart","stability":"beta"},{"category":"display","name":"lineChip","title":"LineChip","description":"The transit line / route identity chip: a small pill showing a line/route number (渋66 / 東98 / JY / 丸ノ内線) in the line's official brand colour, with auto-contrast text (black/white by luminance) so it stays readable on any hue. The label carries the meaning, so it works colour-blind / in mono — colour is decoration. The IDENTITY counterpart to Badge (a status/semantic tone): this keys a chip to a transit line. For approach lists, route candidates, leg details, run-diagram labels — rail / bus / subway. label + optional color (hex) + optional icon; omit color for a neutral chip. RSC-safe.","variants":{"keys":["default"],"default":"default"},"styling":{"baseClasses":"","baseColorHint":null,"perVariant":[{"key":"default","classes":"","colorHint":null}]},"slots":[],"sourceFile":"src/components/display/LineChip.tsx","specSource":"design/display.pen","docsUrl":"https://gunjo.dev/docs/components/line-chip","stability":"experimental"},{"category":"display","name":"list","title":"List","description":"A semantic list component with customizable markers and spacing.","variants":{"keys":["dot","check","circle"],"default":"dot"},"styling":{"baseClasses":"flex flex-row items-center gap-2","baseColorHint":null,"perVariant":[{"key":"dot","classes":"flex flex-row items-center gap-2","colorHint":null},{"key":"check","classes":"flex flex-row items-center gap-2","colorHint":null},{"key":"circle","classes":"flex flex-row items-center gap-2","colorHint":null}]},"slots":["listDotIcon","listDotText"],"sourceFile":"src/components/display/List.tsx","specSource":"design/display.pen","docsUrl":"https://gunjo.dev/docs/components/list","stability":"experimental"},{"category":"display","name":"listCard","title":"ListCard","description":"The tappable list entry: one item in a scannable, mobile-dense list — a leading accessory (icon / avatar / colour dot / rank / line chip), a title + secondary, optional tag chips, a right-aligned status pill and meta (price / time / count / timestamp), and a trailing chevron. The result-card / status-row primitive every consumer 'list of things' screen opens with — search results, route / product / listing comparisons, status lists (運行状況・在庫・端末), order/incident queues. Tappable rows (onSelect) are a real ≥44px button with hover/focus/selected states; status never rides on colour alone (Badge and status text carry meaning; severity only adds an optional semantic border and subtle background). For the KPI strip use StatGroup; for a severity-triaged alert worklist use ActionQueue; for a money breakdown use AmountBreakdown. RSC-safe by default — onSelect is the only function prop and is opt-in.","variants":{"keys":["default"],"default":"default"},"styling":{"baseClasses":"w-full","baseColorHint":null,"perVariant":[{"key":"default","classes":"w-full","colorHint":null}]},"slots":[],"sourceFile":"src/components/display/ListCard.tsx","specSource":"design/display.pen","docsUrl":"https://gunjo.dev/docs/components/list-card","stability":"beta"},{"category":"display","name":"liveBadge","title":"LiveBadge","description":"The small bordered pill that says 'this is the current value', with a dot that pulses slowly to show something is still arriving. When the value is no longer current the badge steps aside and states WHEN the value is from instead (`detached`) — and renders nothing at all when it has not been told. For monitoring boards, streams, match commentary, trading screens and sensor readouts: anywhere a number could be either live or a snapshot and the reader cannot tell by looking. Holds NO clock and compares nothing — `live` is the caller's decision (the TimeTransport rule); TimeTransport renders its own live state with this badge. The state is never carried by the dot or the colour: the badge always has a word on it (default `LIVE`), and the detached form replaces that word with the 'when'. The dot does not pulse under prefers-reduced-motion: reduce. Deliberately NOT a live region — `role='status'` here would interrupt a screen reader on every reconnection, so the caller adds it on the rare screen where the change is the news. Composed from Badge (success / warning tones, same size scale). Distinct from Badge (a state that is not about freshness), ExpiryBadge (a deadline, not a live edge) and TimeTransport (which also MOVES the value).","variants":{"keys":["default"],"default":"default"},"styling":{"baseClasses":"","baseColorHint":null,"perVariant":[{"key":"default","classes":"","colorHint":null}]},"slots":[],"sourceFile":"src/components/display/LiveBadge.tsx","specSource":"design/display.pen","docsUrl":"https://gunjo.dev/docs/components/live-badge","stability":"experimental"},{"category":"display","name":"loyaltySummaryCard","title":"LoyaltySummaryCard","description":"The points/balance/tier hero every consumer loyalty screen opens with: a prominent balance, a tier/rank badge, optional secondary values (IC残高/当年実績), a higher-is-better progress-to-next-tier with a remaining label (『プラチナまであと ¥13,800』 — never auto-reds like a capacity Meter), an expiry-warning slot and a primary action. The brand tone is a filled gradient surface so the hero has shine without reaching for arbitrary brand-token classes. For airline マイル, 鉄道 IC/ポイント, retail/EC rewards, membership tiers. For the back-office KPI strip use StatGroup; for a money breakdown use AmountBreakdown; for the points/coupon/history list under the hero use ListCard. Presentational (the action slot owns interactivity) — RSC-safe.","variants":{"keys":["default"],"default":"default"},"styling":{"baseClasses":"w-full","baseColorHint":null,"perVariant":[{"key":"default","classes":"w-full","colorHint":null}]},"slots":[],"sourceFile":"src/components/display/LoyaltySummaryCard.tsx","specSource":"design/display.pen","docsUrl":"https://gunjo.dev/docs/components/loyalty-summary-card","stability":"experimental"},{"category":"display","name":"mapStatusCorner","title":"MapStatusCorner","description":"A few short lines in the top-right of a map that say what the reader is looking at: the viewpoint, day or night, which cloud frame, where the terrain comes from, the rain time. On a narrow screen it shares the top edge with the words on the left (`lead`, e.g. the view name and a LiveBadge). `lead` floats left and each line is one unbreakable run, so a line that does not fit beside `lead` moves below it instead of breaking a word: only the first line or two sit beside `lead`, the rest get the full width (a two-column flex row pushed lines down and clipped the last character of a word at 320px). `startInset` keeps room free on the left under `lead` for a compass. Words use the canvas type tier (text-canvas-2xs, /docs/exceptions) with a halo in the page colour, over an optional top-down scrim. The whole corner ignores the pointer so the map still drags. A labelled list for assistive tech. Placed by the caller (absolute inset-x-0 top-0). Distinct from StatusBar (an app status strip on the page, not on imagery) and LiveBadge (one 'this is live' pill; it goes inside `lead`).","variants":{"keys":["default"],"default":"default"},"styling":{"baseClasses":"","baseColorHint":null,"perVariant":[{"key":"default","classes":"","colorHint":null}]},"slots":[],"sourceFile":"src/components/display/MapStatusCorner.tsx","specSource":"design/display.pen","docsUrl":"https://gunjo.dev/docs/components/map-status-corner","stability":"experimental"},{"category":"display","name":"markdownRenderer","title":"MarkdownRenderer","description":"Markdown to HTML rendering with GFM (tables, task lists, code).","variants":{"keys":[],"default":null},"styling":{"baseClasses":"","baseColorHint":null,"perVariant":[]},"slots":[],"sourceFile":"src/components/display/MarkdownRenderer.tsx","specSource":"design/display.pen","docsUrl":"https://gunjo.dev/docs/components/markdown-renderer","stability":"experimental"},{"category":"display","name":"matchCard","title":"MatchCard","description":"The two-sided pairing detail: a LEFT entity and a RIGHT entity side by side with a center match score, plus a factor-by-factor breakdown and actions. The heart of every matching / recommendation / deal-pairing / compare console — 求貨求車 (荷物×空車), M&A (売り手×買い手), 補助金 (自社×制度), candidate×job, buyer×seller. ENTITY-AGNOSTIC: left and right are arbitrary identity nodes (pair with CompanyCell / PersonCell / anything), and the two sides may be DIFFERENT kinds (a company and a program). Distinct from RelationshipRow, which hardcodes two PersonCells (person⟷person) and has no score/factor region. left + right + score? + factors[] ({label,value,tone?,detail?}) + actions. RSC-safe except opt-in handlers in the slots.","variants":{"keys":["default"],"default":"default"},"styling":{"baseClasses":"w-full","baseColorHint":null,"perVariant":[{"key":"default","classes":"w-full","colorHint":null}]},"slots":[],"sourceFile":"src/components/display/MatchCard.tsx","specSource":"design/display.pen","docsUrl":"https://gunjo.dev/docs/components/match-card","stability":"experimental"},{"category":"display","name":"metadataList","title":"MetadataList","description":"Definition-list style metadata rows for inspectors, file details, and compact property summaries.","variants":{"keys":["default","compact"],"default":"default"},"styling":{"baseClasses":"w-full p-0","baseColorHint":null,"perVariant":[{"key":"default","classes":"w-full p-0","colorHint":null},{"key":"compact","classes":"w-full p-0","colorHint":null}]},"slots":[],"sourceFile":"src/components/display/MetadataList.tsx","specSource":"design/display.pen","docsUrl":"https://gunjo.dev/docs/components/metadata-list","stability":"beta"},{"category":"display","name":"meter","title":"Meter","description":"Capacity / utilisation meter (role=meter): a value-against-max bar whose tone is derived from thresholds (near-full → warning, over → destructive), with an optional incoming overlay to preview 'after this change' and a compact inline size for table cells. The tone contract accepts the complete canonical SemanticTone scale directly; default normalizes to the muted visual state while toMeterTone remains a compatible boundary helper. For warehouse fill, truck load, storage usage and quota — or set direction='higher-is-better' with a target marker for occupancy / utilisation / SLA / yield goals, or direction='fill-is-good' (no target) for coverage / fulfillment. Pass formatValue to format the visible readout (e.g. grouped JPY).","variants":{"keys":["default"],"default":"default"},"styling":{"baseClasses":"w-full","baseColorHint":null,"perVariant":[{"key":"default","classes":"w-full","colorHint":null}]},"slots":[],"sourceFile":"src/components/display/Meter.tsx","specSource":"design/display.pen","docsUrl":"https://gunjo.dev/docs/components/meter","stability":"beta"},{"category":"display","name":"miniDistributionBarCard","title":"Mini Distribution Bar Card","description":"HTML/CSS compact distribution card for product categories, capacity, and utilization widgets with dense ticks, selected segment details, and hover/focus tooltips.","variants":{"keys":["default","compact"],"default":"default"},"styling":{"baseClasses":"w-full p-0","baseColorHint":null,"perVariant":[{"key":"default","classes":"w-full p-0","colorHint":null},{"key":"compact","classes":"w-full p-0","colorHint":null}]},"slots":[],"sourceFile":"src/components/display/MiniDistributionBarCard.tsx","specSource":"design/display.pen","docsUrl":"https://gunjo.dev/docs/components/mini-distribution-bar-card","stability":"experimental"},{"category":"display","name":"navRow","title":"NavRow","description":"The flush settings / nav-list row: a leading icon, a label (+ description), a right-aligned current value, and a trailing chevron — the `[icon] label … value [›]` row every settings / account / マイページ / menu screen is built from. With onSelect the whole row is a NAVIGATION / disclosure button (chevron default, aria-haspopup=\"dialog\" via opensDialog) — deliberately NOT aria-pressed: a row that opens a detail is navigation, not a toggle (the a11y trap of using ListCard.onSelect for settings rows). Without onSelect it is a static control row — put a Switch / Badge in trailing. Group rows in SettingGroup for the rounded-container + hairline-divider look. Distinct from ListCard (a bordered card with aria-pressed selection). RSC-safe except the opt-in onSelect.","variants":{"keys":["default"],"default":"default"},"styling":{"baseClasses":"w-full","baseColorHint":null,"perVariant":[{"key":"default","classes":"w-full","colorHint":null}]},"slots":[],"sourceFile":"src/components/display/NavRow.tsx","specSource":"design/display.pen","docsUrl":"https://gunjo.dev/docs/components/nav-row","stability":"experimental"},{"category":"display","name":"occupancyMeter","title":"OccupancyMeter","description":"A labeled occupancy and capacity gauge with a neutral fill, formatted readout, and optional target marker.","variants":{"keys":["default"],"default":"default"},"styling":{"baseClasses":"flex flex-col items-center w-full gap-2","baseColorHint":null,"perVariant":[{"key":"default","classes":"flex flex-col items-center w-full gap-2","colorHint":null}]},"slots":["ibxXb","KQNAO"],"sourceFile":"src/components/display/OccupancyMeter.tsx","specSource":"design/display.pen","docsUrl":"https://gunjo.dev/docs/components/occupancy-meter","stability":"experimental"},{"category":"display","name":"originDestination","title":"OriginDestination","description":"The A→B route header: 出発 → 到着 (東京 → 新大阪 / HND → CTS / POL → POD / 新宿 → 大阪), each endpoint a label + optional sub (code / time / platform), joined by an arrow (or a connector slot for a duration / mode icon), with an optional swap button (出発⇄到着) and via stops. The compact identity of every transit / freight SEARCH & RESULT screen — a HORIZONTAL A→B across the top, NOT a vertical sequence (that is RouteStops / Itinerary, which go DOWN the page). `inline` gives the small single-line variant for a result row (発→着 times). from + to (+ via[]) of {label, sub?}; connector, onSwap, inline, label. RSC-safe except the opt-in onSwap.","variants":{"keys":["default"],"default":"default"},"styling":{"baseClasses":"w-full","baseColorHint":null,"perVariant":[{"key":"default","classes":"w-full","colorHint":null}]},"slots":[],"sourceFile":"src/components/display/OriginDestination.tsx","specSource":"design/display.pen","docsUrl":"https://gunjo.dev/docs/components/origin-destination","stability":"experimental"},{"category":"display","name":"pageHeader","title":"PageHeader","description":"The mobile app bar / page header every consumer phone screen opens with: a leading back button, a title (+ optional subtitle), and a trailing action slot, sticky to the top with a header landmark, a bottom border and safe-area-inset padding (notch). Touch targets are ≥44px; title align left (default) or center (iOS-style). The kit's Header / AppRail are desktop app/docs chrome — this is the lightweight per-page bar for a phone (booking flows, finders, trackers, detail pages). Pass onBack for the ≥44px back button, or override the leading slot; actions holds close/refresh/menu buttons.","variants":{"keys":["default"],"default":"default"},"styling":{"baseClasses":"w-full","baseColorHint":null,"perVariant":[{"key":"default","classes":"w-full","colorHint":null}]},"slots":[],"sourceFile":"src/components/display/PageHeader.tsx","specSource":"design/display.pen","docsUrl":"https://gunjo.dev/docs/components/page-header","stability":"beta"},{"category":"display","name":"paretoChart","title":"ParetoChart","description":"Pareto chart: descending value bars (HTML/CSS, left value axis) overlaid with a cumulative-% line (SVG) on a right 0–100% axis and a 'vital few' threshold line (80% by default), with focusable points and an accessible per-category summary. For defect / downtime / cause analysis and any 'which few drive most of the total' breakdown.","variants":{"keys":["default"],"default":"default"},"styling":{"baseClasses":"w-full h-[220px] p-0","baseColorHint":null,"perVariant":[{"key":"default","classes":"w-full h-[220px] p-0","colorHint":null}]},"slots":[],"sourceFile":"src/components/display/ParetoChart.tsx","specSource":"design/display.pen","docsUrl":"https://gunjo.dev/docs/components/pareto-chart","stability":"experimental"},{"category":"display","name":"personCell","title":"PersonCell","description":"The atomic identity cell: an avatar paired with a name plus secondary/tertiary lines (role / department / email), an optional presence dot and a trailing slot (status badge, chevron, count, actions). Fallback initials are derived from the name (Japanese family-name aware) when no image is given; sm/md/lg sizes; everything truncates so it fits a table cell. The 'who is this person' unit repeated across directories, table rows, assignee pickers, comment attributions, approver/reviewer rows and detail panels. Presentational by default — let an interactive row (DataTable onRowClick, a wrapping link) own activation rather than nesting a button.","variants":{"keys":["default"],"default":"default"},"styling":{"baseClasses":"w-full","baseColorHint":null,"perVariant":[{"key":"default","classes":"w-full","colorHint":null}]},"slots":[],"sourceFile":"src/components/display/PersonCell.tsx","specSource":"design/display.pen","docsUrl":"https://gunjo.dev/docs/components/person-cell","stability":"beta"},{"category":"display","name":"pieChart","title":"PieChart","description":"HTML/CSS pie chart for proportional segment comparisons with pointer-aware segment tooltips.","variants":{"keys":["default","compact"],"default":"default"},"styling":{"baseClasses":"w-full p-0 rounded-full","baseColorHint":null,"perVariant":[{"key":"default","classes":"w-full p-0 rounded-full","colorHint":null},{"key":"compact","classes":"w-full p-0 rounded-full","colorHint":null}]},"slots":[],"sourceFile":"src/components/display/PieChart.tsx","specSource":"design/display.pen","docsUrl":"https://gunjo.dev/docs/components/pie-chart","stability":"experimental"},{"category":"display","name":"quadrantMatrix","title":"QuadrantMatrix","description":"HTML/CSS four-quadrant matrix for plotting selectable items by x/y position with ranked values and hover/focus tooltips.","variants":{"keys":["default","compact"],"default":"default"},"styling":{"baseClasses":"w-full p-0","baseColorHint":null,"perVariant":[{"key":"default","classes":"w-full p-0","colorHint":null},{"key":"compact","classes":"w-full p-0","colorHint":null}]},"slots":[],"sourceFile":"src/components/display/QuadrantMatrix.tsx","specSource":"design/display.pen","docsUrl":"https://gunjo.dev/docs/components/quadrant-matrix","stability":"experimental"},{"category":"display","name":"radarChart","title":"RadarChart","description":"HTML/CSS radar chart for comparing single or multi-series multi-axis scores with hover/focus point tooltips.","variants":{"keys":["default","compact"],"default":"default"},"styling":{"baseClasses":"w-full h-[256px] p-0","baseColorHint":null,"perVariant":[{"key":"default","classes":"w-full h-[256px] p-0","colorHint":null},{"key":"compact","classes":"w-full h-[208px] p-0","colorHint":null}]},"slots":[],"sourceFile":"src/components/display/RadarChart.tsx","specSource":"design/display.pen","docsUrl":"https://gunjo.dev/docs/components/radar-chart","stability":"experimental"},{"category":"display","name":"radialBarChart","title":"RadialBarChart","description":"HTML/CSS concentric radial bar chart for comparing progress, share, or capacity across multiple series with hover/focus tooltips.","variants":{"keys":["default","compact"],"default":"default"},"styling":{"baseClasses":"w-full h-[224px] p-0 rounded-full","baseColorHint":null,"perVariant":[{"key":"default","classes":"w-full h-[224px] p-0 rounded-full","colorHint":null},{"key":"compact","classes":"w-full h-[176px] p-0 rounded-full","colorHint":null}]},"slots":[],"sourceFile":"src/components/display/RadialBarChart.tsx","specSource":"design/display.pen","docsUrl":"https://gunjo.dev/docs/components/radial-bar-chart","stability":"experimental"},{"category":"display","name":"radioCard","title":"RadioCard","description":"The priced selectable choice card: RadioGroup's single-select role=radio + keyboard semantics (radiogroup, roving tabindex, arrow keys) wearing a card body — tags, title, secondary (area・period), a dominant price slot, an おトク/highlight hook, leading accessory — with a built-in selected check + ring. The B2C purchase / plan-picker / shipping-option / payment-method atom. Use this for pick-one-of-many (NOT ListCard, whose onSelect is an aria-pressed toggle, not radio single-select; NOT RadioGroup, which is a bare 16px dot + label). ≥44px tap target; selection marked by a check, not colour alone. RadioCardGroup (value/onValueChange/name) wraps the RadioCards.","variants":{"keys":["default"],"default":"default"},"styling":{"baseClasses":"w-full","baseColorHint":null,"perVariant":[{"key":"default","classes":"w-full","colorHint":null}]},"slots":[],"sourceFile":"src/components/display/RadioCard.tsx","specSource":"design/display.pen","docsUrl":"https://gunjo.dev/docs/components/radio-card","stability":"beta"},{"category":"display","name":"rangeBar","title":"RangeBar","description":"One range drawn where it sits inside a whole scale: a thin track from `min` to `max` with the stretch from `low` to `high` filled. Every row of a list shares the same `min` / `max`, so a week of forecasts (lowest to highest temperature), the price band of each plan or the opening hours of each site line up and the eye compares positions, not numbers — the numbers stay outside the bar, where the caller puts them. `variant='gradient'` lays one cool-to-warm ramp (primary → info → warning) across the WHOLE scale and reveals only the covered part, so the same value is the same colour on every row; `solid` fills with primary. Equal ends still draw, as a dot the height of the track ('20° to 20°' is an answer); an unknown range (`null`) draws the track only. role='img' with an accessible name ('Temperature: 20°–28°'). HTML/CSS, no SVG. Distinct from Meter (one value from zero), DistributionBar (shares that add up to 100%) and RangeSlider (an input with thumbs).","variants":{"keys":["solid","gradient"],"default":"solid"},"styling":{"baseClasses":"","baseColorHint":null,"perVariant":[{"key":"solid","classes":"","colorHint":null},{"key":"gradient","classes":"","colorHint":null}]},"slots":[],"sourceFile":"src/components/display/RangeBar.tsx","specSource":"design/display.pen","docsUrl":"https://gunjo.dev/docs/components/range-bar","stability":"experimental"},{"category":"display","name":"rating","title":"Rating","description":"Read-only star rating display with half-star support, optional numeric value and review count, for product, review, and feedback summaries.","variants":{"keys":["default","sm","lg"],"default":"default"},"styling":{"baseClasses":"","baseColorHint":null,"perVariant":[{"key":"default","classes":"","colorHint":null},{"key":"sm","classes":"","colorHint":null},{"key":"lg","classes":"","colorHint":null}]},"slots":[],"sourceFile":"src/components/display/Rating.tsx","specSource":"design/display.pen","docsUrl":"https://gunjo.dev/docs/components/rating","stability":"experimental"},{"category":"display","name":"referenceValue","title":"ReferenceValue","description":"A measured value judged against a reference range: classifies it as normal / high (H) / low (L) / critical (HH/LL) and renders the value with a flag code, tone and screen-reader text — the value-vs-range judgement that vitals, lab results, dose safety, SLA/quota and tolerance bands all need. Exports a pure `flagValue()` helper for tables and charts.","variants":{"keys":["default"],"default":"default"},"styling":{"baseClasses":"","baseColorHint":null,"perVariant":[{"key":"default","classes":"","colorHint":null}]},"slots":[],"sourceFile":"src/components/display/ReferenceValue.tsx","specSource":"design/display.pen","docsUrl":"https://gunjo.dev/docs/components/reference-value","stability":"beta"},{"category":"display","name":"relationshipRow","title":"RelationshipRow","description":"Two PersonCells side by side with a connector (⟷ by default) and an optional relationship label: the 'person ⟷ person' unit. Models the pairings that define people-heavy domains — manager↔report (1on1), helper↔client (訪問介護), 利用者↔担当ケアマネ (ケアプラン), approver chains, mentor↔mentee. Each side is a full PersonCell (avatar + name + secondary/tertiary + status); a trailing slot holds a badge/chevron/actions. Presentational by default — let an interactive row (a wrapping link, DataTable onRowClick) own activation rather than nesting a button.","variants":{"keys":["default"],"default":"default"},"styling":{"baseClasses":"w-full","baseColorHint":null,"perVariant":[{"key":"default","classes":"w-full","colorHint":null}]},"slots":[],"sourceFile":"src/components/display/RelationshipRow.tsx","specSource":"design/display.pen","docsUrl":"https://gunjo.dev/docs/components/relationship-row","stability":"experimental"},{"category":"display","name":"retentionCohortCard","title":"Retention Cohort Card","description":"HTML/CSS cohort retention card for dashboard grids with editable cohorts, periods, values, and hover/focus cell tooltips.","variants":{"keys":["default","compact"],"default":"default"},"styling":{"baseClasses":"w-full p-0","baseColorHint":null,"perVariant":[{"key":"default","classes":"w-full p-0","colorHint":null},{"key":"compact","classes":"w-full p-0","colorHint":null}]},"slots":[],"sourceFile":"src/components/display/RetentionCohortCard.tsx","specSource":"design/display.pen","docsUrl":"https://gunjo.dev/docs/components/retention-cohort-card","stability":"experimental"},{"category":"display","name":"revealSection","title":"RevealSection","description":"State-driven conditional section: show or hide a fieldset on `open` and reveal it as a properly-labelled, screen-reader-announced region. For declaration forms where sections appear based on prior answers (配偶者控除, conditional panels).","variants":{"keys":["default"],"default":"default"},"styling":{"baseClasses":"w-full","baseColorHint":null,"perVariant":[{"key":"default","classes":"w-full","colorHint":null}]},"slots":[],"sourceFile":"src/components/display/RevealSection.tsx","specSource":"design/display.pen","docsUrl":"https://gunjo.dev/docs/components/reveal-section","stability":"experimental"},{"category":"display","name":"ribbonChart","title":"RibbonChart","description":"HTML/CSS ribbon chart for comparing changing flow, volume, or segment width across periods with hover/focus point tooltips.","variants":{"keys":["flow","stacked"],"default":"flow"},"styling":{"baseClasses":"w-full h-[260px] p-0","baseColorHint":null,"perVariant":[{"key":"flow","classes":"w-full h-[260px] p-0","colorHint":null},{"key":"stacked","classes":"w-full h-[260px] p-0","colorHint":null}]},"slots":[],"sourceFile":"src/components/display/RibbonChart.tsx","specSource":"design/display.pen","docsUrl":"https://gunjo.dev/docs/components/ribbon-chart","stability":"experimental"},{"category":"display","name":"routeStops","title":"RouteStops","description":"Ordered route / itinerary list: numbered stops with a per-stop status (pending / current / completed / failed / delayed) driving the marker and a status label, a planned-vs-actual time pair with a signed delay, the current stop wired with aria-current, and a trailing actions slot. For delivery tracking, picking walk-paths and any sequenced-stop flow.","variants":{"keys":["default"],"default":"default"},"styling":{"baseClasses":"w-full","baseColorHint":null,"perVariant":[{"key":"default","classes":"w-full","colorHint":null}]},"slots":[],"sourceFile":"src/components/display/RouteStops.tsx","specSource":"design/display.pen","docsUrl":"https://gunjo.dev/docs/components/route-stops","stability":"beta"},{"category":"display","name":"scaleBar","title":"ScaleBar","description":"How far the reader is looking on a map or canvas: a distance in words ('20 km') over a line whose length is that distance at the current zoom. Deliberately NEVER a zoom factor — '×250' answers '250 times what?' with nothing. The distance is rounded to 1 / 2 / 5 × 10ⁿ by the exported pure `niceScale(metersPerPixel, targetWidth, minWidth)` so the words stay short and the line absorbs the remainder; the line eases between lengths (no easing under prefers-reduced-motion). Takes `metersPerPixel` at the centre of the view — the caller's map library knows it — and shows '—' with no line while that is unknown, because a bar that guesses is worse than none. The words use the canvas type tier (text-canvas-2xs) with a halo in the page background colour so they read over any imagery. role='img' with an accessible name ('Scale: 20 km'). Placed by the caller, usually bottom-left. Distinct from Meter / Progress (a share of a whole) and Slider (an input).","variants":{"keys":["default"],"default":"default"},"styling":{"baseClasses":"","baseColorHint":null,"perVariant":[{"key":"default","classes":"","colorHint":null}]},"slots":[],"sourceFile":"src/components/display/ScaleBar.tsx","specSource":"design/display.pen","docsUrl":"https://gunjo.dev/docs/components/scale-bar","stability":"experimental"},{"category":"display","name":"scheduleGrid","title":"ScheduleGrid","description":"A 2-D matrix grid: a row axis × a column axis of rich content cells with a frozen first column + sticky header row, role=grid semantics (rowheaders / columnheaders / gridcells with composed accessible names), roving-tabindex arrow-key navigation, per-cell tone (a destructive flag ring), an unavailable slot treatment, and a contained horizontal scroll that does not push the page on mobile. For any rows×columns matrix of rich navigable/editable cells — timetables (periods×days), gradebooks (students×subjects), shift rosters, comparison/cohort matrices, availability and room/resource booking grids. (Not for sortable list data — that is DataTable; not for value-by-color heatmaps — that is HeatmapChart.)","variants":{"keys":["default"],"default":"default"},"styling":{"baseClasses":"w-full","baseColorHint":null,"perVariant":[{"key":"default","classes":"w-full","colorHint":null}]},"slots":[],"sourceFile":"src/components/display/ScheduleGrid.tsx","specSource":"design/display.pen","docsUrl":"https://gunjo.dev/docs/components/schedule-grid","stability":"beta"},{"category":"display","name":"searchableAccordion","title":"SearchableAccordion","description":"Searchable and category-filterable accordion composition for FAQ, help, and docs lists.","variants":{"keys":["default","withCategories","empty"],"default":"default"},"styling":{"baseClasses":"w-full p-0","baseColorHint":null,"perVariant":[{"key":"default","classes":"w-full p-0","colorHint":null},{"key":"withCategories","classes":"w-full p-0","colorHint":null},{"key":"empty","classes":"w-full p-0","colorHint":null}]},"slots":[],"sourceFile":"src/components/display/SearchableAccordion.tsx","specSource":"design/display.pen","docsUrl":"https://gunjo.dev/docs/components/searchable-accordion","stability":"experimental"},{"category":"display","name":"seatMap","title":"SeatMap","description":"The 2-D selectable seat grid: rows × columns with aisle gaps (columns array with nulls for the aisle — 3-3 / 2-4-2 / 2-2 cabins), per-seat state (空席 / 予約済 / 確保中 / 選択中) and type (非常口 / 足元ゆったり / プレミアム / 窓側 / 通路側), controlled multi-select with a capacity cap (maxSelectable), and grid a11y: role=grid, arrow-key roving focus, aria-selected / aria-disabled, composed seat names (『12番A席、窓側、非常口座席、空席、¥1,500』). The seat/spot picker every booking flow needs — airline / 新幹線 seats, cinema, stadium, event hall, restaurant tables. State never rides on colour alone (selected shows a check, occupied an ×, plus an sr-only label). Owns its horizontal scroll so a wide cabin doesn't push the page on a phone. Controlled — pass selectedIds + onToggle. For a read-only intensity grid use HeatmapChart; this is the interactive picker.","variants":{"keys":["default"],"default":"default"},"styling":{"baseClasses":"w-full","baseColorHint":null,"perVariant":[{"key":"default","classes":"w-full","colorHint":null}]},"slots":[],"sourceFile":"src/components/display/SeatMap.tsx","specSource":"design/display.pen","docsUrl":"https://gunjo.dev/docs/components/seat-map","stability":"experimental"},{"category":"display","name":"sectionList","title":"SectionList","description":"The grouped-list / sectioned layout: a sequence of sections, each a heading band (title + sublabel + a right-aligned group aggregate) over the caller's body rows, with an optional per-group subtotal footer. The grouping spine every history / 利用明細 / 取引履歴 / statement / invoice-by-客先 screen hand-rolls — groupBy + a section header + a per-group subtotal. Body-agnostic: drop in ListCards (mobile history), a Table (desktop invoices), or signed ledger rows. The caller owns the grouping + subtotal math + any cross-group selection; this owns the consistent header/footer chrome + the sectioned a11y structure. Distinct from StatusBoard.groups (status tiles) and Itinerary.days (a trip timeline). sections[] of {key,title,sublabel?,meta?,content,footer?}; stickyHeaders optional. RSC-safe.","variants":{"keys":["default"],"default":"default"},"styling":{"baseClasses":"w-full","baseColorHint":null,"perVariant":[{"key":"default","classes":"w-full","colorHint":null}]},"slots":[],"sourceFile":"src/components/display/SectionList.tsx","specSource":"design/display.pen","docsUrl":"https://gunjo.dev/docs/components/section-list","stability":"experimental"},{"category":"display","name":"segmentedGaugeCard","title":"Segmented Gauge Card","description":"HTML/CSS segmented semicircle gauge card for status, spend, risk, and progress dashboards with editable segments, target value, and hover/focus tooltips.","variants":{"keys":["default","compact"],"default":"default"},"styling":{"baseClasses":"w-full p-0","baseColorHint":null,"perVariant":[{"key":"default","classes":"w-full p-0","colorHint":null},{"key":"compact","classes":"w-full p-0","colorHint":null}]},"slots":[],"sourceFile":"src/components/display/SegmentedGaugeCard.tsx","specSource":"design/display.pen","docsUrl":"https://gunjo.dev/docs/components/segmented-gauge-card","stability":"experimental"},{"category":"display","name":"segmentTimelineCard","title":"Segment Timeline Card","description":"HTML/CSS horizontal segment timeline card for sleep stages, uptime states, and categorical duration ranges with metrics, markers, and hover/focus tooltips.","variants":{"keys":["default","compact"],"default":"default"},"styling":{"baseClasses":"w-full p-0","baseColorHint":null,"perVariant":[{"key":"default","classes":"w-full p-0","colorHint":null},{"key":"compact","classes":"w-full p-0","colorHint":null}]},"slots":[],"sourceFile":"src/components/display/SegmentTimelineCard.tsx","specSource":"design/display.pen","docsUrl":"https://gunjo.dev/docs/components/segment-timeline-card","stability":"experimental"},{"category":"display","name":"separator","title":"Separator","description":"Visually or semantically separates content.","variants":{"keys":["horizontal","vertical"],"default":"horizontal"},"styling":{"baseClasses":"w-full h-[1px]","baseColorHint":"fill=#e2e8f0","perVariant":[{"key":"horizontal","classes":"w-full h-[1px]","colorHint":"fill=#e2e8f0"},{"key":"vertical","classes":"w-[1px] h-6","colorHint":"fill=#e2e8f0"}]},"slots":[],"sourceFile":"src/components/display/Separator.tsx","specSource":"design/display.pen","docsUrl":"https://gunjo.dev/docs/components/separator","stability":"beta"},{"category":"display","name":"signedRecord","title":"SignedRecord","description":"Append-only signed legal record: a draft body that, once signed, locks read-only (recording signer + timestamp) and can only be amended by a timestamped, authored addendum — never edited. Renders the draft/signed badge, the locked affordance, the signer audit line, an addendum composer and chain, and an optional CoSign gate. For clinical notes, discharge summaries, operative records and any signed/audited document.","variants":{"keys":["default"],"default":"default"},"styling":{"baseClasses":"w-full","baseColorHint":null,"perVariant":[{"key":"default","classes":"w-full","colorHint":null}]},"slots":[],"sourceFile":"src/components/display/SignedRecord.tsx","specSource":"design/display.pen","docsUrl":"https://gunjo.dev/docs/components/signed-record","stability":"beta"},{"category":"display","name":"skeleton","title":"Skeleton","description":"Loading placeholder for content while it is being fetched.","variants":{"keys":[],"default":null},"styling":{"baseClasses":"","baseColorHint":null,"perVariant":[]},"slots":[],"sourceFile":"src/components/display/Skeleton.tsx","specSource":"design/display.pen","docsUrl":"https://gunjo.dev/docs/components/skeleton","stability":"experimental"},{"category":"display","name":"spacer","title":"Spacer","description":"Flex-grow filler for pushing siblings to the edges of a flex container.","variants":{"keys":[],"default":null},"styling":{"baseClasses":"","baseColorHint":null,"perVariant":[]},"slots":[],"sourceFile":"src/components/display/Spacer.tsx","specSource":"design/display.pen","docsUrl":"https://gunjo.dev/docs/components/spacer","stability":"experimental"},{"category":"display","name":"sparklineChart","title":"SparklineChart","description":"Compact HTML/CSS line, area, or stepped trend chart for dense dashboard cards with hover/focus point tooltips. It can mark the current point with a dot and a vertical line, and put small labels under both ends (such as 15 days ago and in 15 days).","variants":{"keys":["line","area","step"],"default":"line"},"styling":{"baseClasses":"w-full h-24 p-0","baseColorHint":null,"perVariant":[{"key":"line","classes":"w-full h-24 p-0","colorHint":null},{"key":"area","classes":"w-full h-24 p-0","colorHint":null},{"key":"step","classes":"w-full h-24 p-0","colorHint":null}]},"slots":[],"sourceFile":"src/components/display/SparklineChart.tsx","specSource":"design/display.pen","docsUrl":"https://gunjo.dev/docs/components/sparkline-chart","stability":"experimental"},{"category":"display","name":"stackedBarChart","title":"StackedBarChart","description":"HTML/CSS stacked vertical or horizontal bar chart for grouped segment comparisons with hover/focus segment tooltips.","variants":{"keys":["vertical","horizontal"],"default":"vertical"},"styling":{"baseClasses":"w-full h-[224px] p-0","baseColorHint":null,"perVariant":[{"key":"vertical","classes":"w-full h-[224px] p-0","colorHint":null},{"key":"horizontal","classes":"w-full h-[224px] p-0","colorHint":null}]},"slots":[],"sourceFile":"src/components/display/StackedBarChart.tsx","specSource":"design/display.pen","docsUrl":"https://gunjo.dev/docs/components/stacked-bar-chart","stability":"experimental"},{"category":"display","name":"statGroup","title":"StatGroup","description":"The summary metric strip: a responsive grid of Statistics (Card-wrapped by default) — the KPI row almost every back-office screen opens with (件数 / 金額 / 期限 / アラート …). Each item inherits Statistic's canonical SemanticTone contract and its 0.1.x legacy aliases (positive→success, negative→destructive, neutral→muted); trend and goodWhen remain directional/evaluation inputs rather than tone aliases. Fixed or responsive column counts ({ base: 2, md: 4 }). Presentational and RSC-safe (no function props) — pass plain data. For one metric use Statistic; for the row, use this.","variants":{"keys":["default"],"default":"default"},"styling":{"baseClasses":"w-full","baseColorHint":null,"perVariant":[{"key":"default","classes":"w-full","colorHint":null}]},"slots":[],"sourceFile":"src/components/display/StatGroup.tsx","specSource":"design/display.pen","docsUrl":"https://gunjo.dev/docs/components/stat-group","stability":"beta"},{"category":"display","name":"statistic","title":"Statistic","description":"KPI metric card: label + value + delta indicator. Change tones use the canonical SemanticTone scale; legacy positive/negative/neutral aliases map to success/destructive/muted.","variants":{"keys":[],"default":null},"styling":{"baseClasses":"","baseColorHint":null,"perVariant":[]},"slots":[],"sourceFile":"src/components/display/Statistic.tsx","specSource":"design/display.pen","docsUrl":"https://gunjo.dev/docs/components/statistic","stability":"beta"},{"category":"display","name":"statusBoard","title":"StatusBoard","description":"The live entity status board at the center of every dispatch / monitoring floor: many labeled entities (vehicles / machines / spots), each carrying a status (空車 / 故障 / 稼働中), a location, and a note, laid out as a responsive tile grid. The tone contract accepts canonical SemanticTone directly; the 0.1.x danger alias normalizes to destructive before styling, severity sorting, and problemTones matching. Problems and availability stand out via a semantic border + subtle background and a colour-safe status pill (icon + text, never colour alone); tiles sort fault-first by default; tiles group by zone/area with a per-group problem count. items[] (flat) or groups[] of {id,label,status,tone,location?,note?,icon?,trailing?,rank?,onSelect?}. The board a Gantt / DataTable / HeatmapChart can't be — taxi 配車盤, 駅務の機器状態盤, ramp GSE board, factory line OEE. (Gantt = rows × time, DataTable = sortable grid of rows, HeatmapChart = read-only value-by-colour matrix; this is a spatial/grouped board of selectable status entities where problems pop.) RSC-safe except the opt-in onSelect.","variants":{"keys":["default"],"default":"default"},"styling":{"baseClasses":"w-full","baseColorHint":null,"perVariant":[{"key":"default","classes":"w-full","colorHint":null}]},"slots":[],"sourceFile":"src/components/display/StatusBoard.tsx","specSource":"design/display.pen","docsUrl":"https://gunjo.dev/docs/components/status-board","stability":"experimental"},{"category":"display","name":"statusLevel","title":"StatusLevel","description":"The ORDERED qualitative level indicator: a scale written once (levels[], low end → high end) plus the current value, rendered as a colour-safe chip and a filled-step bar that reads 「4段階中 3段目」 to screen readers. For states that have a rank — 空いています < やや混雑 < 混雑, 平常運転 < 遅延 < 迂回 < 運休, 低 < 中 < 高 < 緊急, good < watch < bad, 在庫 多/少, 鮮度, 難易度. The order lives in ONE array, so the sort key (compareStatusLevel), the roll-up (highestStatusLevel) and the pill cannot drift apart — the papercut behind the hand-rolled LEVEL_META + LEVEL_BADGE + LEVEL_SEVERITY + rank quartet. Tone is the WEIGHT of a step, never the order: the bar is drawn in foreground-vs-border shades, not semantic tones, so the step count survives greyscale. NOT for unordered states (支払済 / 請求中, 下書き / 公開) — that is Badge. NOT for a position in a process (受付 → 審査 → 完了, 空席 → 着席 → 会計) — that is Stepper / ApprovalSteps / RouteStops, which advance without getting heavier. Pairs with the pure statusLevelIndex / statusLevelStep / compareStatusLevel / highestStatusLevel helpers, mirroring how ExpiryBadge pairs with classifyExpiry(). RSC-safe.","variants":{"keys":["default"],"default":"default"},"styling":{"baseClasses":"","baseColorHint":null,"perVariant":[{"key":"default","classes":"","colorHint":null}]},"slots":[],"sourceFile":"src/components/display/StatusLevel.tsx","specSource":"design/display.pen","docsUrl":"https://gunjo.dev/docs/components/status-level","stability":"experimental"},{"category":"display","name":"stringline","title":"Stringline","description":"The time × distance run diagram (運行図表 / ダイヤグラム / Marey / string-line chart): the route's stops on the distance (y) axis, time on the x axis, each run a DIAGONAL polyline across the stops over time. Slope = speed, a horizontal kink = a dwell, two lines converging = a meet / overtake / bunching (続行・だんご). Bidirectional runs (up/down), an optional now-line, planned-vs-actual pairs (planned dashed + actual solid), and focusable runs (onSelect). The transport-ops view a Gantt structurally cannot draw — Gantt is resource rows × horizontal bars (y = identity); this transposes the same time engine onto a continuous distance axis (y = distance) so runs can cross. For rail/bus/tram/ferry dispatch & timetable diagrams. SSR-safe: pass now in rather than reading the clock. SVG line geometry like LineChart.","variants":{"keys":["default"],"default":"default"},"styling":{"baseClasses":"w-full","baseColorHint":null,"perVariant":[{"key":"default","classes":"w-full","colorHint":null}]},"slots":[],"sourceFile":"src/components/display/Stringline.tsx","specSource":"design/display.pen","docsUrl":"https://gunjo.dev/docs/components/stringline","stability":"experimental"},{"category":"display","name":"swatchGroup","title":"SwatchGroup","description":"Selectable color swatch group (single-select) with roving keyboard focus and disabled out-of-stock swatches, for product variant and theme pickers.","variants":{"keys":["default","sm","lg"],"default":"default"},"styling":{"baseClasses":"","baseColorHint":null,"perVariant":[{"key":"default","classes":"","colorHint":null},{"key":"sm","classes":"","colorHint":null},{"key":"lg","classes":"","colorHint":null}]},"slots":[],"sourceFile":"src/components/display/SwatchGroup.tsx","specSource":"design/display.pen","docsUrl":"https://gunjo.dev/docs/components/swatch-group","stability":"experimental"},{"category":"display","name":"table","title":"Table","description":"A responsive table component.","variants":{"keys":["default"],"default":"default"},"styling":{"baseClasses":"flex flex-col w-full rounded-lg border","baseColorHint":"fill=#FFFFFF | stroke=#e2e8f0@1px","perVariant":[{"key":"default","classes":"flex flex-col w-full rounded-lg border","colorHint":"fill=#FFFFFF | stroke=#e2e8f0@1px"}]},"slots":["tableHeader","tableRow"],"sourceFile":"src/components/display/Table.tsx","specSource":"design/display.pen","docsUrl":"https://gunjo.dev/docs/components/table","stability":"beta"},{"category":"display","name":"tag","title":"Tag","description":"Removable badge with × button. Useful for filter chips and tag editors.","variants":{"keys":[],"default":null},"styling":{"baseClasses":"","baseColorHint":null,"perVariant":[]},"slots":[],"sourceFile":"src/components/display/Tag.tsx","specSource":"design/display.pen","docsUrl":"https://gunjo.dev/docs/components/tag","stability":"beta"},{"category":"display","name":"tagEditor","title":"TagEditor","description":"Tag editing control composed from TagInput and suggestion actions for asset inspectors and filter panels.","variants":{"keys":["default","compact"],"default":"default"},"styling":{"baseClasses":"w-full p-0","baseColorHint":null,"perVariant":[{"key":"default","classes":"w-full p-0","colorHint":null},{"key":"compact","classes":"w-full p-0","colorHint":null}]},"slots":[],"sourceFile":"src/components/display/TagEditor.tsx","specSource":"design/display.pen","docsUrl":"https://gunjo.dev/docs/components/tag-editor","stability":"experimental"},{"category":"display","name":"ticketStub","title":"TicketStub","description":"The scannable pass / ticket / coupon / member-card stub: a card with a barcode or QR (real value in the SR name via role=img), a human-readable code label, an optional perforation notch (the cut-out look that reads as a ticket), and a content slot above for the domain detail (flight OD-pair + seat/gate, coupon discount + 期限, member tier + points). The thing the traveller holds up at the gate / register — the consumer mirror of ScanInput/ScanGate (which capture a code; this displays one). value + format (code128 / qr). RSC-safe; the built-in code render is a deterministic (SSR-safe) visual placeholder — pass the code prop for a production-scannable barcode from a lib.","variants":{"keys":["default"],"default":"default"},"styling":{"baseClasses":"w-full","baseColorHint":null,"perVariant":[{"key":"default","classes":"w-full","colorHint":null}]},"slots":[],"sourceFile":"src/components/display/TicketStub.tsx","specSource":"design/display.pen","docsUrl":"https://gunjo.dev/docs/components/ticket-stub","stability":"experimental"},{"category":"display","name":"timeline","title":"Timeline","description":"Vertical time-ordered list with markers and connector lines.","variants":{"keys":[],"default":null},"styling":{"baseClasses":"","baseColorHint":null,"perVariant":[]},"slots":[],"sourceFile":"src/components/display/Timeline.tsx","specSource":"design/display.pen","docsUrl":"https://gunjo.dev/docs/components/timeline","stability":"beta"},{"category":"display","name":"toolPill","title":"ToolPill","description":"Compact icon pill used for toolbar quick actions with active and danger states.","variants":{"keys":["primary","secondary","danger"],"default":"primary"},"styling":{"baseClasses":"w-10 h-10 p-2 rounded-xl","baseColorHint":"fill=#eff6ff","perVariant":[{"key":"primary","classes":"w-10 h-10 p-2 rounded-xl","colorHint":"fill=#eff6ff"},{"key":"secondary","classes":"w-10 h-10 p-2 rounded-xl","colorHint":"fill=#ffffff80"},{"key":"danger","classes":"w-10 h-10 p-2 rounded-xl","colorHint":"fill=#fef2f2"}]},"slots":[],"sourceFile":"src/components/display/ToolPill.tsx","specSource":"design/display.pen","docsUrl":"https://gunjo.dev/docs/components/tool-pill","stability":"experimental"},{"category":"display","name":"treeView","title":"TreeView","description":"Hierarchical tree with expand/collapse for file explorers and navigation.","variants":{"keys":[],"default":null},"styling":{"baseClasses":"","baseColorHint":null,"perVariant":[]},"slots":[],"sourceFile":"src/components/display/TreeView.tsx","specSource":"design/display.pen","docsUrl":"https://gunjo.dev/docs/components/tree-view","stability":"experimental"},{"category":"display","name":"weekView","title":"WeekView","description":"Week-view time-grid calendar: day columns × an hour axis with events positioned by start/end time and overlap-packed into side-by-side columns, plus a time gutter, weekday/date headers and an optional today highlight. Owns the week math (pass weekOf + events); today is injectable (SSR-safe). Events are focusable buttons with a composed accessible name. For appointments, bookings, shift schedules, week schedulers and any time-of-day calendar.","variants":{"keys":["default"],"default":"default"},"styling":{"baseClasses":"w-full","baseColorHint":null,"perVariant":[{"key":"default","classes":"w-full","colorHint":null}]},"slots":[],"sourceFile":"src/components/display/WeekView.tsx","specSource":"design/display.pen","docsUrl":"https://gunjo.dev/docs/components/week-view","stability":"experimental"},{"category":"feedback","name":"actionProgress","title":"ActionProgress","description":"Blocking feedback for a short action (save, send, redirect), composed from Dialog, Progress (indeterminate) and Spinner. It appears only when the action is still pending after delayMs (default 350ms), so fast work never flashes a modal, and closes as soon as open turns false. Never shows a percentage. FormActionProgress reads the enclosing form's pending state via React 19 useFormStatus. Not for long work with a visual or a cancel — that is ProgressDialog.","variants":{"keys":["default"],"default":"default"},"styling":{"baseClasses":"p-0","baseColorHint":null,"perVariant":[{"key":"default","classes":"p-0","colorHint":null}]},"slots":[],"sourceFile":"src/components/feedback/ActionProgress.tsx","specSource":"design/feedback.pen","docsUrl":"https://gunjo.dev/docs/components/action-progress","stability":"experimental"},{"category":"feedback","name":"alert","title":"Alert","description":"Displays a callout for user attention.","variants":{"keys":["default","destructive","info","success","warning"],"default":"default"},"styling":{"baseClasses":"inline-flex items-center w-full py-3 px-4 gap-1 rounded-lg border text-sm font-medium","baseColorHint":"fill=#FFFFFF | stroke=#e2e8f0@1px | text=#0c0c12","perVariant":[{"key":"default","classes":"inline-flex items-center w-full py-3 px-4 gap-1 rounded-lg border text-sm font-medium","colorHint":"fill=#FFFFFF | stroke=#e2e8f0@1px | text=#0c0c12"},{"key":"destructive","classes":"inline-flex items-center w-full py-3 px-4 gap-1 rounded-lg border text-sm font-medium","colorHint":"fill=#fef2f2 | stroke=#fecaca@1px | text=#991b1b"},{"key":"info","classes":"inline-flex items-center w-full py-3 px-4 gap-1 rounded-lg border text-sm font-medium","colorHint":"fill=#eff6ff | stroke=#bfdbfe@1px | text=#1e40af"},{"key":"success","classes":"inline-flex items-center w-full py-3 px-4 gap-1 rounded-lg border text-sm font-medium","colorHint":"fill=#f0fdf4 | stroke=#bbf7d0@1px | text=#166534"},{"key":"warning","classes":"inline-flex items-center w-full py-3 px-4 gap-1 rounded-lg border text-sm font-medium","colorHint":"fill=#fef3c7 | stroke=#fcd34d@1px | text=#78350f"}]},"slots":[],"sourceFile":"src/components/feedback/Alert.tsx","specSource":"design/feedback.pen","docsUrl":"https://gunjo.dev/docs/components/alert","stability":"beta"},{"category":"feedback","name":"banner","title":"Banner","description":"Page-wide announcement bar, optionally dismissible.","variants":{"keys":[],"default":null},"styling":{"baseClasses":"","baseColorHint":null,"perVariant":[]},"slots":[],"sourceFile":"src/components/feedback/Banner.tsx","specSource":"design/feedback.pen","docsUrl":"https://gunjo.dev/docs/components/banner","stability":"beta"},{"category":"feedback","name":"notificationCenter","title":"Notification Center","description":"Popover-based inbox for unread activity and quick actions.","variants":{"keys":["default"],"default":"default"},"styling":{"baseClasses":"flex flex-col w-[320px]","baseColorHint":null,"perVariant":[{"key":"default","classes":"flex flex-col w-[320px]","colorHint":null}]},"slots":["notificationCenterTrigger","notificationCenterPanel"],"sourceFile":"src/components/feedback/NotificationCenter.tsx","specSource":"design/feedback.pen","docsUrl":"https://gunjo.dev/docs/components/notification-center","stability":"experimental"},{"category":"feedback","name":"progress","title":"Progress","description":"Displays an indicator showing the completion progress of a task, typically displayed as a progress bar.","variants":{"keys":["bar"],"default":"bar"},"styling":{"baseClasses":"w-full h-4 rounded-full","baseColorHint":"fill=#f1f5f9","perVariant":[{"key":"bar","classes":"w-full h-4 rounded-full","colorHint":"fill=#f1f5f9"}]},"slots":[],"sourceFile":"src/components/feedback/Progress.tsx","specSource":"design/feedback.pen","docsUrl":"https://gunjo.dev/docs/components/progress","stability":"beta"},{"category":"feedback","name":"progressWidget","title":"ProgressWidget","description":"Metric card showing title, value, progress bar, and optional subtext.","variants":{"keys":["default"],"default":"default"},"styling":{"baseClasses":"flex flex-col w-full rounded-lg border","baseColorHint":"fill=#ffffff | stroke=#e2e8f0@1px","perVariant":[{"key":"default","classes":"flex flex-col w-full rounded-lg border","colorHint":"fill=#ffffff | stroke=#e2e8f0@1px"}]},"slots":["progressWidgetHeader","progressWidgetContent"],"sourceFile":"src/components/feedback/ProgressWidget.tsx","specSource":"design/feedback.pen","docsUrl":"https://gunjo.dev/docs/components/progress-widget","stability":"experimental"},{"category":"feedback","name":"routeProgress","title":"RouteProgress","description":"A thin indeterminate bar pinned to the top of the viewport (or of a positioned container) while a page or view loads. Framework-agnostic: render it from any loading boundary and unmount it when done. Built on Progress indeterminate, so there is one sweep implementation; it never shows a percentage and becomes a still, dimmed bar under reduced motion.","variants":{"keys":["default"],"default":"default"},"styling":{"baseClasses":"p-0","baseColorHint":null,"perVariant":[{"key":"default","classes":"p-0","colorHint":null}]},"slots":[],"sourceFile":"src/components/feedback/RouteProgress.tsx","specSource":"design/feedback.pen","docsUrl":"https://gunjo.dev/docs/components/route-progress","stability":"experimental"},{"category":"feedback","name":"safetyBanner","title":"SafetyBanner","description":"Persistent, assertive, acknowledgeable safety alert: a loud banner for a critical condition (allergy, contraindication, panic value, over-dose) that announces assertively, requires an explicit acknowledgement, and exposes that acked state so the consumer can block a sign-off until it's cleared. Stronger than Alert (which is presentational and has no acknowledge contract).","variants":{"keys":["default"],"default":"default"},"styling":{"baseClasses":"inline-flex items-center w-full py-3 px-4 gap-1 rounded-lg","baseColorHint":null,"perVariant":[{"key":"default","classes":"inline-flex items-center w-full py-3 px-4 gap-1 rounded-lg","colorHint":null}]},"slots":[],"sourceFile":"src/components/feedback/SafetyBanner.tsx","specSource":"design/feedback.pen","docsUrl":"https://gunjo.dev/docs/components/safety-banner","stability":"experimental"},{"category":"feedback","name":"spinner","title":"Spinner","description":"A visual indicator that content is being loaded.","variants":{"keys":["sm","default","lg"],"default":"default"},"styling":{"baseClasses":"w-4 h-4","baseColorHint":"fill=#64748b","perVariant":[{"key":"sm","classes":"w-3 h-3","colorHint":"fill=#64748b"},{"key":"default","classes":"w-4 h-4","colorHint":"fill=#64748b"},{"key":"lg","classes":"w-6 h-6","colorHint":"fill=#64748b"}]},"slots":[],"sourceFile":"src/components/feedback/Spinner.tsx","specSource":"design/feedback.pen","docsUrl":"https://gunjo.dev/docs/components/spinner","stability":"experimental"},{"category":"feedback","name":"statusBar","title":"StatusBar","description":"Bottom fixed utility bar with left, center and right regions.","variants":{"keys":["fixed"],"default":"fixed"},"styling":{"baseClasses":"flex flex-row w-[640px] py-1 px-4","baseColorHint":"fill=#2563eb","perVariant":[{"key":"fixed","classes":"flex flex-row w-[640px] py-1 px-4","colorHint":"fill=#2563eb"}]},"slots":["statusBarLeft","statusBarCenter","statusBarRight"],"sourceFile":"src/components/feedback/StatusBar.tsx","specSource":"design/feedback.pen","docsUrl":"https://gunjo.dev/docs/components/status-bar","stability":"experimental"},{"category":"feedback","name":"statusScreen","title":"StatusScreen","description":"Full-page status feedback for not-found, error, offline, forbidden, maintenance, and coming-soon states.","variants":{"keys":["not-found","error","offline","forbidden","maintenance","coming-soon"],"default":"not-found"},"styling":{"baseClasses":"w-full p-8","baseColorHint":null,"perVariant":[{"key":"not-found","classes":"w-full p-8","colorHint":null},{"key":"error","classes":"w-full p-8","colorHint":null},{"key":"offline","classes":"w-full p-8","colorHint":null},{"key":"forbidden","classes":"w-full p-8","colorHint":null},{"key":"maintenance","classes":"w-full p-8","colorHint":null},{"key":"coming-soon","classes":"w-full p-8","colorHint":null}]},"slots":[],"sourceFile":"src/components/feedback/StatusScreen.tsx","specSource":"design/feedback.pen","docsUrl":"https://gunjo.dev/docs/components/status-screen","stability":"experimental"},{"category":"feedback","name":"stepper","title":"Stepper","description":"A multi-step progress indicator with completed, current, and upcoming states.","variants":{"keys":[],"default":null},"styling":{"baseClasses":"","baseColorHint":null,"perVariant":[]},"slots":[],"sourceFile":"src/components/feedback/Stepper.tsx","specSource":"design/feedback.pen","docsUrl":"https://gunjo.dev/docs/components/stepper","stability":"beta"},{"category":"feedback","name":"stickyNoticeBar","title":"StickyNoticeBar","description":"A single fixed site-announcement slot at an explicitly selected top or bottom edge. The dismiss control can be a word instead of ×, and the message can wrap only between words.","variants":{"keys":["top","bottom"],"default":null},"styling":{"baseClasses":"flex flex-row items-center w-full py-2 px-4 gap-3 border","baseColorHint":"fill=#ffffff | stroke=#e2e8f0@1px","perVariant":[{"key":"top","classes":"flex flex-row items-center w-full py-2 px-4 gap-3 border","colorHint":"fill=#ffffff | stroke=#e2e8f0@1px"},{"key":"bottom","classes":"flex flex-row items-center w-full py-2 px-4 gap-3 border","colorHint":"fill=#ffffff | stroke=#e2e8f0@1px"}]},"slots":["stickyNoticeBarTopMessage","stickyNoticeBarTopAction","stickyNoticeBarTopDismiss"],"sourceFile":"src/components/feedback/StickyNoticeBar.tsx","specSource":"design/feedback.pen","docsUrl":"https://gunjo.dev/docs/components/sticky-notice-bar","stability":"experimental"},{"category":"feedback","name":"toast","title":"Toast","description":"Transient feedback message with semantic variants.","variants":{"keys":["success","error","info"],"default":"success"},"styling":{"baseClasses":"flex py-3 px-4 rounded-xl border","baseColorHint":"fill=#ffffff | stroke=#22c55e33@1px","perVariant":[{"key":"success","classes":"flex py-3 px-4 rounded-xl border","colorHint":"fill=#ffffff | stroke=#22c55e33@1px"},{"key":"error","classes":"flex py-3 px-4 rounded-xl border","colorHint":"fill=#ffffff | stroke=#ef444433@1px"},{"key":"info","classes":"flex py-3 px-4 rounded-xl border","colorHint":"fill=#ffffff | stroke=#3b82f633@1px"}]},"slots":["toastSuccessIcon","toastSuccessText","toastSuccessClose"],"sourceFile":"src/components/feedback/Toast.tsx","specSource":"design/feedback.pen","docsUrl":"https://gunjo.dev/docs/components/toast","stability":"experimental"},{"category":"feedback","name":"toastProvider","title":"Toast Provider","description":"Global toast stack manager for showing transient feedback messages.","variants":{"keys":["default"],"default":"default"},"styling":{"baseClasses":"flex flex-col","baseColorHint":null,"perVariant":[{"key":"default","classes":"flex flex-col","colorHint":null}]},"slots":["toastProviderStack","toastProviderDefaultDuration","toastProviderExitDelay"],"sourceFile":"src/components/feedback/ToastProvider.tsx","specSource":"design/feedback.pen","docsUrl":"https://gunjo.dev/docs/components/toast-provider","stability":"experimental"},{"category":"navigation","name":"appRail","title":"App Rail","description":"Primary vertical icon rail used for application-wide navigation.","variants":{"keys":["default"],"default":"default"},"styling":{"baseClasses":"flex flex-col items-center w-16 h-[320px] py-4 px-0 gap-4","baseColorHint":"fill=#111827","perVariant":[{"key":"default","classes":"flex flex-col items-center w-16 h-[320px] py-4 px-0 gap-4","colorHint":"fill=#111827"}]},"slots":["appRailIconHome","appRailIconSearch","appRailIconFolder"],"sourceFile":"src/components/navigation/AppRail.tsx","specSource":"design/navigation.pen","docsUrl":"https://gunjo.dev/docs/components/app-rail","stability":"experimental"},{"category":"navigation","name":"breadcrumb","title":"Breadcrumb","description":"Displays the path to the current resource using a hierarchy of links.","variants":{"keys":["default"],"default":"default"},"styling":{"baseClasses":"flex flex-row items-center gap-2","baseColorHint":null,"perVariant":[{"key":"default","classes":"flex flex-row items-center gap-2","colorHint":null}]},"slots":["breadcrumbLink1","breadcrumbSep1","breadcrumbLink2","breadcrumbSep2","breadcrumbPage"],"sourceFile":"src/components/navigation/Breadcrumb.tsx","specSource":"design/navigation.pen","docsUrl":"https://gunjo.dev/docs/components/breadcrumb","stability":"experimental"},{"category":"navigation","name":"command","title":"Command","description":"Fast, composable, unstyled command menu for React.","variants":{"keys":["default"],"default":"default"},"styling":{"baseClasses":"flex flex-col w-full rounded-lg border","baseColorHint":"fill=#FFFFFF | stroke=#e2e8f0@1px","perVariant":[{"key":"default","classes":"flex flex-col w-full rounded-lg border","colorHint":"fill=#FFFFFF | stroke=#e2e8f0@1px"}]},"slots":["commandInput","commandList"],"sourceFile":"src/components/navigation/Command.tsx","specSource":"design/navigation.pen","docsUrl":"https://gunjo.dev/docs/components/command","stability":"experimental"},{"category":"navigation","name":"commandPalette","title":"Command Palette","description":"Global quick-action launcher with grouped commands and keyboard shortcuts.","variants":{"keys":["default"],"default":"default"},"styling":{"baseClasses":"flex flex-col w-full rounded-lg border","baseColorHint":"fill=#ffffff | stroke=#e2e8f0@1px","perVariant":[{"key":"default","classes":"flex flex-col w-full rounded-lg border","colorHint":"fill=#ffffff | stroke=#e2e8f0@1px"}]},"slots":["commandPaletteInput","commandPaletteGroup"],"sourceFile":"src/components/navigation/CommandPalette.tsx","specSource":"design/navigation.pen","docsUrl":"https://gunjo.dev/docs/components/command-palette","stability":"experimental"},{"category":"navigation","name":"documentPager","title":"DocumentPager","description":"Adjacent-document navigation with preview thumbnail, category label, title, and description.","variants":{"keys":["default"],"default":"default"},"styling":{"baseClasses":"flex items-center w-full pt-5 pb-0 px-0 gap-3","baseColorHint":null,"perVariant":[{"key":"default","classes":"flex items-center w-full pt-5 pb-0 px-0 gap-3","colorHint":null}]},"slots":["documentPagerPrevious","documentPagerNext"],"sourceFile":"src/components/navigation/DocumentPager.tsx","specSource":"design/navigation.pen","docsUrl":"https://gunjo.dev/docs/components/document-pager","stability":"experimental"},{"category":"navigation","name":"footer","title":"Footer","description":"Standard footer with brand, link sections, and copyright row.","variants":{"keys":[],"default":null},"styling":{"baseClasses":"","baseColorHint":null,"perVariant":[]},"slots":[],"sourceFile":"src/components/navigation/Footer.tsx","specSource":"design/navigation.pen","docsUrl":"https://gunjo.dev/docs/components/footer","stability":"experimental"},{"category":"navigation","name":"header","title":"Header","description":"Top navigation bar with logo, primary nav, and right-aligned actions.","variants":{"keys":[],"default":null},"styling":{"baseClasses":"","baseColorHint":null,"perVariant":[]},"slots":[],"sourceFile":"src/components/navigation/Header.tsx","specSource":"design/navigation.pen","docsUrl":"https://gunjo.dev/docs/components/header","stability":"experimental"},{"category":"navigation","name":"menubar","title":"Menubar","description":"Top application menu with trigger items and nested submenu entry.","variants":{"keys":["default"],"default":"default"},"styling":{"baseClasses":"flex flex-row items-center h-10 p-1 gap-1 rounded-md border","baseColorHint":"fill=#ffffff | stroke=#e2e8f0@1px","perVariant":[{"key":"default","classes":"flex flex-row items-center h-10 p-1 gap-1 rounded-md border","colorHint":"fill=#ffffff | stroke=#e2e8f0@1px"}]},"slots":["menubarTrigger","menubarContent"],"sourceFile":"src/components/navigation/Menubar.tsx","specSource":"design/navigation.pen","docsUrl":"https://gunjo.dev/docs/components/menubar","stability":"experimental"},{"category":"navigation","name":"navigationMenu","title":"NavigationMenu","description":"Top-nav with mega-menu dropdowns for site navigation.","variants":{"keys":[],"default":null},"styling":{"baseClasses":"","baseColorHint":null,"perVariant":[]},"slots":[],"sourceFile":"src/components/navigation/NavigationMenu.tsx","specSource":"design/navigation.pen","docsUrl":"https://gunjo.dev/docs/components/navigation-menu","stability":"experimental"},{"category":"navigation","name":"pageAside","title":"PageAside","description":"Responsive page support layout that renders supporting information as a right rail on wide screens and a collapsible block on narrow screens.","variants":{"keys":["default"],"default":"default"},"styling":{"baseClasses":"w-full","baseColorHint":null,"perVariant":[{"key":"default","classes":"w-full","colorHint":null}]},"slots":[],"sourceFile":"src/components/navigation/PageAside.tsx","specSource":"design/navigation.pen","docsUrl":"https://gunjo.dev/docs/components/page-aside","stability":"experimental"},{"category":"navigation","name":"pagination","title":"Pagination","description":"Navigation controls for traversing paged content.","variants":{"keys":["default"],"default":"default"},"styling":{"baseClasses":"flex flex-row items-center gap-1","baseColorHint":null,"perVariant":[{"key":"default","classes":"flex flex-row items-center gap-1","colorHint":null}]},"slots":["paginationContent"],"sourceFile":"src/components/navigation/Pagination.tsx","specSource":"design/navigation.pen","docsUrl":"https://gunjo.dev/docs/components/pagination","stability":"experimental"},{"category":"navigation","name":"rightRail","title":"Right Rail","description":"Secondary side panel for contextual tools and inspector content.","variants":{"keys":["default"],"default":"default"},"styling":{"baseClasses":"flex flex-col h-full border","baseColorHint":"fill=#ffffff | stroke=#e5e7eb@1px","perVariant":[{"key":"default","classes":"flex flex-col h-full border","colorHint":"fill=#ffffff | stroke=#e5e7eb@1px"}]},"slots":["rightRailHeader","rightRailItem"],"sourceFile":"src/components/navigation/RightRail.tsx","specSource":"design/navigation.pen","docsUrl":"https://gunjo.dev/docs/components/right-rail","stability":"experimental"},{"category":"navigation","name":"sidebar","title":"Sidebar","description":"Full sidebar orchestrator with provider, header, nav items, and footer slots.","variants":{"keys":[],"default":null},"styling":{"baseClasses":"","baseColorHint":null,"perVariant":[]},"slots":[],"sourceFile":"src/components/navigation/Sidebar.tsx","specSource":"design/navigation.pen","docsUrl":"https://gunjo.dev/docs/components/sidebar","stability":"experimental"},{"category":"navigation","name":"sidebarItem","title":"SidebarItem","description":"Nested sidebar row with chevron, icon, label, and counter area.","variants":{"keys":["default","active"],"default":"default"},"styling":{"baseClasses":"flex flex-row w-full h-9 rounded-md cursor-pointer","baseColorHint":null,"perVariant":[{"key":"default","classes":"flex flex-row w-full h-9 rounded-md cursor-pointer","colorHint":null},{"key":"active","classes":"flex flex-row w-full h-9 rounded-md cursor-pointer","colorHint":"fill=#f1f5f9"}]},"slots":["HM8cZ","ag7i8"],"sourceFile":"src/components/navigation/SidebarItem.tsx","specSource":"design/navigation.pen","docsUrl":"https://gunjo.dev/docs/components/sidebar-item","stability":"experimental"},{"category":"navigation","name":"tabs","title":"Tabs","description":"A set of layered sections of content—known as tab panels—that are displayed one at a time.","variants":{"keys":["default"],"default":"default"},"styling":{"baseClasses":"flex flex-col w-full rounded-lg border","baseColorHint":"fill=#FFFFFF | stroke=#e2e8f0@1px","perVariant":[{"key":"default","classes":"flex flex-col w-full rounded-lg border","colorHint":"fill=#FFFFFF | stroke=#e2e8f0@1px"}]},"slots":["tabsList","tabsContent"],"sourceFile":"src/components/navigation/Tabs.tsx","specSource":"design/navigation.pen","docsUrl":"https://gunjo.dev/docs/components/tabs","stability":"beta"},{"category":"navigation","name":"textLink","title":"TextLink","description":"Inline text link that automatically shows an external-tab icon when it opens a new tab.","variants":{"keys":["default","muted"],"default":"default"},"styling":{"baseClasses":"inline-flex items-center p-0 gap-1 text-sm font-medium","baseColorHint":"text=#2563eb","perVariant":[{"key":"default","classes":"inline-flex items-center p-0 gap-1 text-sm font-medium","colorHint":"text=#2563eb"},{"key":"muted","classes":"inline-flex items-center p-0 gap-1 text-sm font-medium","colorHint":"text=#0f172a"}]},"slots":[],"sourceFile":"src/components/navigation/TextLink.tsx","specSource":"design/navigation.pen","docsUrl":"https://gunjo.dev/docs/components/text-link","stability":"experimental"},{"category":"overlay","name":"alertDialog","title":"AlertDialog","description":"Modal dialog focused on confirming a destructive or important action.","variants":{"keys":[],"default":null},"styling":{"baseClasses":"","baseColorHint":null,"perVariant":[]},"slots":[],"sourceFile":"src/components/overlay/AlertDialog.tsx","specSource":"design/overlay.pen","docsUrl":"https://gunjo.dev/docs/components/alert-dialog","stability":"experimental"},{"category":"overlay","name":"chatPanel","title":"ChatPanel","description":"Contained chat overlay surface that composes ChatMessage and ChatInput for support, assistant, or team conversation panels.","variants":{"keys":["default","compact"],"default":"default"},"styling":{"baseClasses":"w-full h-[560px] p-0 rounded-lg","baseColorHint":"fill=#ffffff","perVariant":[{"key":"default","classes":"w-full h-[560px] p-0 rounded-lg","colorHint":"fill=#ffffff"},{"key":"compact","classes":"w-full h-[420px] p-0 rounded-lg","colorHint":"fill=#ffffff"}]},"slots":[],"sourceFile":"src/components/overlay/ChatPanel.tsx","specSource":"design/overlay.pen","docsUrl":"https://gunjo.dev/docs/components/chat-panel","stability":"experimental"},{"category":"overlay","name":"contextMenu","title":"ContextMenu","description":"Right-click style action list with labels and nested trigger.","variants":{"keys":["default"],"default":"default"},"styling":{"baseClasses":"flex flex-col items-center w-[192px] p-1 gap-1 rounded-md border","baseColorHint":"fill=#ffffff | stroke=#e2e8f0@1px","perVariant":[{"key":"default","classes":"flex flex-col items-center w-[192px] p-1 gap-1 rounded-md border","colorHint":"fill=#ffffff | stroke=#e2e8f0@1px"}]},"slots":["contextMenuLabelText","contextMenuItem","contextMenuSeparator","contextMenuSubTrigger"],"sourceFile":"src/components/overlay/ContextMenu.tsx","specSource":"design/overlay.pen","docsUrl":"https://gunjo.dev/docs/components/context-menu","stability":"experimental"},{"category":"overlay","name":"dialog","title":"Dialog","description":"Centered modal dialog with overlay, header, and footer actions.","variants":{"keys":["default"],"default":"default"},"styling":{"baseClasses":"flex flex-col w-[512px]","baseColorHint":null,"perVariant":[{"key":"default","classes":"flex flex-col w-[512px]","colorHint":null}]},"slots":["dialogOverlay","dialogContent"],"sourceFile":"src/components/overlay/Dialog.tsx","specSource":"design/overlay.pen","docsUrl":"https://gunjo.dev/docs/components/dialog","stability":"beta"},{"category":"overlay","name":"drawer","title":"Drawer","description":"Mobile-friendly bottom sheet with drag-to-dismiss handle (vaul-based).","variants":{"keys":[],"default":null},"styling":{"baseClasses":"","baseColorHint":null,"perVariant":[]},"slots":[],"sourceFile":"src/components/overlay/Drawer.tsx","specSource":"design/overlay.pen","docsUrl":"https://gunjo.dev/docs/components/drawer","stability":"beta"},{"category":"overlay","name":"dropdownMenu","title":"Dropdown Menu","description":"Displays a menu to the user—such as a set of actions or functions—triggered by a button.","variants":{"keys":["default"],"default":"default"},"styling":{"baseClasses":"flex flex-col w-[180px] rounded-lg border","baseColorHint":"fill=#FFFFFF | stroke=#e2e8f0@1px","perVariant":[{"key":"default","classes":"flex flex-col w-[180px] rounded-lg border","colorHint":"fill=#FFFFFF | stroke=#e2e8f0@1px"}]},"slots":["dropdownMenuLabel","dropdownMenuSeparator","dropdownMenuItem"],"sourceFile":"src/components/overlay/DropdownMenu.tsx","specSource":"design/overlay.pen","docsUrl":"https://gunjo.dev/docs/components/dropdown-menu","stability":"experimental"},{"category":"overlay","name":"floatingPanel","title":"Floating Panel","description":"Animated floating container for transient UI surfaces.","variants":{"keys":["glass"],"default":"glass"},"styling":{"baseClasses":"flex flex-col w-[360px] rounded-2xl border","baseColorHint":"fill=#ffffffcc | stroke=#dddddd@1px","perVariant":[{"key":"glass","classes":"flex flex-col w-[360px] rounded-2xl border","colorHint":"fill=#ffffffcc | stroke=#dddddd@1px"}]},"slots":["floatingPanelTitleBar","floatingPanelContent"],"sourceFile":"src/components/overlay/FloatingPanel.tsx","specSource":"design/overlay.pen","docsUrl":"https://gunjo.dev/docs/components/floating-panel","stability":"experimental"},{"category":"overlay","name":"hoverCard","title":"HoverCard","description":"Rich hover content with compact profile-like layout.","variants":{"keys":["default"],"default":"default"},"styling":{"baseClasses":"flex flex-col items-center w-[256px] p-4 gap-2 rounded-md border","baseColorHint":"fill=#ffffff | stroke=#e2e8f0@1px","perVariant":[{"key":"default","classes":"flex flex-col items-center w-[256px] p-4 gap-2 rounded-md border","colorHint":"fill=#ffffff | stroke=#e2e8f0@1px"}]},"slots":["hoverCardHeader"],"sourceFile":"src/components/overlay/HoverCard.tsx","specSource":"design/overlay.pen","docsUrl":"https://gunjo.dev/docs/components/hover-card","stability":"experimental"},{"category":"overlay","name":"mediaLightbox","title":"MediaLightbox","description":"Full-screen media preview dialog with navigation, wheel/button zoom, click-and-drag pan, double-click toggle between fit-frame and fit-width, and asset actions.","variants":{"keys":["default","compact"],"default":"default"},"styling":{"baseClasses":"w-full p-0","baseColorHint":null,"perVariant":[{"key":"default","classes":"w-full p-0","colorHint":null},{"key":"compact","classes":"w-full p-0","colorHint":null}]},"slots":[],"sourceFile":"src/components/overlay/MediaLightbox.tsx","specSource":"design/overlay.pen","docsUrl":"https://gunjo.dev/docs/components/media-lightbox","stability":"experimental"},{"category":"overlay","name":"mediaPickerDialog","title":"MediaPickerDialog","description":"Media selection dialog with search, AssetGrid rendering, single-select and multi-select confirmation flows.","variants":{"keys":["default","compact"],"default":"default"},"styling":{"baseClasses":"w-full p-0","baseColorHint":null,"perVariant":[{"key":"default","classes":"w-full p-0","colorHint":null},{"key":"compact","classes":"w-full p-0","colorHint":null}]},"slots":[],"sourceFile":"src/components/overlay/MediaPickerDialog.tsx","specSource":"design/overlay.pen","docsUrl":"https://gunjo.dev/docs/components/media-picker-dialog","stability":"experimental"},{"category":"overlay","name":"modal","title":"Modal","description":"Dialog surface with header, content, and optional footer actions.","variants":{"keys":["default"],"default":"default"},"styling":{"baseClasses":"flex flex-col w-[448px] rounded-lg border","baseColorHint":"fill=#ffffff | stroke=#e2e8f0@1px","perVariant":[{"key":"default","classes":"flex flex-col w-[448px] rounded-lg border","colorHint":"fill=#ffffff | stroke=#e2e8f0@1px"}]},"slots":["modalHeader","modalContent","modalFooter"],"sourceFile":"src/components/overlay/Modal.tsx","specSource":"design/overlay.pen","docsUrl":"https://gunjo.dev/docs/components/modal","stability":"experimental"},{"category":"overlay","name":"onboardingFlow","title":"OnboardingFlow","description":"Multi-step guided flow with step indicator, content, and Back/Continue actions.","variants":{"keys":[],"default":null},"styling":{"baseClasses":"","baseColorHint":null,"perVariant":[]},"slots":[],"sourceFile":"src/components/overlay/OnboardingFlow.tsx","specSource":"design/overlay.pen","docsUrl":"https://gunjo.dev/docs/components/onboarding-flow","stability":"experimental"},{"category":"overlay","name":"placePanel","title":"PlacePanel","description":"The details of one place picked on a map, in a panel that comes up from the bottom edge: the place's name, one large value with a caption (the temperature and the sky), and a grid of labelled values. Every row is drawn from the first frame and only the VALUES wait, as fixed-width skeletons, because swapping rows in as each service answers changes the row count and shakes the panel; the panel's height does not change between loading and loaded, so the map above stays still. Each value has three states told apart by the value alone — `undefined` loading (skeleton), `null` could not be fetched (settles to '—' and stops pulsing: a skeleton left pulsing after the request gave up says 'still coming' when nothing is), anything else the value. `aria-busy` while anything is loading. NOT a Sheet: a Sheet is modal (overlay, focus trap, locked page), and a map reader must keep panning while the panel is up — this is a plain landmark the caller places (absolute at the bottom of the map container on a phone, beside the map on a wide screen). The field grid switches to two columns by the panel's own width (container query), not the viewport's. Composes Skeleton, which now stops pulsing under prefers-reduced-motion. Distinct from Sheet / Drawer (modal), DescriptionList / MetadataList (no loading states, not a panel) and Card.","variants":{"keys":["default"],"default":"default"},"styling":{"baseClasses":"","baseColorHint":null,"perVariant":[{"key":"default","classes":"","colorHint":null}]},"slots":[],"sourceFile":"src/components/overlay/PlacePanel.tsx","specSource":"design/overlay.pen","docsUrl":"https://gunjo.dev/docs/components/place-panel","stability":"experimental"},{"category":"overlay","name":"popover","title":"Popover","description":"Displays rich content in a portal, triggered by a button.","variants":{"keys":["default"],"default":"default"},"styling":{"baseClasses":"flex flex-col w-[288px] p-4 rounded-lg border","baseColorHint":"fill=#FFFFFF | stroke=#e2e8f0@1px","perVariant":[{"key":"default","classes":"flex flex-col w-[288px] p-4 rounded-lg border","colorHint":"fill=#FFFFFF | stroke=#e2e8f0@1px"}]},"slots":["popoverContentText","popoverMetaText"],"sourceFile":"src/components/overlay/Popover.tsx","specSource":"design/overlay.pen","docsUrl":"https://gunjo.dev/docs/components/popover","stability":"experimental"},{"category":"overlay","name":"progressDialog","title":"ProgressDialog","description":"Modal wait for long-running work, composed from Dialog: a replaceable 16:9 media area (decorative, aria-hidden), the title and description, the current state in words inside a polite live region, an optional slot, and an optional explicit cancel in the footer. Controlled only: Escape, outside click and the close button are all suppressed, so the caller closes it on success, failure or cancel. Uses Progress: a real value draws a determinate bar; with no value the bar sweeps without a number (no invented percentage). Under reduced motion the sweep stops while the status, slot and cancel remain usable. The body scrolls inside the dialog so the footer stays reachable at 390px. Variants: default stacks the title under the media; overlay lays the title, description and an optional badge over the top of the media on a background-colour scrim.","variants":{"keys":["default","overlay"],"default":"default"},"styling":{"baseClasses":"w-full p-0","baseColorHint":null,"perVariant":[{"key":"default","classes":"w-full p-0","colorHint":null},{"key":"overlay","classes":"w-full p-0","colorHint":null}]},"slots":[],"sourceFile":"src/components/overlay/ProgressDialog.tsx","specSource":"design/overlay.pen","docsUrl":"https://gunjo.dev/docs/components/progress-dialog","stability":"experimental"},{"category":"overlay","name":"shareModal","title":"Share Modal","description":"Dialog for toggling public access and copying shareable URLs.","variants":{"keys":["default"],"default":"default"},"styling":{"baseClasses":"flex flex-col w-[448px] rounded-xl border","baseColorHint":"fill=#ffffff | stroke=#e5e7eb@1px","perVariant":[{"key":"default","classes":"flex flex-col w-[448px] rounded-xl border","colorHint":"fill=#ffffff | stroke=#e5e7eb@1px"}]},"slots":["shareModalHeader","shareModalContent"],"sourceFile":"src/components/overlay/ShareModal.tsx","specSource":"design/overlay.pen","docsUrl":"https://gunjo.dev/docs/components/share-modal","stability":"experimental"},{"category":"overlay","name":"sheet","title":"Sheet","description":"Side panel variant with overlay, heading, and action area.","variants":{"keys":["right"],"default":"right"},"styling":{"baseClasses":"flex flex-col w-[384px]","baseColorHint":null,"perVariant":[{"key":"right","classes":"flex flex-col w-[384px]","colorHint":null}]},"slots":["sheetOverlay","sheetContent"],"sourceFile":"src/components/overlay/Sheet.tsx","specSource":"design/overlay.pen","docsUrl":"https://gunjo.dev/docs/components/sheet","stability":"beta"},{"category":"overlay","name":"tooltip","title":"Tooltip","description":"Compact helper text bubble for hover and focus states.","variants":{"keys":["default"],"default":"default"},"styling":{"baseClasses":"flex flex-row w-[168px] py-1 px-3 rounded-md border","baseColorHint":"fill=#ffffff | stroke=#e2e8f0@1px","perVariant":[{"key":"default","classes":"flex flex-row w-[168px] py-1 px-3 rounded-md border","colorHint":"fill=#ffffff | stroke=#e2e8f0@1px"}]},"slots":["tooltipText","tooltipHintText"],"sourceFile":"src/components/overlay/Tooltip.tsx","specSource":"design/overlay.pen","docsUrl":"https://gunjo.dev/docs/components/tooltip","stability":"experimental"},{"category":"layout","name":"aspectRatio","title":"AspectRatio","description":"Maintains a fixed aspect ratio for media containers (image, video, iframe).","variants":{"keys":[],"default":null},"styling":{"baseClasses":"","baseColorHint":null,"perVariant":[]},"slots":[],"sourceFile":"src/components/layout/AspectRatio.tsx","specSource":"design/layout.pen","docsUrl":"https://gunjo.dev/docs/components/aspect-ratio","stability":"experimental"},{"category":"layout","name":"assetInspectorPanel","title":"AssetInspectorPanel","description":"Media library inspector panel for asset preview, title and note fields, tag editing, metadata rows, and asset actions.","variants":{"keys":["default","compact"],"default":"default"},"styling":{"baseClasses":"w-full p-0","baseColorHint":null,"perVariant":[{"key":"default","classes":"w-full p-0","colorHint":null},{"key":"compact","classes":"w-full p-0","colorHint":null}]},"slots":[],"sourceFile":"src/components/layout/AssetInspectorPanel.tsx","specSource":"design/layout.pen","docsUrl":"https://gunjo.dev/docs/components/asset-inspector-panel","stability":"experimental"},{"category":"layout","name":"cluster","title":"Cluster","description":"Wrapping flex layout — items flow horizontally and wrap onto new lines.","variants":{"keys":[],"default":null},"styling":{"baseClasses":"","baseColorHint":null,"perVariant":[]},"slots":[],"sourceFile":"src/components/layout/Cluster.tsx","specSource":"design/layout.pen","docsUrl":"https://gunjo.dev/docs/components/cluster","stability":"experimental"},{"category":"layout","name":"collapsiblePanelToggle","title":"CollapsiblePanelToggle","description":"Boundary control for opening and closing a collapsible panel from the left, right, top, or bottom edge.","variants":{"keys":["left","right","top","bottom"],"default":"left"},"styling":{"baseClasses":"w-10 h-10","baseColorHint":null,"perVariant":[{"key":"left","classes":"w-10 h-10","colorHint":null},{"key":"right","classes":"w-10 h-10","colorHint":null},{"key":"top","classes":"w-10 h-10","colorHint":null},{"key":"bottom","classes":"w-10 h-10","colorHint":null}]},"slots":[],"sourceFile":"src/components/layout/CollapsiblePanelToggle.tsx","specSource":"design/layout.pen","docsUrl":"https://gunjo.dev/docs/components/collapsible-panel-toggle","stability":"experimental"},{"category":"layout","name":"container","title":"Container","description":"Max-width + horizontal padding wrapper for page content.","variants":{"keys":[],"default":null},"styling":{"baseClasses":"","baseColorHint":null,"perVariant":[]},"slots":[],"sourceFile":"src/components/layout/Container.tsx","specSource":"design/layout.pen","docsUrl":"https://gunjo.dev/docs/components/container","stability":"beta"},{"category":"layout","name":"deviceFrame","title":"DeviceFrame","description":"Browser chrome frame with URL entry, visual chrome variants, and desktop, tablet, and mobile viewport controls for interactive pattern previews.","variants":{"keys":["default","windows11"],"default":"default"},"styling":{"baseClasses":"w-full p-0","baseColorHint":null,"perVariant":[{"key":"default","classes":"w-full p-0","colorHint":null},{"key":"windows11","classes":"w-full p-0","colorHint":null}]},"slots":[],"sourceFile":"src/components/layout/DeviceFrame.tsx","specSource":"design/layout.pen","docsUrl":"https://gunjo.dev/docs/components/device-frame","stability":"experimental"},{"category":"layout","name":"grid","title":"Grid","description":"CSS grid wrapper with cols, gap, and minItemWidth props.","variants":{"keys":[],"default":null},"styling":{"baseClasses":"","baseColorHint":null,"perVariant":[]},"slots":[],"sourceFile":"src/components/layout/Grid.tsx","specSource":"design/layout.pen","docsUrl":"https://gunjo.dev/docs/components/grid","stability":"experimental"},{"category":"layout","name":"hStack","title":"HStack","description":"Horizontal flex layout with gap, align, and justify props.","variants":{"keys":[],"default":null},"styling":{"baseClasses":"","baseColorHint":null,"perVariant":[]},"slots":[],"sourceFile":"src/components/layout/HStack.tsx","specSource":"design/layout.pen","docsUrl":"https://gunjo.dev/docs/components/h-stack","stability":"experimental"},{"category":"layout","name":"inspectorPanel","title":"Inspector Panel","description":"Structured side panel for detailed property editing.","variants":{"keys":["default"],"default":"default"},"styling":{"baseClasses":"flex flex-col w-[320px] h-[420px] border","baseColorHint":"fill=#ffffff | stroke=#e5e7eb@1px","perVariant":[{"key":"default","classes":"flex flex-col w-[320px] h-[420px] border","colorHint":"fill=#ffffff | stroke=#e5e7eb@1px"}]},"slots":["inspectorPanelHeader","inspectorPanelBody"],"sourceFile":"src/components/layout/InspectorPanel.tsx","specSource":"design/layout.pen","docsUrl":"https://gunjo.dev/docs/components/inspector-panel","stability":"experimental"},{"category":"layout","name":"marqueeFrame","title":"MarqueeFrame","description":"Scaled fake-browser viewport wrapper for marquee pattern pages. It keeps pattern content and overlays scoped to the active preview viewport.","variants":{"keys":["default","desktop","tablet","mobile"],"default":"default"},"styling":{"baseClasses":"w-full p-0","baseColorHint":null,"perVariant":[{"key":"default","classes":"w-full p-0","colorHint":null},{"key":"desktop","classes":"w-full p-0","colorHint":null},{"key":"tablet","classes":"w-full p-0","colorHint":null},{"key":"mobile","classes":"w-full p-0","colorHint":null}]},"slots":[],"sourceFile":"src/components/layout/MarqueeFrame.tsx","specSource":"design/layout.pen","docsUrl":"https://gunjo.dev/docs/components/marquee-frame","stability":"experimental"},{"category":"layout","name":"resizable","title":"Resizable","description":"Pane group with draggable handle and optional grip indicator.","variants":{"keys":["horizontal"],"default":"horizontal"},"styling":{"baseClasses":"flex","baseColorHint":null,"perVariant":[{"key":"horizontal","classes":"flex","colorHint":null}]},"slots":["resizablePanelGroup","resizableHandle"],"sourceFile":"src/components/layout/Resizable.tsx","specSource":"design/layout.pen","docsUrl":"https://gunjo.dev/docs/components/resizable","stability":"experimental"},{"category":"layout","name":"scrollArea","title":"ScrollArea","description":"Custom scrollbar container with viewport and thumb controls.","variants":{"keys":["default"],"default":"default"},"styling":{"baseClasses":"flex flex-col","baseColorHint":null,"perVariant":[{"key":"default","classes":"flex flex-col","colorHint":null}]},"slots":["scrollAreaViewport","scrollAreaScrollbar"],"sourceFile":"src/components/layout/ScrollArea.tsx","specSource":"design/layout.pen","docsUrl":"https://gunjo.dev/docs/components/scroll-area","stability":"experimental"},{"category":"layout","name":"spatialCanvas","title":"Spatial Canvas","description":"Large grid-based interaction surface for node and layout editing.","variants":{"keys":["default"],"default":"default"},"styling":{"baseClasses":"flex flex-col","baseColorHint":"fill=#f9fafb","perVariant":[{"key":"default","classes":"flex flex-col","colorHint":"fill=#f9fafb"}]},"slots":["spatialCanvasHint","spatialCanvasHintDetail"],"sourceFile":"src/components/layout/SpatialCanvas.tsx","specSource":"design/layout.pen","docsUrl":"https://gunjo.dev/docs/components/spatial-canvas","stability":"experimental"},{"category":"layout","name":"vStack","title":"VStack","description":"Vertical flex layout with gap, align, and justify props.","variants":{"keys":[],"default":null},"styling":{"baseClasses":"","baseColorHint":null,"perVariant":[]},"slots":[],"sourceFile":"src/components/layout/VStack.tsx","specSource":"design/layout.pen","docsUrl":"https://gunjo.dev/docs/components/v-stack","stability":"beta"},{"category":"patterns","name":"authTemplate","title":"Auth Template","description":"Split authentication layout with branded panel and centered form.","variants":{"keys":["default"],"default":"default"},"styling":{"baseClasses":"flex w-full","baseColorHint":null,"perVariant":[{"key":"default","classes":"flex w-full","colorHint":null}]},"slots":["authTemplateVisualPanel","authTemplateFormPanel"],"sourceFile":"src/components/patterns/AuthTemplate.tsx","specSource":"design/patterns.pen","docsUrl":"https://gunjo.dev/docs/components/auth-template","stability":"experimental"},{"category":"patterns","name":"bannalyzeTemplate","title":"Bannalyze Template","description":"Three-region analysis workspace with center canvas and side inspectors.","variants":{"keys":["default"],"default":"default"},"styling":{"baseClasses":"flex flex-col w-full h-full","baseColorHint":"fill=#ffffff","perVariant":[{"key":"default","classes":"flex flex-col w-full h-full","colorHint":"fill=#ffffff"}]},"slots":["bannalyzeTemplateHeader","bannalyzeTemplateBody"],"sourceFile":"src/components/patterns/BannalyzeTemplate.tsx","specSource":"design/patterns.pen","docsUrl":"https://gunjo.dev/docs/components/bannalyze-template","stability":"experimental"},{"category":"patterns","name":"blogTemplate","title":"blogTemplate","description":null,"variants":{"keys":[],"default":null},"styling":{"baseClasses":"","baseColorHint":null,"perVariant":[]},"slots":[],"sourceFile":"src/components/patterns/BlogTemplate.tsx","specSource":"design/patterns.pen","docsUrl":"https://gunjo.dev/docs/components/blog-template","stability":"experimental"},{"category":"patterns","name":"chatTemplate","title":"Chat Template","description":"Conversation layout with channel rail, message area, and detail pane.","variants":{"keys":["default"],"default":"default"},"styling":{"baseClasses":"flex w-full h-full","baseColorHint":"fill=#ffffff","perVariant":[{"key":"default","classes":"flex w-full h-full","colorHint":"fill=#ffffff"}]},"slots":["chatTemplateSidebarList","chatTemplateMainArea","chatTemplateSidebarDetail"],"sourceFile":"src/components/patterns/ChatTemplate.tsx","specSource":"design/patterns.pen","docsUrl":"https://gunjo.dev/docs/components/chat-template","stability":"experimental"},{"category":"patterns","name":"dashboardTemplate","title":"Dashboard Template","description":"Two-column dashboard shell with optional header and sidebar.","variants":{"keys":["default"],"default":"default"},"styling":{"baseClasses":"flex flex-col w-full","baseColorHint":null,"perVariant":[{"key":"default","classes":"flex flex-col w-full","colorHint":null}]},"slots":["dashboardTemplateHeader","dashboardTemplateBody"],"sourceFile":"src/components/patterns/DashboardTemplate.tsx","specSource":"design/patterns.pen","docsUrl":"https://gunjo.dev/docs/components/dashboard-template","stability":"experimental"},{"category":"patterns","name":"docsTemplate","title":"docsTemplate","description":null,"variants":{"keys":[],"default":null},"styling":{"baseClasses":"","baseColorHint":null,"perVariant":[]},"slots":[],"sourceFile":"src/components/patterns/DocsTemplate.tsx","specSource":"design/patterns.pen","docsUrl":"https://gunjo.dev/docs/components/docs-template","stability":"experimental"},{"category":"patterns","name":"editorTemplate","title":"Editor Template","description":"Panel-based editing layout with top bar and side docks.","variants":{"keys":["default"],"default":"default"},"styling":{"baseClasses":"flex flex-col w-full h-full","baseColorHint":null,"perVariant":[{"key":"default","classes":"flex flex-col w-full h-full","colorHint":null}]},"slots":["editorTemplateTopBar","editorTemplateBody"],"sourceFile":"src/components/patterns/EditorTemplate.tsx","specSource":"design/patterns.pen","docsUrl":"https://gunjo.dev/docs/components/editor-template","stability":"experimental"},{"category":"patterns","name":"kanbanTemplate","title":"Kanban Template","description":"Board workflow shell with optional sidebar and horizontal columns.","variants":{"keys":["default"],"default":"default"},"styling":{"baseClasses":"flex w-full h-full","baseColorHint":null,"perVariant":[{"key":"default","classes":"flex w-full h-full","colorHint":null}]},"slots":["kanbanTemplateSidebar","kanbanTemplateMain"],"sourceFile":"src/components/patterns/KanbanTemplate.tsx","specSource":"design/patterns.pen","docsUrl":"https://gunjo.dev/docs/components/kanban-template","stability":"experimental"},{"category":"patterns","name":"landingTemplate","title":"Landing Template","description":"Marketing page skeleton with sticky header and section rhythm.","variants":{"keys":["default"],"default":"default"},"styling":{"baseClasses":"flex flex-col w-full","baseColorHint":null,"perVariant":[{"key":"default","classes":"flex flex-col w-full","colorHint":null}]},"slots":["landingTemplateHeader","landingTemplateHero","landingTemplateFeatureSection"],"sourceFile":"src/components/patterns/LandingTemplate.tsx","specSource":"design/patterns.pen","docsUrl":"https://gunjo.dev/docs/components/landing-template","stability":"experimental"},{"category":"patterns","name":"mediaLibraryTemplate","title":"Media Library Template","description":"Asset management workspace with folders, grid area, and details pane.","variants":{"keys":["default"],"default":"default"},"styling":{"baseClasses":"flex flex-col w-full h-full","baseColorHint":"fill=#ffffff","perVariant":[{"key":"default","classes":"flex flex-col w-full h-full","colorHint":"fill=#ffffff"}]},"slots":["mediaLibraryTemplateHeader","mediaLibraryTemplateBody"],"sourceFile":"src/components/patterns/MediaLibraryTemplate.tsx","specSource":"design/patterns.pen","docsUrl":"https://gunjo.dev/docs/components/media-library-template","stability":"experimental"},{"category":"patterns","name":"onboardingTemplate","title":"onboardingTemplate","description":null,"variants":{"keys":[],"default":null},"styling":{"baseClasses":"","baseColorHint":null,"perVariant":[]},"slots":[],"sourceFile":"src/components/patterns/OnboardingTemplate.tsx","specSource":"design/patterns.pen","docsUrl":"https://gunjo.dev/docs/components/onboarding-template","stability":"experimental"},{"category":"patterns","name":"pricingTemplate","title":"Simple pricing that scales with usage, not complexity.","description":"Choose monthly for flexibility or yearly for the best unit economics. Every plan includes shared projects, role-based access, and workflow analytics.","variants":{"keys":["default"],"default":"default"},"styling":{"baseClasses":"flex flex-col items-center w-full gap-8","baseColorHint":null,"perVariant":[{"key":"default","classes":"flex flex-col items-center w-full gap-8","colorHint":null}]},"slots":["j0i4u","c2Q5YO"],"sourceFile":"src/components/patterns/PricingTemplate.tsx","specSource":"design/patterns.pen","docsUrl":"https://gunjo.dev/docs/components/pricing-template","stability":"experimental"},{"category":"patterns","name":"responsiveAuthCardPattern","title":"Responsive Auth Card Pattern","description":"Responsive authentication card with Japanese labels, validation, and typed submit callbacks.","variants":{"keys":["default"],"default":"default"},"styling":{"baseClasses":"flex flex-col items-center w-full py-10 px-4 gap-6","baseColorHint":"fill=#000000","perVariant":[{"key":"default","classes":"flex flex-col items-center w-full py-10 px-4 gap-6","colorHint":"fill=#000000"}]},"slots":["T1VaJ","HlI3Z","dg3KD","DTyPr"],"sourceFile":"src/components/patterns/ResponsiveAuthCardPattern.tsx","specSource":"design/patterns.pen","docsUrl":"https://gunjo.dev/docs/components/responsive-auth-card-pattern","stability":"experimental"},{"category":"patterns","name":"settingsTemplate","title":"Settings Template","description":"Responsive settings layout with mobile stack and desktop split view.","variants":{"keys":["default"],"default":"default"},"styling":{"baseClasses":"flex flex-col items-center w-full gap-4","baseColorHint":null,"perVariant":[{"key":"default","classes":"flex flex-col items-center w-full gap-4","colorHint":null}]},"slots":["settingsTemplateMobileView","settingsTemplateDesktopView"],"sourceFile":"src/components/patterns/SettingsTemplate.tsx","specSource":"design/patterns.pen","docsUrl":"https://gunjo.dev/docs/components/settings-template","stability":"experimental"}]}