# Standing TV design audit — 1 November 2026

**Status:** Approved and implemented on 1 November 2026. The developer approved all DA-001–DA-005 in the conversation. No commit or deployment was requested.

## Scope and baseline

- Target: `standing-tv.html` for Ruang A–D. `index.html` and `data-jadwal.js` were inspected where they determine display content and operation.
- The directory has no `.git` repository, so a revision and dirty status are unavailable. The baseline is the files inspected on 1 November 2026.
- No `AGENTS.md`, `PRODUCT.md`, or active `DESIGN.md` exists in this project.

## Project brief from evidence

| Aspect | Evidence and confidence |
| --- | --- |
| Audience | **Inferred, high confidence:** visitors reading room schedules; panitia operating the screen. The README calls `index.html` a panitia portal and documents TV shortcuts. This is an intended role, not user research. |
| Main task | **Observed:** find the room, current or next session, its topic and speakers, and the local time. `standing-tv.html` renders three sessions per room with three subthemes and speakers each (`renderCards`, lines 669–830). |
| Content | **Observed:** four rooms, three hourly sessions per room, nine subthemes and nine speakers per room. Source data is explicitly dummy data (`data-jadwal.js`, lines 1–11). Names and times should not be presented as a verified event schedule. |
| Platform | **Observed:** static HTML/CSS/JavaScript in a browser, designed for portrait 9:16; optional 90° rotation, fullscreen and Wake Lock (`README.md`; `standing-tv.html`, lines 43–126, 956–975). |
| Input | **Observed:** unattended display with optional keyboard and mouse operator actions (`README.md`; `standing-tv.html`, lines 388–398, 977–999). Touch is mentioned in the CSS comments, but actual hardware and touch use are **unknown**. |
| Identity | **Observed:** UNAIR blue `#002147`, yellow `#FFC72C`, Plus Jakarta Sans, and `pattern-unair.png` (`standing-tv.html`, lines 9–40, 79–85, 341–357). Whether this is an approved brand system is **unknown**. |
| Constraints | **Observed:** the frame is fixed to viewport height, contents may scroll with hidden scrollbar (`standing-tv.html`, lines 79–94); edits persist in browser `localStorage` (`data-jadwal.js`, lines 273–283). Cross-tab updates use `storage` events (`standing-tv.html`, lines 965–969), which do not synchronize separate devices. |

## Method and coverage

Primary guidance: [Impeccable](https://github.com/pbakaus/impeccable), cached revision `5adaee704634e9031ec8943721c4ffa1a3c22221`, adapted to noninteractive browser signage. Its critique, audit, operate, and distill references informed hierarchy, technical inspection, and reduction of decorative layers. The upstream launcher, detector, and edit commands were not run; their cache is guidance only under the [design-audit workflow](/Users/mohammadsubkhan/dev/design-guidance-library/skills/design-audit/SKILL.md).

Initial audit coverage was source-based: before the first session, current session, between sessions, after all sessions, room switching, editor markup, fullscreen/rotation code, and same-origin storage updates. The first Zen browser attempt returned a blank capture. After approval, Safari responsive preview rendered the revised page at 540×960 and 1080×1920, including a before-session view for rooms A and D and a current-session view for room A. A 1920×1080 landscape preview with `?rotate=cw` showed the rotated content. The operator modal was opened by keyboard and inspected with visible focus and labeled fields. Screenshots were viewed in the tool but not saved as files.

## Findings and proposed changes

| ID | Priority / confidence | Finding and user impact | Proposed correction | Acceptance check / effort |
| --- | --- | --- | --- | --- |
| DA-001 | P1 / high for code risk; actual clipping unverified | **Unattended content can be hidden.** The fixed-height frame scrolls while its scrollbar is hidden (lines 79–94), and all three cards and nine speaker rows are rendered at once (lines 693–830). A long title or smaller portrait output can leave content below the fold, with no operator to scroll. | Build a single-screen schedule hierarchy: show the most relevant session with all three subthemes and speakers; retain the other two as clear time-and-title summaries. Before the first session, feature the next session; after the last, show the day summary. Keep every session accessible in the operator editor. Remove hidden overflow as a way to fit content. | At 1080×1920 and 540×960, no content or footer is clipped for longest supplied titles, before/during/between/after states; no scroll is needed. **Medium.** |
| DA-002 | P1 / high | **The visual hierarchy is crowded and generic.** Repeated pills, rounded cards inside a card, a glow shadow, pulse, microphone emoji, two large watermarks and all-heavy text compete with topic and speaker names (lines 186–325, 341–357, 709–829). | Keep blue/yellow identity; use a flat editorial timetable, aligned time column, thin rules, one yellow current-state marker, and restrained type weights. Remove glow, pulse, emoji, decorative watermarks, nested cards, and redundant labels. | A viewer can identify room, current/next status, time, topic and speaker in that order; no decorative animation remains. **Medium.** |
| DA-003 | P1 / high | **“WIB” may be wrong.** The clock and session matching use `Date#getHours()` in the device timezone while the header and time pills say WIB (lines 375–384, 633–646, 669–690). A TV configured outside `Asia/Jakarta` can show the wrong current session. | Derive display clock, date, and session comparisons from `Asia/Jakarta`; make the time treatment legible and consistent. | With a browser timezone outside WIB, the displayed time/date and highlighted session still match Jakarta time. **Small.** |
| DA-004 | P2 / high for code; visual result unverified | **Display controls occupy the masthead and have weak affordance.** The icon buttons are tiny and dim (lines 388–398, 327–332), while the footer text is also a navigation link (lines 407–412). On a TV, these compete with room and schedule; for an operator they can be hard to find or focus. | Move setup actions to a clearly named operator entry state; keep keyboard shortcuts. Hide controls during unattended display but reveal them on pointer/keyboard activity with visible focus and accessible labels. Keep footer institutional text as text. | Setup remains reachable by keyboard and pointer, focus is visible, idle screen has no controls, and `P`, `F`, `R`, `1`–`4` still work. **Small–medium.** |
| DA-005 | P2 / high | **Network failure can damage the display.** Tailwind, font, and Lucide are loaded from external CDNs (lines 9–15). If unavailable, utility classes and icons will not render as designed. | For a TV deployment, package required CSS/font/icon assets locally or replace the few needed icons with native text/SVG. Do not add a framework. | Reload with network disabled and confirm the screen remains styled and readable. **Medium.** |

### Positive baseline

The project already has a clear room identifier, explicit session times, a solid institutional palette, a portrait scaling mechanism, current/next/past state logic, and keyboard shortcuts for operators. These should remain functional.

## Proposed implementation packages

1. **Signage composition (DA-001, DA-002):** edit `standing-tv.html` CSS and `renderCards()` output. Use one prominent session and two summaries with no timed page transitions. Preserve all supplied titles, speaker strings, status logic, room selection, and the editor data contract. Add a concise no-session state for before/after the schedule.
2. **Operational accuracy (DA-003, DA-004):** edit clock/session calculations and controls in `standing-tv.html`; adjust `index.html` clock/current indicators only where they would contradict the TV. Keep operator shortcuts and editor save/reset behavior.
3. **TV resilience (DA-005):** replace CDN runtime dependencies used by the TV with local equivalents. This needs no paid service; any font file or package asset should be license checked before inclusion. Keep portal changes limited to shared dependencies if necessary.
4. **Documentation:** after approval, merge the accepted system from `DESIGN.proposed.md` into a new root `DESIGN.md`; update `README.md` with accurate deployment and display guidance. No dependencies, new imagery, migration, or backend is proposed.

**Verification after approval:** inspect actual 1080×1920 and 540×960 renders, rotated landscape output, all four rooms, longest strings, current/next/past states, keyboard focus, modal opening/closing, and offline loading. Check that `scrollHeight <= clientHeight` for the unattended frame and that Jakarta time determines statuses. Physical TV viewing distance, panel overscan, orientation hardware, and cross-device synchronization remain unknown; no claim of physical-device validation is made.

**Tradeoff:** showing one detailed session at a time gives its speakers room to read. The other two remain visible by time and main title; their subthemes and speakers remain in the editor/data but are not shown simultaneously on the unattended screen. This is the proposed information priority, subject to the developer decision below.

## Developer decision

The developer chose **implement all DA-001–DA-005** in the conversation on 1 November 2026. This authorized the application and design-document changes listed above, not publishing or deployment.

## Implementation record

All five IDs are implemented:

- **DA-001/DA-002:** Replaced three dense cards with one detailed session and two time/title summaries in `standing-tv.html`, `standing-tv.css`, and `standing-tv.js`. Removed glow, pulse, emoji, nested cards, and decorative watermark. The frame has no unattended scroll. Before/after states are labeled truthfully.
- **DA-003:** Added `getJakartaTimeParts()` in `data-jadwal.js`; the TV and portal use Jakarta time for clocks, date, session state, and around-now presets (`standing-tv.js`, `index.html`).
- **DA-004:** Added a text-labeled operator toolbar that appears on activity, visible keyboard focus, pressed room/rotation states, and a labeled editor dialog. Preserved fullscreen, rotation, room shortcuts, save, and reset.
- **DA-005:** Removed all remote stylesheet, font, and icon requests from the TV page. `standing-tv.css` and `standing-tv.js` are local. The portal still has its prior CDN dependencies, documented in `README.md`.
- **Documentation:** `DESIGN.md` is the active contract; `README.md` explains the new display, local runtime, and same-browser storage boundary. This proposed document remains the audit snapshot.

**Checks performed:** `TZ=UTC node --test tests/signage.test.cjs` passed 3 tests for Jakarta time, session boundaries/featured choice, and escaped operator text. `node --check` passed for `standing-tv.js`, `data-jadwal.js`, and both inline portal scripts. Safari showed the full content and footer at 540×960 and 1080×1920 for the inspected rooms, plus a rotated 1920×1080 preview. The around-now preset produced the expected live session; the original demo schedule was restored afterward. Source inspection confirms the TV HTML/CSS/JS have no remote URLs.

**Remaining verification limits:** No physical standing TV was available for reading distance, overscan, browser Wake Lock, or HDMI rotation checks. Safari preview does not prove behavior on every TV browser. Room B/C and unusually long operator-edited strings were not visually inspected. The portal still requires a network connection for its current styling. Cross-device schedule sync remains outside this visual scope and still requires a shared data source.
