@@ -91,6 +91,62 @@ func floorSVG(floor domain.Floor, t trail, idx int) template.HTML {
9191 return template .HTML (b .String ()) //nolint:gosec // built here from escaped parts; node text/attrs all pass html.EscapeString
9292}
9393
94+ // floorCards renders the universe as worlds-only "door" cards (ADR 0006 §5):
95+ // the universe lists worlds, never loose documents. Each card reads as a door at
96+ // rest — a container glyph, the world name, a trailing chevron — affordances a
97+ // document row never has. Federated/remote worlds (portals) get a dashed,
98+ // external-link treatment: visibly "a server you connect to," not a local world
99+ // you enter. This is the default cold-entry view; floorSVG is the "view as map".
100+ func floorCards (floor domain.Floor , t trail , idx int ) template.HTML {
101+ if len (floor .Worlds ) == 0 {
102+ return template .HTML (`<p class="floor-empty">The universe is empty — no worlds visible to your identity.</p>` ) //nolint:gosec // static markup
103+ }
104+ var b strings.Builder
105+ b .WriteString (`<ul class="worlds">` )
106+ for _ , fw := range floor .Worlds {
107+ cls := "world-card"
108+ var href string
109+ if fw .Portal {
110+ cls += " federated"
111+ href = trailURL (trailAfterClick (t , idx , paneAddr {Kind : paneDoc , World : fw .World .Name , Value : "/" }))
112+ } else {
113+ href = trailURL (trailAfterClick (t , idx , paneAddr {Kind : paneFloor , World : fw .World .Name }))
114+ }
115+ if fw .Err {
116+ cls += " gone"
117+ }
118+ fmt .Fprintf (& b , `<li><a class="%s" href="%s">` , cls , html .EscapeString (href ))
119+ b .WriteString (`<span class="world-glyph" aria-hidden="true">▤</span>` )
120+ fmt .Fprintf (& b , `<span class="world-name">%s</span>` , html .EscapeString (fw .World .Name ))
121+ switch {
122+ case fw .Portal :
123+ b .WriteString (`<span class="world-tag">federated · sign-in</span><span class="world-chev" aria-hidden="true">↗</span>` )
124+ case fw .Err :
125+ b .WriteString (`<span class="world-tag">unreadable</span>` )
126+ default :
127+ b .WriteString (`<span class="world-chev" aria-hidden="true">›</span>` )
128+ }
129+ b .WriteString (`</a></li>` )
130+ }
131+ b .WriteString (`</ul>` )
132+ return template .HTML (b .String ()) //nolint:gosec // built from html.EscapeString'd parts only
133+ }
134+
135+ // floorViewToggle is the "view as map / worlds" switch (ADR 0006 §5): the
136+ // universe is worlds-by-default, with the federation topology a deliberate
137+ // secondary view at ?view=map.
138+ func floorViewToggle (t trail , mapView bool ) template.HTML {
139+ base := trailURL (t )
140+ if mapView {
141+ return template .HTML (`<a class="floor-view" href="` + html .EscapeString (base ) + `">← worlds</a>` ) //nolint:gosec // escaped
142+ }
143+ sep := "?"
144+ if strings .Contains (base , "?" ) {
145+ sep = "&"
146+ }
147+ return template .HTML (`<a class="floor-view" href="` + html .EscapeString (base + sep + "view=map" ) + `">view as map →</a>` ) //nolint:gosec // escaped
148+ }
149+
94150// floorSystem renders one authorized world: the world node (zooms into the
95151// world map) plus its top-importance documents as satellites on an orbit ring.
96152func floorSystem (b * strings.Builder , fw domain.FloorWorld , c floorPoint , t trail , idx int ) {
0 commit comments