loopable / web /src /settings /perms.css
fsanyoto's picture
Deploy AIOS web (React glide grid + FastAPI slice)
1f123e1 verified
Raw
History Blame
10.4 kB
/* settings/perms.css β€” wave 33 (owner item 11, W33-T34/T38).
*
* β›” CONTRACT C4: `index.css` is lane B's. Everything the permission editor's
* per-database DISCLOSURE needs is new, so it lives here and is imported by
* `PermsEditor.tsx` β€” the established practice (`query.css`, `navExtras.css`,
* `SwipeView.css`). Nothing in this file redefines an `index.css` rule; it only
* styles classes that did not exist before this wave.
*
* WHY A DISCLOSURE AT ALL. Owner, 2026-08-14: *"the database should not show all
* immediately the detail (for filter or hide fields), the user should have the
* ability to see ALL databases"*. Those two clauses pull against each other β€”
* more databases, less detail per database β€” and an accordion is what satisfies
* both. Before wave 33 the list was a fixed TWO and every panel rendered inline;
* it is now every database the tenant has.
*/
/* The trailing controls of a module head, grouped as ONE flex child so the
`space-between` rule in `index.css` still sees exactly two children. */
.set-perm-headend {
display: flex;
align-items: center;
gap: 10px;
flex: none;
}
/* Smaller and quieter than a primary action: this button reveals detail, it does
not commit anything. It borrows `.set-secondary`'s border, surface and focus
ring rather than restating them β€” a second definition of the button chrome is a
second place for the focus ring to go missing.
⚠ STILL LIVE, and only in the agent editor. Wave 40 replaced the account
editor's accordion with a full-pane room (`.set-perm-edit` below); the agent
editor mounts the same list without `onEdit` and keeps this disclosure. */
.set-perm-disclose {
font-size: var(--lp-fs-2xs);
padding: 3px 9px;
white-space: nowrap;
}
/* The open state reads as pressed, so a scrolled-away head still says which
database owns the panels below it. */
.set-perm-disclose[aria-expanded="true"] {
border-color: var(--lp-blue-deep);
color: var(--lp-blue-deep);
}
/* ── wave 40, owner instruction 7 (W40-T14): the row's ONE way in, and the room
it opens ──────────────────────────────────────────────────────────────────
*
* WHY THE ACCORDION BECAME A ROOM. Wave 33's disclosure answered "show every
* database, not every panel", and it did β€” while the list was two rows. It is now
* every database the tenant has, and a filter builder unfolded inside one row of
* that list reads as a menu that failed to close. Owner: *"Edit opens the whole
* database's Fields and Filters to toggle, with a Back button to return."*
*/
/* Sized and quietened like the disclosure it replaces, and borrowing
`.set-secondary`'s border, surface and focus ring for the same reason that one
does: a second definition of the button chrome is a second place for the focus
ring to go missing. */
.set-perm-edit {
font-size: var(--lp-fs-2xs);
padding: 3px 9px;
white-space: nowrap;
}
/* The way out and the name of the room share one line, so the reader learns
where they are and how to leave in a single glance. `baseline` rather than
`center`: the title's cap height should sit on the button's label, which is
the alignment every other head on this page uses. */
.set-dbperm-head {
display: flex;
align-items: baseline;
gap: 12px;
margin-bottom: 16px;
}
/* The chevron rides with the words rather than beside them. */
.set-dbperm-back { display: inline-flex; align-items: center; gap: 6px; flex: none; }
/* `.set-h4` carries block margins meant for a heading that starts a section; here
it is a flex item on the head's own line. */
.set-dbperm-title { margin: 0; min-width: 0; }
/* ⭐ W40-T16 β€” `.set-dbperm-metrics` IS DELETED WITH THE BOX IT SPACED. Owner instruction 13
folded the blanket Metrics checkbox into the Hide-fields list as one row per metric, so the
rule had no element left to apply to. A rule that matches nothing is how a stylesheet ends up
describing a screen that no longer exists. */
/* THE PANELS STACK, one decision per eye level. A grid rather than a column flex
box on purpose: `.set-perm-pop` carries `flex: 1 1 320px` for the side-by-side
accordion, and flex properties are inert on a GRID item, so this container gets
the stacking it wants without redefining a rule that belongs to `index.css`. */
.set-dbperm-panels {
display: grid;
grid-template-columns: minmax(0, 1fr);
gap: 14px;
}
/* ── wave 40, owner instructions 8 + 9 + 10 (W40-T15): the account page stops
shouting, and Save sits where the hand is ──────────────────────────────────
*
* Three complaints, one page. The header put an exit, a person and two chips on
* one flex row; the reset-password control was split across a two-column grid
* with its consequence read BEFORE the button that causes it; and a long access
* list had its only Save at the bottom.
*
* β›” EVERY SELECTOR BELOW THAT OVERRIDES AN `index.css` DEFAULT CARRIES TWO
* CLASSES ON PURPOSE. A single-class rule here would tie at 0-1-0 with the rule
* it means to beat, and the winner would then be vite's import order across two
* stylesheets β€” a thing no reader of either file can see. Nothing in `index.css`
* is edited or restated; these only bound the new arrangement.
*/
/* --- instruction 9c: the way out is page chrome, on its own line ----------- */
/* The quiet-button register this system already uses (`.shell-newfolder`: muted
ink, wash on hover, nothing else), with the native chrome reset in the BASE
rule as `DESIGN.md` §4 requires. ⚠ `font: inherit` FIRST and the size after
it: a shorthand declared below its own longhands re-expands and undoes them,
which is the Alerts-button scar `verify_ui.py`'s R5b cascade check exists to
catch. The negative left margin is optical, not spacing β€” it pulls the
chevron out to the page's text edge so the label starts where the title does. */
.set-perm-back {
display: inline-flex;
align-items: center;
gap: 6px;
border: 0;
background: transparent;
font: inherit;
font-size: var(--lp-fs-2xs);
color: var(--lp-muted);
padding: 4px 8px;
margin: 0 0 10px -8px;
border-radius: var(--lp-r-sm);
cursor: pointer;
}
.set-perm-back:hover { background: var(--lp-wash); color: var(--lp-ink); }
.set-perm-back:focus-visible { outline: 2px solid var(--lp-blue-deep); outline-offset: 1px; }
/* The identity is the page TITLE now, so it owns the space under the head
rather than sharing a row with the exit. */
.set-perm-ident { margin-bottom: 16px; }
/* The chips sit beside the name, which is where `index.css` already argued they
belong: pushed to the far end they read as a status of the dialog rather than
of the person.
⚠ `baseline`, NOT the `center` the old head used, and the difference is which
sibling the chip is beside. On that row the chip sat next to a TWO-LINE block
(name over username) and index.css records the reason for centring it: a chip
top-aligned against two lines looks dropped. Here its sibling is the one-line
title, so the chip's text sits on the title's baseline, which is the alignment
`.set-perm-modhead` and `.set-dbperm-head` already use for a heading and a
smaller control on one line. The username moved out of this row entirely. */
.set-perm-nameline {
display: flex;
align-items: baseline;
flex-wrap: wrap;
gap: 10px;
}
/* --- instruction 9a + 9b: the password group reads top to bottom ----------- */
/* Label, box and button on one line and one baseline; the consequence under
them. `flex-end` rather than `baseline` because the label sits ABOVE the box:
what has to line up is the bottom of the input and the bottom of the button,
which are both 32px tall. */
.set-pw-row {
display: flex;
align-items: flex-end;
flex-wrap: wrap;
gap: 12px;
}
/* `.set-field` carries 13px of bottom margin meant for stacked form rows; here
it would lift the box off the button's baseline. The width keeps the box the
size a password is, instead of letting it stretch the whole card. */
.set-pw-group .set-pw-field { flex: 1 1 220px; max-width: 320px; margin-bottom: 0; }
/* The gap goes ABOVE the sentence now that the sentence is last. */
.set-perms .set-pw-note { margin: 8px 0 0; }
/* --- instruction 10: Save access at the head of the section too ------------ */
/* The trailing controls of the Access head, grouped as ONE flex child so
`index.css`'s `space-between` on `.set-perm-sect` still sees exactly two. */
.set-perm-sectend {
display: flex;
align-items: center;
gap: 8px;
flex: none;
}
/* Sized to the copy door beside it rather than to the 32px action row at the
bottom of the page: controls sharing a row share a height (`DESIGN.md` Β§4),
and this one is riding a heading's line. It stays `.set-primary` in colour,
because it commits the same write the bottom button commits. */
.set-perms .set-perm-savetop {
height: 28px;
padding: 0 12px;
font-size: var(--lp-fs-2xs);
}
/* --- instruction 8: "Database" and "Module" ------------------------------- */
/* A label for a group of cards, one step quieter than the `Access` heading it
sits under, so the reader gets the hierarchy from weight rather than from
indentation. Sentence case: the product has no ALL-CAPS chrome.
⚠ The bottom margin is deliberately small because `.set-perm-mod` brings 14px
of its own top margin and adjacent margins collapse to the larger β€” anything
under 14px here has no effect at all, so 4px says "as tight as the card
allows" rather than pretending to a number the layout cannot honour. */
.set-perms .set-perm-group {
margin: 22px 0 4px;
font-size: var(--lp-fs-2xs);
color: var(--lp-muted);
}
@media (max-width: 640px) {
/* The head wraps before the label truncates: a database name is the one thing
in this row that cannot be guessed from context. */
.set-perm-headend { flex-wrap: wrap; justify-content: flex-end; }
.set-dbperm-head { flex-wrap: wrap; }
/* The Access heading keeps its own line and the two controls take the next
one, rather than the copy door and Save being crushed into a strip beside
the word. */
.set-perm-sectend { flex-wrap: wrap; justify-content: flex-end; }
}