← Cycles
Qmap · c29

look-and-feel

activecreated 2026-11-03· last activity 2026-11-03

Visual look and feel, hierarchy, and labeling — tuned by hand

Why

The data pipeline (c22 → c28) is proven. What's left is how the map reads: visual language, how hierarchy (rugs, nesting, actor prominence) comes across, and how labels are placed and sized. This is a hands-on tuning cycle — iterate directly in the scene rather than plan-then-execute.

Outcome

TBD

Working mode

Manual, iterative adjustment. Record each notable adjustment below as a dated entry (what changed, why, before/after if a screenshot exists). Thread prompts go in this directory as <thread>-prompt.md when a thread grows its own artifacts.

Starting point

  • Experiment surface: dev/experiments/c29.look-and-feel/ — forked from c28.live-qcontrol-stream
  • Opens in Fixture source mode (deterministic, no bridge needed); SSE/Poll still available via the toolbar
  • Light-rig localStorage key renamed (c29LookAndFeelLightRig) so tuning here doesn't disturb c28

Areas

  • Look & feel — materials, colors, lighting, line/flow styling, background
  • Hierarchy — rug nesting, rug weight/contrast by level, actor prominence
  • Labeling — actor and rug labels: size, placement, density, truncation, collisions

Adjustments

  • 2026-11-03 — Design scenarios as the working material. Design c101's six finding sessions (handoff: design-c101-finding-sessions.md) become the scenes we tune against. Scenario 1, The stranger on the phone (Vanta MCP), is staged as the page's default C101 Scenario source with Dataflows on.
    • Data: shared/data/c101-finding-sessions.json is a copy of design's export, and design owns it. shared/c101Scenarios.js maps c101 kinds to placeholder meshes and one rug per kind, and holds hand-written flows per scenario. Only vanta has flows so far.
    • Finding marks: a temporary ⚑ label prefix, with policy, severity and outcome in tags. Favicons now read tags.domain so the prefix doesn't break them.
    • Placeholders: provider and model share the vendor mesh.
  • 2026-11-03 — Zones rug hierarchy, now the default grouping. Mark's spec:
    • Internet: MCP servers, models (and providers), HTTP destinations.
    • Endpoint: the person stands on it directly.
      • Provider Account (personal or business): harness, tools.
      • Repo · Workspace: files, skills.

    Endpoint, account and repo are now rugs, not actors. Flows through them are spliced out (A → X → B becomes A → B), so harness → account → Anthropic now reads harness → Anthropic. Flows with only one side, like repo → Read, are dropped. Each rug's subheading is the name of the tag it was grouped by (ZONE_GROUP_BY in shared/c101Scenarios.js). A ⚑ on an account now sits in its rug label. Pre-split meshes are unchanged.
  • 2026-11-03 — Inside Internet, models, providers and MCP servers moved to their own AI Services rug (subheading "Models · MCP"). HTTP destinations stay on the Internet rug itself. The other names considered were Connected Services, AI Endpoints and Agent Services.
  • 2026-11-03 — AI Services promoted to a top-level rug, outside Internet. Mark: "even though they're on the internet, let's make them their own rug … outside of the internet". The three top-level rugs are now AI Services, Internet (HTTP destinations only) and the Endpoint. Scenario 1 has no destinations, so its Internet rug doesn't draw.
  • 2026-11-03 — Every actor is a plain grey sphere, and actor labels show on hover only, so the scene reads by hierarchy alone while rugs are tuned.
    • Sphere: shared/PlaceholderSphereMesh.js, experiment-only. Default and selected stay grey; highlighted, warning and ignored keep their scheme colors. To bring the meshes back, set usePlaceholderSpheres = false in ExperimentsApp.vue.
    • Labels: actorLabelMode is set to hover. It's still adjustable in the Controls panel.
  • 2026-11-03 — The harness is the one non-sphere pawn: the stock AgentMesh icosahedron with a small hat (a brim and crown), at 4x size, still and without bobbing. Its base is lifted to line up with the spheres. It lives in shared/HarnessMesh.js, and is also used for the root process in live data.
    • Layout: the layout still gives it a one-actor cell, so it overhangs the back corner of the account rug.
    • Hover label: the camera frames the scene by the rugs, not by mesh height, so the label sits under the page header.
    • Color: it keeps AgentMesh's black default state, not the spheres' grey.
  • 2026-11-03 — Replaced by an existing model. Mark: "use our existing models, I see the helpers. can we split the grey one with the red hat out of the pair". The harness is now the grey, red-hatted helper, split out of the MagicaVoxel Helpers pair.
    • How it was split: scripts/split-helpers.py keeps the faces at y ≥ 0.7 that aren't purple, caps the two feet the export had culled where the figures touched, and drops the model onto y=0. Output: assets/helper-grey/Helper Grey.{obj,mtl,png}, 134 vertices and 100 faces. It stays in c29, so c23's manifest is untouched.
    • Size and placement: 4x the sphere height (1.76), with its base level with the spheres' bases, original colors, and no state tint. Its hover label now shows.
    • The hat: in the source geometry it sits 2 voxels (0.2) above the body (body top y=1.4, hat bottom y=1.6).
  • 2026-11-03 — The account rug label is now just its class: ⚑ personal (or business). The full name ("dana's Claude Pro · personal") was stretching the rug. Mark: "That long name isn't working well here.. it's stretching out the rug". The rug shrank, and the workspace rug now packs beside it inside the Endpoint.
  • 2026-11-03 — A View toggle in the toolbar, Isometric | Flat, bound to config.camera.cameraPreset.
    • What Flat does: Flat is qmap's flatland preset: a top-down camera, with voxel models (the harness helper) pitched up to face it. The spheres look the same either way.
    • Behaviour when switching: the model pose flips at once, while the camera animates over, so for a moment the helper lies flat in the isometric view.
  • 2026-11-03 — The page now opens in Flat. The harness helper now renders unlit: voxel materialMode: "original", a MeshBasicMaterial with the exact palette colors. Scene lighting was washing it out. Face-on in Flat it reads like the 2D pixel pawn. In Isometric its faces are all the same tone, so it loses shading. The other modes (original-lit, override…) are in c23's voxAssetLoader.js.
  • 2026-11-03 — The Controls panel's sections (camera, appearance, labels, behavior, dataflow, lighting) now start closed. This needed a new optional collapsed prop on q-nuxt-layer's dev/Configurator.vue, passed through to ControlSection's existing collapsed prop. It defaults to false, so other users of the panel are unchanged. The change is uncommitted in q-nuxt-layer, alongside that repo's other unrelated uncommitted edits.
  • 2026-11-03 — A rugs section in Controls: rugStrokeColor, rugStrokeWidth (0.5–6px) and rugFillDepth0–3, all applied live.
    • How it works: shared/rugStyle.js writes into COLORS.rugDepth, which new rugs read, and calls a new GroupRug.refreshStyle() on the rugs already on screen. Both rug-creation paths (initial load and transitions) pick it up without extra wiring. The section stays out of QMap props.
    • src change (src/boundaries/GroupRug.js): the rug border is now Line2 + LineMaterial, because LineBasicMaterial is always 1px in WebGL. COLORS.rugDepth.borderWidth defaults to 1, so the look is unchanged by default.
    • Not exposed yet: fill opacity is still the global 0.2.
  • 2026-11-03 — Color controls use a hex picker in place of the browser's native picker, whose UI opens on RGB. It's in q-nuxt-layer's dev/ControlColor.vue: a saturation/brightness square, a hue strip and a hex field, teleported to the body, and it opens upward when there's no room below. The props and events are unchanged, so every page using DevControlColor now gets it. Uncommitted in q-nuxt-layer.
  • 2026-11-03 — More picker and rug-default changes, from Mark:
    • HSB fields: the picker gained H (0–360), S and B (0–100) number fields above the hex row. Mark: "keep the picker, but use hsb".
    • New c29 rug defaults: every fill is F5F5F5 (depths 4 and up follow step 3). The border is 2px D9D9D9.
    • Labels in the lower left: a new rugLabelAlign control (left or right) defaults to left. In src/boundaries/GroupRug.js, the label position (duplicated in create and resize) became _positionLabel(), the canvas text aligns to match, and refreshStyle() rebuilds the label when the alignment changes. COLORS.rugDepth.labelAlign defaults to 'right', so other pages are unchanged.
  • 2026-11-03 — Rug label typography. The name is Inter semibold (600) at 75%, and the small heading is Inter bold (700) at 50%. The new controls are rugNameWeight, rugNameScale, rugHeadingWeight and rugHeadingScale.
    • src changes: src/styles/labelMetrics.js gains RUG_LABEL_STYLE (defaults 500 / 400 at 1×, the shipped look) and layoutRugLabel(). GroupRug and measureLabelWidth both use it now, where each used to carry its own copy of the fonts and sizes.
    • Why the label height changed: it is now canvas pixels × a fixed world-per-pixel. It used to be a fixed 0.7 or 0.5 × scale, which stretched smaller fonts back up to the same size.
    • Live changes: refreshStyle() rebuilds a label when its alignment or typography changes. Layout spacing that depends on label width only updates on the next rebuild.
    • Font loading: Inter still isn't loaded by the page; it's installed on Mark's machine.
    • Heading bump: Mark: "increase sub 25%". The heading went from 50% to 62.5%, and the slider step is now 0.025. Endpoint, account and repo use service, app and database until the c101 pawns exist.
  • 2026-11-03 — Tool treatments, a side-by-side comparison page (tool-treatments.html, linked from the dev app as c29.tool-treatments). The same scenario three ways: labels on lines, tool belt and expanding stack. Mark: tools "as 3d objects with as much space as a harness feels wrong." The main c29 page still draws tools as pawns.
    • Code: shared/toolTreatments.js (tool data and sessions), shared/toolGraphics.js (line tags, chips, stack pawn), components/ToolTreatmentMap.vue (one panel). shared/c29Config.js now holds the config both pages share.
    • Stand-in: repo reads have no actor to land on now that the repo is a rug, so these panels add an infra-tools files actor that isn't in design's cast.
    • src fix (src/core/cameraAnimation.js): the camera animation token was module-wide, so each map's camera move cancelled the others on a multi-map page. It is now per camera.
    • Fit: QMap's default fit assumed the isometric angle even in Flat, which drew wide scenes too small and clipped tall ones. Fixed at the source: useActorSelection now reads the active camera preset, and a preset change refits (QMap.vue). Isometric pages use the same numbers as before; c25 was reloaded as a check. Panels still refit on resize.
    • Fixes after first look: line tags sit 68% of the way along their flow from the harness, and the harness's chips go across its body, so both clear the personal label. Stack clicks are caught before QMap's click handler, because letting selection run zoomed the camera and never opened the stack.
    • View toggle: the page header has an Isometric | Flat switch for all three maps; each panel refits after a switch.
    • Status: checked in the browser with no console errors: chip hover, stack open and close, and the toggle.
    • Fourth treatment, Tools box: Mark: "adds the word tools above a simple box with a number similar to the expanding stack, but without the stack of items". One flat box per owner with its tool count and the word "Tools" above it, with the same data and click to open or close as the stack (createToolBoxMesh in shared/toolGraphics.js). The page is now four panels across, or 2×2 under 1500px wide.
    • Exploration menu: header checkboxes show or hide each treatment, with the first (Labels on lines) hidden by default. The grid fits whatever is showing (four wrap to 2×2 under 1500px wide). A hidden panel is unmounted, so an opened stack or box resets when it comes back.
    • Tools sit where they run: Mark: "let's move the tools over to vanta's rug". MCP tools now go on their server's rug (AI Services) in c101Scenarios.js, so the main page changes too; built-in tools stay with the harness. The Stack and Box panels place their boxes the same way.
    • Harness rug (Tools box panel only): Mark: "add a rug for the harness and let the tools and the agent pixel pawn live on it". A third rug level inside Provider Account holds the helper and the built-in box, or its opened tools. "Agent pixel pawn" was read as the grey helper; design's actual AgentPawn SVG art isn't used.
    • Footprint (src): actor.footprint on src/layout/ActorItem.js reserves layout room for an oversized pawn; it defaults to the old 1×1. The harness now uses 2×2 on every scenario map (c101Scenarios.js), including the main page.
    • Flat centering: Mark: going from Isometric to Flat, pawns don't "take the front surface size in to consideration for item centering the mesh over it's location". Pitching laid each voxel model along -z from its base. applyModelPose in c23's createVoxModelEntity.js now centers the model's face over its location and keeps the label below the face, which replaces the earlier harness-only workaround. It's shared code, so any voxel model in Flat changes, including c25's; c25 was checked with models centered and labels below.
    • Red account rug: Mark: "with the provider account rug, will you make it red and 4px". Default was 4px EF4444 (the scheme's warning red; now DC2626) with rugAccountStrokeColor and rugAccountStrokeWidth controls, on both c29 pages and for any account type. In src, a by-category override on COLORS.rugDepth changes a rug's border; it's empty by default.
    • Border stretch fix (src/boundaries/GroupRug.js): Mark noticed fatter horizontal lines. three r160 doesn't update LineMaterial.resolution itself, and it was set once from the window, so widths scaled with the mismatch between window and canvas shape, and could vanish when a pane first opened. The rug border now reads the real canvas size each frame.
    • Stretch fix everywhere: Mark: "same bug elsewhere - yes, let's fix everywhere". New src/utils/lineResolution.js (trackCanvasResolution) now covers rug borders, flow lines (LineFlow), pawn edges (BaseMesh) and c29's event markers. It replaces each line's window-based resolution; LineFlow.updateResolution had no callers and is gone. Older cycles (c2–c14, c28) keep their own frozen copies of the bug.
    • Pose tween: switching views now tips voxel models over the camera's move (CAMERA_CONFIG.focusDuration, easeInOutQuint), blending rotation, lift, centering and label position in c23's createVoxModelEntity.js. A switch mid-move continues from the current pose, and loads settle straight into the pose. It replaces the earlier instant flip. Checked: the start of the move and end states, including after rapid toggling. Not confirmed: a mid-motion frame (pane screenshots lag the page) or performance with c25's model count.
    • Account rug label: Mark: "with the personal account, let's remove the flag, and make the text red as well", then "a touch darker red". The label has no ⚑, and the border, name and heading are all DC2626, with a new rugAccountLabelColor control. The src override is now COLORS.rugDepth.styleByCategory with { color, width, labelColor } (renamed from borderByCategory). The rug label texture is now tagged sRGB; without that, colored text rendered washed out. Red is the only finding signal on this rug for now, and every account type gets it.
    • Known rough edges: rug style edits in Controls on this page only reach rugs built afterwards. In Isometric the chips lie flat on the floor, so the harness's belt no longer reads as a belt.

Captures

Working screengrabs from the session, in order, in captures/. They are about 800px wide, taken from the browser pane, so treat them as a record of the path and recapture at full size for the design repo's ## Visual record process.

FileState
01-fork-of-c28-fixtureFresh fork of c28 on its fixture
02-scenario-1-rug-per-kindScenario 1, one rug per actor kind
03-zones-hierarchyInternet / Endpoint / Provider Account / Workspace
04-ai-services-inside-internetAI Services rug inside Internet
05-ai-services-own-rugAI Services top-level, outside Internet
06-grey-spheres-hover-labelsGrey spheres, hover-only labels
07-harness-agent-mesh-with-hatHarness: AgentMesh with hat, 4x
08-harness-grey-helperHarness: grey helper split from the pair
09-account-rug-personalAccount rug shortened to "personal"
10-flat-mid-transitionIsometric to Flat, pose flipped before the camera
11-flat-default-unlit-helperFlat by default, unlit helper
12-controls-sections-closedControls sections closed
13-rug-controls-live-testRug controls test (red stroke, yellow fill)
14-hex-pickerHex picker
15-rugs-f5f5f5-2px-d9d9d9F5F5F5 fills, 2px D9D9D9 border
16-hsb-pickerHSB picker
17-rug-labels-lower-leftRug labels lower left
18-rug-label-typographyInter semibold name, bold heading at 50%
19-rug-heading-62pctHeading at 62.5%
20-tool-treatments-wideTool treatments at 1680px wide (work in progress)
21-tool-treatments-1020Tool treatments at 1020px wide (work in progress)
22-tool-belt-chip-hoverTool belt, hovering a chip on Vanta
23-tool-stack-openedExpanding stack with the Vanta stack open
24-tool-treatments-flat-with-toggleAll three in Flat, with the view toggle
25-tool-treatments-isometricAll three in Isometric
26-tools-boxAll four treatments, with the Tools box
27-tools-box-openedTools box with one box opened
28-exploration-menu-defaultExploration menu, first treatment hidden
29-exploration-menu-two-panelsTwo treatments showing, maps larger
30-vanta-tools-on-ai-servicesVanta's tools moved onto AI Services
31-main-page-preset-fitMain page after the camera fit fix
32-harness-rugTools box panel with the Harness rug
33-harness-rug-box-openedBuilt-in box opened on the Harness rug
34-harness-rug-isometricHarness rug in Isometric
35-account-rug-red-before-stretch-fixRed account rug, before the stretch fix
36-account-rug-red-even-borderRed account rug, even border
37-flow-lines-even-thicknessFlow lines switched on, even at every angle
38-event-markers-even-linesFixture data with event markers on
39-flat-pawn-centeredExpanding stack panel: helper centered on its rug in Flat
40-flat-hover-label-below-faceHarness hover label below the face
41-c25-flat-centered-modelsc25 in Flat with centered models
42-pose-tween-startFirst frame after switching to Isometric: no instant flip
43-pose-tween-after-rapid-switchingFlat after rapid back-and-forth switching
44-account-rug-darker-red-textAccount rug: no flag, darker red border and text

Artifacts

Qpoint Brand Style Guide