Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions README.ko.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ Mossland 생태계를 탐색하는 지도와 Algora, AO, Bridge의 픽셀 아트

## 모니터 탐색

기본 화면은 **Map**입니다. 레지스트리 항목은 Official, Participation, Developers, Markets, Ecosystem 영역별 궤도에 배치됩니다. 천체에 마우스를 올리면 상세 정보가 표시됩니다. Algora, AO, Bridge를 클릭하면 상세 화면이 열리고, 다른 항목은 해당 목적지로 이동합니다. 모니터 자신의 천체를 클릭하면 지도 중앙으로 돌아옵니다.
기본 화면은 **Map**입니다. 레지스트리 항목은 Official, Participation, Developers, Markets, Ecosystem 영역별 궤도에 배치됩니다. 천체에 마우스를 올리면 상세 정보가 표시됩니다. Algora, AO, Bridge를 클릭하면 상세 화면이 열리고, 다른 항목은 해당 목적지로 이동합니다. 터치스크린에서는 천체를 처음 탭하면 상세 정보가 표시되고, 같은 천체를 한 번 더 탭하면 열립니다. 빈 곳을 탭하거나 정보 패널을 열면 상세 정보가 닫힙니다. 모니터 자신의 천체는 지금 보고 있는 이 페이지를 나타내므로, 클릭해도 아무것도 열리지 않습니다. 키보드나 화면 낭독기로는 정보 패널의 Ecosystem 목록에서 모든 천체를 같은 상태 정보와 함께 링크로 찾을 수 있습니다.

| 지도 형태 | 의미 |
| --- | --- |
Expand All @@ -26,11 +26,11 @@ Mossland 생태계를 탐색하는 지도와 Algora, AO, Bridge의 픽셀 아트
| Listed only | 레지스트리에 등록되어 있지만 상태 측정값은 없습니다. |
| Link or file | 거래소 링크, 소셜 계정, 공개 파일 등의 참조 항목입니다. 서비스 상태 집계에서 제외합니다. |

색상은 `ok`, `degraded`, `down`, 또는 해석 가능한 측정값 없음을 나타내며, `running`처럼 계약 밖의 상태 값도 측정값 없음에 포함됩니다. `down`이나 `degraded`인 천체는 이름표에도 그 상태를 글자로 표시하므로, 판정을 색상만으로 전달하지 않습니다. 보관·폐기된 항목도 지도에 남기되, 상태 색상 **대신** 흐린 보관 색상으로 그립니다. 측정된 상태가 있으면 마우스를 올렸을 때의 툴팁과 사이드바에 그대로 표시되고, `down`이나 `degraded`이면 이름표에도 표시됩니다.
색상은 `ok`, `degraded`, `down`, 또는 해석 가능한 측정값 없음을 나타내며, `running`처럼 계약 밖의 상태 값도 측정값 없음에 포함됩니다. `down`이나 `degraded`인 천체는 이름표에도 그 상태를 글자로 표시하므로, 판정을 색상만으로 전달하지 않습니다. 보관·폐기된 항목도 지도에 남기되, 상태 색상 **대신** 흐린 보관 색상으로 그립니다. 측정된 상태가 있으면 툴팁과 사이드바에 그대로 표시되고, `down`이나 `degraded`이면 이름표에도 표시됩니다.

지도 상단과 사이드바의 Ecosystem 패널은 서비스가 보고한 상태를 셉니다. `ok`, `off-contract`, `degraded`, `down`, `unmeasured`를 각각 따로 세고, 서비스만 대상으로 하며(링크와 파일은 세지 않음), 보관된 서비스도 다른 서비스와 마찬가지로 측정값에 따라 셉니다. `off-contract`, `degraded`, `down`을 보고한 서비스는 이름을 표시하고, 사이드바의 해당 행에도 그 판정을 글자로 붙이며, Ecosystem 패널은 이 집계와 이름을 맨 앞에 보여 줍니다. 패널이 낮은 지도 위에 놓이는 768~1100px에서는 지도 상단에 서비스 수와 측정 시각만 두고, 보고된 상태의 집계와 이름은 패널에 맡깁니다. 지도 위에 여유 공간이 있는 세로 방향 태블릿에서는 지도 상단에도 표시합니다. 높이가 700px 미만인 휴대폰에서는 지도 상단의 이름 목록을 생략하고 천체 이름표와 정보 패널에 맡깁니다. 하나라도 down이나 degraded이면 페이지 제목 앞에 `(1 down)`처럼 개수가 붙습니다. 숨겨진 탭은 폴링하지 않으므로(아래 참고) 제목은 탭이 숨겨지기 전의 마지막 측정값을 보여 주며, 그 뒤에 down이 된 서비스는 반영하지 못합니다. 다만 다른 화면과 같은 기준으로 오래된 측정값임을 표시합니다. 사이드바에는 레지스트리 항목과 라이프사이클, 서비스 수, API 응답 여부, 거버넌스 수치도 표시됩니다.

**Map / Algora / AO / Bridge** 탭은 데스크톱과 모바일 모두에서 동작합니다. 768px 미만에서는 메뉴 버튼으로 정보 패널을 열며, 닫힌 패널에 가려지는 데이터 API의 `LIVE` / `OFFLINE` / `CONNECTING` 상태를 지도 상단에도 표시합니다. 768~1100px에서는 패널이 스테이지 위에 배치됩니다. 모바일 기준 너비를 넘나들면 캔버스를 맞추기 위해 앱을 새로 불러옵니다. 모션 감소 설정을 사용하면 지도 회전과 활동 효과가 억제되고 탭 전환 시 카메라 이동 애니메이션이 생략됩니다.
**Map / Algora / AO / Bridge** 탭은 데스크톱과 모바일 모두에서 동작하며, 키보드에서는 화살표 키와 Home, End 키로 탭 사이를 이동합니다. 768px 미만에서는 메뉴 버튼으로 정보 패널을 열고 Escape 키나 패널 바깥을 탭해 닫습니다. 패널이 열려 있는 동안 Tab 키는 패널과 메뉴 버튼 사이에서만 이동합니다. 또한 닫힌 패널에 가려지는 데이터 API의 `LIVE` / `OFFLINE` / `CONNECTING` 상태를 지도 상단에도 표시합니다. 768~1100px에서는 패널이 스테이지 위에 배치됩니다. 휴대폰에서는 각 상세 화면을 화면 위쪽에 두고, 그 아래 카드에 캔버스로는 너무 작아 읽을 수 없는 내용인 최신 토론, 아이디어와 점수, 벨트 위의 신호, 에이전트 신뢰도 평균, 최근 결과를 보여 줍니다. 카드에는 해당 서비스의 `LIVE` / `OFFLINE` / `CONNECTING` 표시가 붙고, 서비스가 응답하지 않으면 목록을 최신 내용이 아니라 마지막으로 받은 내용이라고 표시합니다. 모바일 기준 너비를 넘나들면 캔버스를 맞추기 위해 앱을 새로 불러옵니다. 모션 감소 설정을 사용하면 지도 회전과 활동 효과가 억제되고, 상세 벨트의 트레드와 봇 애니메이션, 에이전트 깜박임이 멈추며 항목은 미끄러지지 않고 한 칸씩 끊어서 움직이고(Algora의 신호와 Bridge의 제안은 단계별로, AO의 아이디어는 일정한 간격으로 움직이다가 도달한 점수 기준선 위에 표시), 탭 전환 시 카메라 이동 애니메이션이 생략됩니다. 페이지를 연 상태에서 설정을 바꿔도 바로 반영됩니다.

## 거버넌스 상세 화면

Expand Down Expand Up @@ -80,7 +80,7 @@ npm test
npm run build
```

[GitHub Actions](.github/workflows/ci.yml)는 대상 브랜치와 관계없이 모든 풀 리퀘스트와, 병합이 끝난 `main`에 대해 같은 검사를 실행한 뒤 빌드가 올바른 `dist/health.json`을 생성했는지 확인합니다(`node scripts/check-health-json.mjs`). 풀 리퀘스트 없이 푸시한 브랜치는 자동으로 검사하지 않으므로, 초안 풀 리퀘스트를 열거나 워크플로를 직접 실행하세요. 테스트는 상태 응답 해석, 생태계 피드의 판정·병합·폴링(레지스트리의 빠른 재시도와 상태 측정값이 오래된 것으로 바뀌는 시점 포함), 상태 집계와 페이지 제목, 서비스 데이터 폴러의 연결 상태·폴링 일정(탭이 숨겨졌을 때의 일시 정지 포함)·신호 중복 제거·서비스별 통계와 신호 기준점·상세 화면 총계, 사이드바와 지도 툴팁이 마크업에 쓰는 값과 바뀌지 않은 사이드바 패널을 다시 쓰지 않는 동작, 그리고 오리진이 빌드를 서빙하는 방식(없는 파일은 404, 디렉터리 목록 없음)을 검증합니다. 해당 코드를 수정할 때는 `npm run test:watch`를 사용할 수 있습니다.
[GitHub Actions](.github/workflows/ci.yml)는 대상 브랜치와 관계없이 모든 풀 리퀘스트와, 병합이 끝난 `main`에 대해 같은 검사를 실행한 뒤 빌드가 올바른 `dist/health.json`을 생성했는지 확인합니다(`node scripts/check-health-json.mjs`). 풀 리퀘스트 없이 푸시한 브랜치는 자동으로 검사하지 않으므로, 초안 풀 리퀘스트를 열거나 워크플로를 직접 실행하세요. 테스트는 상태 응답 해석, 생태계 피드의 판정·병합·폴링(레지스트리의 빠른 재시도와 상태 측정값이 오래된 것으로 바뀌는 시점 포함), 상태 집계와 페이지 제목, 서비스 데이터 폴러의 연결 상태·폴링 일정(탭이 숨겨졌을 때의 일시 정지 포함)·신호 중복 제거·서비스별 통계와 신호 기준점·상세 화면 총계, 사이드바, 지도 툴팁, 휴대폰 상세 카드가 마크업에 쓰는 값과 바뀌지 않은 사이드바 패널을 다시 쓰지 않고 다시 쓴 링크의 키보드 포커스를 유지하는 동작, 지도의 탭 선택과 텍스트 배치, 모션 감소 설정, 탭 막대의 키 조작과 휴대폰 서랍의 포커스, 그리고 오리진이 빌드를 서빙하는 방식(없는 파일은 404, 디렉터리 목록 없음)을 검증합니다. 해당 코드를 수정할 때는 `npm run test:watch`를 사용할 수 있습니다.

```bash
npm run preview # 프로덕션 빌드를 로컬에서 확인
Expand Down
8 changes: 4 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ The map separates **what exists**, **what can be observed**, and **what a servic

## Explore the monitor

**Map** is the default view. Registry entries orbit by section: Official, Participation, Developers, Markets, and Ecosystem. Hover over a body for details; click Algora, AO, or Bridge to open its detail view, or other entries to visit their destination. Clicking the monitor's own body recenters the map.
**Map** is the default view. Registry entries orbit by section: Official, Participation, Developers, Markets, and Ecosystem. Hover over a body for details; click Algora, AO, or Bridge to open its detail view, or other entries to visit their destination. On a touch screen the first tap on a body shows its details and a second tap on the same body opens it; a tap on empty space, or opening the information panel, dismisses them. The monitor's own body marks this page, so clicking it opens nothing. From the keyboard or a screen reader, every body is also a link in the information panel's Ecosystem list, with the same reported health.

| Map form | Meaning |
| --- | --- |
Expand All @@ -26,11 +26,11 @@ The map separates **what exists**, **what can be observed**, and **what a servic
| Listed only | The registry lists the service, but no health reading is available. |
| Link or file | A reference such as an exchange listing, social account, or published file; excluded from service health counts. |

Colour shows `ok`, `degraded`, `down`, or no interpretable measurement, which includes an off-contract status such as `running`. A `down` or `degraded` body also carries the word on its label, so the verdict never rests on colour alone. Archived/deprecated entries stay visible, drawn in a dimmed archived colour **instead of** a health colour; their measured health, if any, is still shown in the hover tooltip, in the sidebar, and on the label when it is `down` or `degraded`.
Colour shows `ok`, `degraded`, `down`, or no interpretable measurement, which includes an off-contract status such as `running`. A `down` or `degraded` body also carries the word on its label, so the verdict never rests on colour alone. Archived/deprecated entries stay visible, drawn in a dimmed archived colour **instead of** a health colour; their measured health, if any, is still shown in the tooltip, in the sidebar, and on the label when it is `down` or `degraded`.

The map heading and the sidebar's Ecosystem panel count what the services report: `ok`, `off-contract`, `degraded`, `down` and `unmeasured`, one bucket each, services only (links and files are not counted), with archived services counted by their reading like any other. Every service reporting `off-contract`, `degraded` or `down` is named, and its sidebar row carries that verdict as text; the Ecosystem panel leads with the counts and names. Between 768px and 1100px, where the panel sits above a short map, the heading keeps only the service counts and the reading time and leaves the tally and names to the panel; a portrait tablet has room above the map, so its heading keeps them too. On a phone less than 700px tall the heading leaves the names to the body labels and the panel. While anything is down or degraded the page title starts with a count, e.g. `(1 down)`. A hidden tab does not poll (see below), so its title shows the last reading taken before it was hidden and cannot pick up a service that goes down afterwards; it does turn stale on the same clock as everything else. The sidebar also lists registry entries and lifecycle labels, service counts, API reachability, and governance figures.

The **Map / Algora / AO / Bridge** tabs work on desktop and mobile. Below 768px, the information panel opens from the menu button, and the map heading shows the data APIs' `LIVE` / `OFFLINE` / `CONNECTING` state that the closed panel would otherwise hide; between 768px and 1100px it sits above the stage. Crossing the mobile breakpoint reloads the app to fit its canvas. Reduced-motion preferences suppress map rotation and activity effects and remove tab-switch camera transitions.
The **Map / Algora / AO / Bridge** tabs work on desktop and mobile; from the keyboard, the arrow keys, Home and End move between them. Below 768px, the information panel opens from the menu button and closes with Escape or a tap beside it; while it is open, Tab moves only between it and the menu button. The map heading there shows the data APIs' `LIVE` / `OFFLINE` / `CONNECTING` state that the closed panel would otherwise hide; between 768px and 1100px the panel sits above the stage. On a phone each detail view sits at the top of the screen, above a card with the text its canvas is too small to show there: the latest debates, ideas and their scores, the signals on the belt, the agent trust average and recent outcomes. The card carries the service's `LIVE` / `OFFLINE` / `CONNECTING` badge, and once the service has not answered it calls its lists the last received rather than the latest. Crossing the mobile breakpoint reloads the app to fit its canvas. Reduced-motion preferences suppress map rotation and activity effects, stop the detail belts' treads, bots and blinking agents and move their items in steps instead of sliding (Algora's signals and Bridge's proposals stage by stage, AO's ideas a fixed distance at a time and onto each score threshold they reach), and remove tab-switch camera transitions; a change to the preference applies while the page is open.

## Governance detail views

Expand Down Expand Up @@ -80,7 +80,7 @@ npm test
npm run build
```

[GitHub Actions](.github/workflows/ci.yml) runs these checks on every pull request, whatever its base branch, and on `main` after each merge, then confirms the build emitted a well-formed `dist/health.json` (`node scripts/check-health-json.mjs`). A branch pushed without an open pull request is not tested automatically; open a draft pull request or run the workflow by hand. Tests cover health-response interpretation; the ecosystem feed's grading, merging and polling, including the registry's early retry and when health readings turn stale; the status counts and page title; the service-data poller's connection state, polling schedules (including the pause while hidden), signal deduplication, the per-service stats and signal baselines, and detail-view totals; the values the sidebar and the map's tooltip write into their markup, and the sidebar leaving unchanged panels alone; and how the origin serves a build (404 for missing files, no directory listing). Use `npm run test:watch` while working on those readers.
[GitHub Actions](.github/workflows/ci.yml) runs these checks on every pull request, whatever its base branch, and on `main` after each merge, then confirms the build emitted a well-formed `dist/health.json` (`node scripts/check-health-json.mjs`). A branch pushed without an open pull request is not tested automatically; open a draft pull request or run the workflow by hand. Tests cover health-response interpretation; the ecosystem feed's grading, merging and polling, including the registry's early retry and when health readings turn stale; the status counts and page title; the service-data poller's connection state, polling schedules (including the pause while hidden), signal deduplication, the per-service stats and signal baselines, and detail-view totals; the values the sidebar, the map's tooltip and the phone's detail card write into their markup, and the sidebar leaving unchanged panels alone and keeping keyboard focus on a link it rewrites; the map's tap selection and where its text is placed; the reduced-motion setting; the tab bar's keys and the phone drawer's focus; and how the origin serves a build (404 for missing files, no directory listing). Use `npm run test:watch` while working on those readers.

```bash
npm run preview # inspect the production build locally
Expand Down
12 changes: 12 additions & 0 deletions src/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,18 @@ const game = new Phaser.Game({
: { mode: Phaser.Scale.FIT, autoCenter: Phaser.Scale.CENTER_BOTH },
});

// The canvas has no text of its own, and was exposed as an unnamed image.
// #stageNote, which the tabpanel (#stage) takes as its description, is its
// text alternative: it says where every body can be reached from the
// keyboard. Hidden from screen readers only — pointer and touch are
// untouched, and the canvas takes no focus. Phaser boots at once when the
// document is already parsed, as it is for this module script; otherwise
// the canvas arrives with BOOT, and an optional chain alone would have
// dropped the attribute silently.
const hideCanvas = () => game.canvas.setAttribute("aria-hidden", "true");
if (game.canvas) hideCanvas();
else game.events.once(Phaser.Core.Events.BOOT, hideCanvas);

/**
* Keep one bad frame from killing the page.
*
Expand Down
Loading
Loading