# UNAIR signage and admin design contract

## Identity

Use UNAIR blue `#002147`, deep blue `#00152E`, yellow `#FFC72C`, and near-white `#F7F8F6`. Keep surfaces calm, with readable contrast and visible focus; reserve subtle depth for the active TV session. Use locally hosted `Plus Jakarta Sans`, with `sans-serif` as fallback, across TV, portal, and admin. Use `pattern-unair.png` for the favicon, brand mark, and a sparse, irregular, low-opacity watermark on the public portal and TV. Avoid gradients, glow, and attention-seeking animation.

## Admin panel

The admin uses official shadcn/ui React components, a responsive sidebar/dashboard composition, and Tailwind theme tokens. Use blue for navigation and primary actions, deep blue for secondary navigation surfaces, near-white for the workspace, white for forms/tables, and yellow with blue text for selected states and accents. Destructive actions use a semantic red.

All labels and feedback are in Bahasa Indonesia. Forms have explicit labels, field validation, pending states, and keyboard support. Dialogs retain accessible titles and focus management. Tables offer search and pagination; schedules filter by event, room, and WIB date. Mobile navigation uses the shadcn sheet. Editing order uses labeled up/down controls rather than requiring dragging.

The navigation covers Ringkasan, Acara, Ruangan, Narasumber, Jadwal sesi, Pratinjau TV, and Profil. Saved changes become public immediately. Admin controls must clearly identify destructive operations and explain referenced-record deletion conflicts.

## Public portal

The portal is read-only and uses the same palette. It lists database events and assigned rooms, full session details, ordered topics/speakers, and canonical TV links. Counts reflect actual data. Public assets and fonts are local, without CDN runtime dependencies. Room-only legacy links require an explicit event selection.

## Standing TV

Render WIB seconds at 55% of the hour/minute size on the same baseline, preserving the full semantic timestamp. Use distinct status badges: green with a live dot for ongoing, gold with a clock for upcoming, and muted gray with a check for completed. Give the white ongoing card a shallow gold edge and restrained shadow, without tilting, scaling, or changing stacking contexts. Dim completed cards through darker navy surfaces and muted readable text/accent colors rather than opacity on the entire card, so watermarks remain behind the text. These styles follow session status rather than card position.

The 9:16 screen prioritizes room, event, current/next session, its time, topics, and speakers. Keep the blue canvas, minimally rounded session cards, yellow structural rule, WIB clock with seconds, room category, and date footer. Place the gold uppercase room category above the large white room name. Full timestamps determine states across days and midnight. Before/between sessions feature the next; after the final session feature the final completed session. Only an ongoing session uses a white surface, navy text, green status dot, and circulating gold border segment. Upcoming and completed sessions use blue surfaces and light text regardless of card position. Use a 12-second linear SVG stroke-dashoffset animation for the border without gradients or glow; under reduced motion, show a static gold outline. Calculate the thin gold progress bar from saved start/end timestamps, clamping to 0–100%. Update progress without rebuilding the cards each second.

Use a single decorative watermark layer behind all text and above the flat card surfaces. Reuse the existing `pattern-unair.png` with its source file and proportions unchanged. CSS renders neutral silhouettes with difference blending, making the marks light on blue surfaces and dark on white. Keep the existing ten images and three classes, but use compact sizes: four small at 50px, four medium at 65px, and two large at 80px at 1080×1920, scaling down with smaller canvases. Use selected points from the Wayang Kreatif reference's 260px staggered tile with a 24px inset and alternating half-tile offsets; scale coordinates with the portrait unit. Preserve distinct CSS custom properties for each mark's duration, negative delay, and drift direction. Use 35–53 second alternating `translate3d()` loops with smooth easing, 64–70px travel, constant 5% opacity, no pointer events, and clipped screen boundaries. Disable watermark animation under `prefers-reduced-motion`. Align topic numbers and their text using the first baseline rather than their top edges.

Show at most two sessions with full ordered topic and speaker lists. Keep the current/next session in the first card. Cycle other sessions through the second card every 10 seconds, completing each session's continuation pages before moving on. If there is only one session, use the available schedule space for that card. Pack topic rows to their content height with compact padding, and emphasize speaker names with bold text and yellow accents. Highlight ongoing, upcoming, and completed states with labeled badges.

When either card exceeds measured screen capacity, split its full content into continuation pages at word boundaries (character boundaries only for oversized individual words), show a page indicator, and advance every 10 seconds. Content that fits remains static. Unchanged polling responses do not reset pages. Pause continuation and session rotation while the settings dialog is open; remeasure when the local font finishes loading or screen dimensions change.

Use natural wrapping without ellipsis. Preserve the existing font scale and never reduce `--fit` below `0.68`. No unattended scrolling. Keep a visible inset for overscan. Validate 540×960, 1080×1920, and 1920×1080 rotated output with long titles and multiple speakers. Physical reading distance and overscan still require actual TV verification.

The read-only settings dialog provides dynamic room selection and rotation. `P` opens settings, `F` fullscreen, `R` rotation, and `1–9` select the first nine assigned rooms. Use compact 32px icon buttons for settings and fullscreen, with accessible labels, tooltips, and an updated fullscreen exit icon. The toolbar starts hidden and appears only on pointer movement/press, touch, wheel, keyboard activity, or focus. Fade it and hide the cursor after 3.5 idle seconds. Pointer clicks must not pin controls through lingering focus; closing settings starts a fresh idle countdown. Keep controls available while the dialog is open or a toolbar button has keyboard focus. Lifting a finger must not dismiss the controls immediately. Schedule editing occurs only in the authenticated admin.

## Data and connection states

Fetch the event/room schedule immediately and poll every 15 seconds. Re-render only when data or time-derived session state changes. Cache the last successful response per event and room; on temporary failure show it with a subtle last-update warning while retrying. Confirmed deleted/missing assignments clear that cache. Provide loading, empty, unavailable, and offline-without-cache states. Cached data supports an already loaded screen, not offline application startup.
