Skip to content

UI Structure

Purpose

This file is the compact UI contract for new or migrated application screens.

Reference

  • Core reference page: frontend/pages/platform/ui/pilot.php.
  • Runtime helpers:
  • app/shared/ui/structure.php
  • app/shared/ui/shell.php
  • app/shared/ui/runtime.php
  • Default MK modal/table runtime:
  • KJModal
  • kjTable
  • Do not use new POPUP.createDialog, $.fn.kjtable, KJTABLE.buildOption, or direct window.KJTABLE option-builder paths on new or migrated screens.
  • Use KJTableUtilities for remaining shared upload, file viewer, HTML escaping, and bulk-closing helpers while the legacy KJTABLE global is being retired.

Product UI Direction

  • Dense operations UI, not marketing UI.
  • Stable surface language across pages.
  • Fast scanning, visible state, compact controls.
  • Minimize user clicks and manual input: when the next action is unambiguous, open the required editor or workflow directly instead of inserting an intermediate screen or confirmation button. Keep explicit confirmation only for irreversible, security-sensitive, or concrete data-integrity-risk actions.
  • Use tokens and shared components before page-specific CSS.

Page Pattern

app shell
  header / context chips
  section shell
    summary / primary controls
    table or workspace
  modal
    form
    state snapshot

Density

Mode Use
comfy overview, admin, onboarding
compact default operations screen
dense tables, grids, high-frequency data entry

Defaults: - Operational pages: compact. - Tables: dense. - Modal forms: compact, with dense rows only for repetitive line items.

Layout Tokens

Token Value
Section radius 20px
Sub-card radius 16px
Field/button radius 12px
Modal radius 22px
Page title 24px
Section title 16px
Body text 13px
Micro label 11px
Table text 12px
Dense row height 32-36px
Compact field height 34-36px
Dense field height 30-32px

Typography Standard

  • Application sans: Montserrat, "Helvetica Neue", sans-serif.
  • Code and identifiers: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace.
  • Supported weights are 400, 500, 600, and 700. Use heavier legacy values only while preserving an existing screen.
  • Page title: 24px / 600 / 1.2; section title: 16px / 600 / 1.2; body: 13px / 400 / 1.5; field label and table: 12px / 500 / 1.35; micro label: 11px / 500 / 1.2.
  • Strong text uses slate 900, normal text slate 700, secondary text slate 500, and disabled text slate 400.

Spacing Standard

  • Use a 4px base unit and the supported scale 4, 8, 12, 16, 20, 24, 32px.
  • Prefer parent gap for spacing between sibling controls. Do not add ad-hoc margins to every field.
  • Modal header, body, and footer own their internal padding. Modal action groups use an 8px gap and the footer keeps at least 14px 18px padding.
  • Compact form grids use 12-16px gaps. Related fields share one section; unrelated sections use a 16px gap.
  • A long field may span the full grid. Short fields should share a row when their labels and values remain readable.

Surface Rules

  • Page background uses bg.
  • Main content uses panel.
  • Secondary/read-only areas use panelAlt.
  • Sidebar uses the dark shell.
  • Semantic colors are for status chips, validation, and alerts only.
  • Do not nest card inside card unless the inner area is a distinct interactive workspace.
  • Avoid decorative section header bars on MK operations pages.

Component Rules

Form System

  • KJForm is the common field contract for Pilot, newly migrated KJModal screens, and explicitly migrated standalone forms. It owns control, label, Tom Select, validation, and field-state styling.
  • KJModal owns only the modal shell (header, body, footer, action placement, and shared spacing). Modal-specific field CSS must not replace KJForm defaults.
  • Reuse KJForm classes and enhancers before adding a screen-local field/select style. Promote a repeated, justified exception to KJForm rather than copying it between screens.
  • Legacy pages and legacy popups remain unchanged by this rule. Convert only a screen explicitly requested by the user, validate its actual workflow, then proceed to the next screen.
  • Screen-specific field grids may vary by business purpose, importance, and expected value length; the underlying field formatting remains KJForm unless a documented exception is required.

App Shell

  • Fixed navigation shell where applicable.
  • Content width should support dense operational tables.
  • Mobile must remain usable, even if table actions degrade to horizontal scroll.

Section Shell

  • Use for grouping an operational unit.
  • Prefer summary text and controls over decorative titles.
  • Do not add explanatory subtext, captions, or subtitles that merely restate the section title or obvious current state. Add one only when it changes the operator's next action or communicates a real constraint.
  • Keep one main purpose per section.

Toolbar / Filter Bar

  • Put primary filters before secondary actions.
  • Keep filter height compact.
  • Use chips for active filters or selected rows.

Button

  • Primary action: one per local context.
  • Secondary actions: neutral.
  • Destructive actions: explicit confirmation.
  • Disabled state must explain itself through visible copy or context.

Field

  • Label must remain visible.
  • Validation message must be visible.
  • Use dense controls only when repeated rows require it.

Status Chip

  • Chip text must use domain status names.
  • Color reinforces state but cannot be the only signal.

Data Table

  • Header stays clear and compact.
  • Empty state must say what the user can do next.
  • Row actions must be predictable and aligned.
  • Loading/error states must be visible.
  • Active list schemas use the KJTable api-v2 adapter with an explicit /api/... endpoint. The adapter requires data.items and a non-negative numeric data.total; malformed success payloads must surface as visible errors rather than empty tables.

Timeline / Operational Board

  • Timeline boards are read-only unless the user explicitly requests editing controls.
  • Keep the left identity/status column stable and use horizontal scrolling for time ranges on narrow viewports.
  • Use semantic block styles for job type, idle time, active work, and issue states.
  • Detail drawers should show source record context and correction guidance without creating a second editing path.
  • For loader timeline screens, T_STAFF_TIME_EVENT is the display source for clock/job events. T_LOADING_PLANNER can be joined for job context, but corrections should happen on the source event or job/planner record that produced the event.

Staff Time Controls

  • Inbound-loader staff clock controls use compact status plus one primary action: Clock In when clocked out, Clock Out when working. When the logged-in loader is working and has an office-created scheduled break/lunch queue row for today as the primary assigned loader, show a secondary Start Break/Start Lunch button beside Clock Out.
  • Loader self-service Break In/Out controls must not be shown as always-available actions. Loader break/lunch start is only available for an existing office-created break queue row where that loader is the primary assigned loader; managers may still use correction flows.
  • Telegram staff time must not show persistent Clock In/Clock Out reply keyboards. Existing typed clock commands or old reply-keyboard text should only remove the keyboard and direct users to the inbound-loader page.
  • Telegram break queue messages must not show inline Start 10MIN BREAK / Start LUNCH BREAK buttons. They should include the inbound-loader link, and old break callback buttons should only direct users to the inbound-loader page. Break/lunch starts are recorded from the inbound-loader assigned break queue start flow.
  • Loader Timeline remains read-only by default. Manager/Admin users may enable Manage Time mode to add, edit, or delete clock in/out events and add break/lunch corrections with a required correction reason.
  • Loader Timeline renders break/lunch blocks from paired BREAK_IN/BREAK_OUT staff-time events and is manager-only. Manager-created or inbound-loader queue-started 10MIN BREAK and LUNCH BREAK rows create BREAK_IN; the protected Telegram cron closes expired breaks with BREAK_OUT and sends the next queued job Telegram when one is ready.
  • Loader Timeline time range defaults to 7 AM-6 PM, supports Auto expansion for out-of-range events, and may expose wider selectable ranges with horizontal scrolling.
  • Modal title describes the operation.
  • Do not repeat the operation as a status badge beside the close button. Header status is reserved for an actual business state such as Hold, Failed, or Completed.
  • Include context snapshot when editing operational records.
  • Keep submit/cancel placement consistent.
  • Group fields by business meaning and size the grid by expected value length instead of rendering one vertical list.
  • Escape closes the topmost modal unless a destructive or incomplete action explicitly requires a confirmation step.
  • Do not hide API errors.

Prohibitions

  • Do not create page-specific design systems.
  • Do not add decorative gradients or large marketing blocks to operations pages.
  • Do not hide key state in tooltips only.
  • Do not create silent empty states.
  • Do not use new legacy popup/table APIs on newly migrated screens.

Implementation Order

  1. Use existing UI helpers/tokens.
  2. Build shell and section layout.
  3. Add table/workspace.
  4. Add modal/form.
  5. Verify dense and mobile layouts.
  6. Check visible loading, empty, validation, and error states.

Telegram-Origin UI Requests

  • Treat any UI work requested through Telegram as requiring browser runtime verification before reporting completion.
  • Treat any user-facing logic change requested through Telegram as requiring the same browser runtime workflow verification, even when the visible UI code did not change.
  • The browser run must use the relevant page, role/session, inputs, buttons, and modal/page transitions that a real user would use. Confirm the final visible state, such as modal closed, row moved, refreshed status, success message, or visible validation error.
  • Do not count server logs, database rows, or HTTP 200 responses alone as UI/workflow verification. JSON APIs must also return parseable JSON without PHP warnings/notices/deprecations injected into the response body.
  • Capture at least one screenshot showing the affected UI after the change. Include additional screenshots for modal, mobile, or error states when those states are part of the requested work.
  • Include screenshots directly in the Telegram message body/attachment for the response. Do not send only a local file path or textual screenshot reference.
  • Local DB writes needed for login, setup, reversible smoke records, or runtime verification are pre-approved for Telegram-origin UI work. Use the local DB target rules in .agents/rules/DEV_ENV.md, keep writes scoped to verification, and document what was written or why no write was needed.
  • Production DB writes and schema changes still require explicit separate confirmation.

Acceptance Criteria

Local Assignment Board candidate

  • Inbound Planning keeps compact Assign Work, Clock Out, and Add Break header actions with page-local modal/card patterns.
  • Assigned JSON work is concealed on Loader as NEXT ASSIGNMENT; Start reveals server-backed detail/timer. Batch results remain per Loader and expose Telegram retry.
  • Started Clock Out hides the general Clock Out button and presents only the workflow action. A Final Break Clock Out shows cleaning first when required, then Start Final 10-Minute Break, a server-offset remaining timer, and workflow Clock Out only after the server threshold; it never shows Clock Back In.

  • Page matches shared density and surface rules.

  • Primary user action is obvious.
  • Table and modal errors are visible.
  • Keyboard/mouse interactions do not dead-end.
  • No console errors on load.
  • No new one-off UI helper unless repetition threshold is met.
  • Telegram-origin UI work includes runtime test evidence and directly attached screenshot evidence.

---

Source: .agents/rules/UI_STRUCTURE.md — ctc repository · This page is an English translation of the source document. Identifiers, file paths and code symbols are unchanged.