Skip to content

moooon

Motir

Vibe your whole project. Bring an idea — Motir's three AI layers plan it, track it, and ship it, end to end. You're looking at Motir, built in Motir.

  • Vibe Project
  • Open Source
  • AI Agent
  • AI Loop
1
requests
0
upvotes
145
planned
1,361
shipped

Motir · Work items

MOTIR-2464Done

Design — the permission-gated shell: the settings door that is not there, the refused destination, and the group that filtered away

Draw what the shell looks like when doors are missing. Every other card in this story removes something, and an absence is the hardest thing to build without a reference — the question "what sits where the Project settings row used to be?" has several plausible answers and only one that should ship.

The surfaces to draw

Five panels, all in ONE asset:

  1. The bottom nav, admin beside member. The Project settings row present on the left, absent on the right, with the rows below closed up. This is the panel the parent story is named after, and it is the one that decides whether the absence needs any acknowledgement at all (a disabled row, a tooltip, nothing).
  2. The settings rail for a partial role — an actor holding some administrative keys and not others. Only groups with a visible entry render; a group whose entries all filtered away has no heading, not an empty one. Draw the two-entry case, because that is the shape a custom role produces and it is where an empty heading would look like a bug.
  3. The refused destination. /settings/project/members reached by direct navigation from an actor who cannot see it: the shipped NoAccessState (components/projects/NoAccessState.tsxEmptyState family, lock glyph, one action). Specify the title, the description, the back label and where back goes, per settings area rather than one generic string.
  4. The project nav for a viewer — the entries whose destinations refuse them outright are gone. Draw the before/after so the code card can see which rows close up and whether the section separators survive.
  5. UNCHANGED, drawn once so nobody re-designs it — the Create button visible-and-disabled with its tooltip, board drag with its read-only banner, the issue-detail inline field pickers, the absent Edit link. These are the 2026-06-09 in-place treatments this story explicitly keeps; the panel exists to make "do not touch" visible rather than a sentence in six cards.

What this composes and does not redraw

The rail, its groups and its rows are already drawn by design/projects/settings-area.mock.html (Subtask 6.5.1) and the shell by design/shell/desktop.pen / desktop-collapsed.pen. This asset composes both and redraws neither — it shows the same rail with entries removed, in the same chrome. Where a panel needs the rail, take the shipped markup rather than re-specifying it; a second rail specification would be built twice and drift.

The behaviour drawn here is specified by the hide-versus-disable decision — its treatment table is the spec for which affordance appears in which panel. Do not invent a treatment this asset needs; if the table does not cover it, that is a gap in the decision.

On ink: --el-text-faint measures 2.39:1 and fails AA, which is why the roles asset had to be corrected by the contrast bug and why the product-wide sweep is open. Do not reach for it here for the secondary text these panels are full of — this asset must not add another site to that sweep. It is not a prerequisite of this card; it is a trap this card is being warned off.

Scope boundary

In: the three-file asset and its design-notes.md section. Out: every line of application code (the sibling code cards), the permission KEY each surface gates on (each code card names its own against that surface's server guard), and any change to the roles & permissions screens shipped by the roles screens story.

Acceptance criteria

  • The three-file set exists at design/projects/permission-gated-ui.mock.html, design/projects/permission-gated-ui.png (a real export of the mock, same basename), plus a new section in design/projects/design-notes.md naming the composing primitives, the copy and the access path.
  • All five panels above are drawn, each labelled.
  • Panel 1 draws the absence in its parent surface — the bottom nav — with the admin state beside it, and the notes state what (if anything) marks the gap.
  • Panel 2 shows a settings group with zero visible entries rendering no heading; this is drawn, not only described.
  • Panel 3 reuses the shipped NoAccessState shape and names, per settings destination, the title / description / back-label / back-href it renders with.
  • The notes state explicitly that the asset composes design/projects/settings-area.mock.html and the design/shell assets and does NOT redesign the rail or the shell, citing both paths.
  • Colour comes only from --el-* element tokens and shape only from the element-semantic shape tokens, and no --el-text-faint appears on active informational text — it fails AA at 2.39:1.
  • Every treatment drawn traces to a row of the decision's treatment table; the notes cite the decision card for the rule rather than restating a rule of their own.
  • The mock renders in both themes without a hardcoded colour.

Context refs

  • design/projects/settings-area.mock.html + design/projects/design-notes.md — the rail this composes, and the file the new section lands in.
  • design/shell/desktop.pen / design/shell/desktop-collapsed.pen / design/shell/cmd-k.pen — the shell chrome and the palette.
  • components/projects/NoAccessState.tsx — the shipped refused-state component panel 3 reuses.
  • app/(authed)/_components/SidebarNav.tsx — the bottom nav and the settings rail as they render today.
  • The hide-versus-disable decision — the treatment table this asset draws.