feat: per-connection publish governance — auto, 1-admin, majority, consensus
Per the owner's spec: each social connection gets publishGovernance in its fields — unset = manual publish (today), auto = dispatch on approval, admin1/admin_majority/admin_consensus = a publish-phase chatgov poll (subject draft_publish, its own open-poll slot, no collision with review gates). Dispatch holds until the publish poll passes (E3 pre-dispatch check); auto dispatches on approval. Includes migration 033, the PATCH /connections/:id/publish-governance route (chatgov.manage), and 19+31 new tests. Implementation by the branding-panel process (claude/opus), lint and integration fixes here.
This commit is contained in:
parent
f2eb14956e
commit
b89dea5c93
26 changed files with 1637 additions and 31 deletions
228
infra/occupymedia/edge/hub-chat-auth.css
Normal file
228
infra/occupymedia/edge/hub-chat-auth.css
Normal file
|
|
@ -0,0 +1,228 @@
|
|||
/* Element Web 1.12.30 auth layout overrides, loaded by the chat edge vhost.
|
||||
* Keep every rule inside mx_AuthPage: the signed-in client keeps its existing
|
||||
* custom-OccupyHub Dark theme and Compound tokens. No hashed selectors or JS.
|
||||
* branding.auth_header_logo_url supplies the small Hub mark; see ../element/.
|
||||
*/
|
||||
.mx_AuthPage {
|
||||
position: relative;
|
||||
box-sizing: border-box;
|
||||
min-height: 100vh;
|
||||
min-height: 100dvh;
|
||||
height: auto !important;
|
||||
padding: 88px 20px 24px;
|
||||
background: #060403 !important; /* Also replaces the inline background image. */
|
||||
color: #f5efed;
|
||||
color-scheme: dark;
|
||||
font-family: system-ui, -apple-system, "Segoe UI", sans-serif !important;
|
||||
}
|
||||
|
||||
.mx_AuthPage .mx_AuthPage_modal {
|
||||
/* AuthHeader's absolute positioning is relative to AuthPage, not the card. */
|
||||
box-sizing: border-box;
|
||||
position: static !important;
|
||||
flex: 0 0 auto;
|
||||
width: 420px;
|
||||
max-width: 100%;
|
||||
margin: auto;
|
||||
border: 1px solid #2a2320;
|
||||
border-radius: 10px;
|
||||
background: #0f0a09 !important;
|
||||
box-shadow: none !important;
|
||||
}
|
||||
|
||||
.mx_AuthPage .mx_AuthPage_modalBlur {
|
||||
display: none !important;
|
||||
}
|
||||
|
||||
.mx_AuthPage .mx_AuthPage_modalContent {
|
||||
flex-direction: column;
|
||||
width: 100%;
|
||||
min-width: 0;
|
||||
background: #0f0a09 !important;
|
||||
}
|
||||
|
||||
/* Turn the old logo sidebar into quiet branding in the top-left corner.
|
||||
* Re-enable it on phones: Element normally hides AuthHeader below 480px.
|
||||
*/
|
||||
.mx_AuthPage .mx_AuthHeader {
|
||||
position: absolute;
|
||||
inset: 24px auto auto 24px;
|
||||
display: flex !important;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
width: auto;
|
||||
max-width: calc(100% - 48px);
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.mx_AuthPage .mx_AuthHeaderLogo {
|
||||
display: flex !important;
|
||||
flex: 0 1 auto;
|
||||
align-items: center;
|
||||
gap: 10px;
|
||||
min-width: 0;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.mx_AuthPage .mx_AuthHeaderLogo img {
|
||||
display: block;
|
||||
flex: 0 0 32px;
|
||||
width: 32px !important;
|
||||
height: 32px !important;
|
||||
max-width: 32px;
|
||||
object-fit: contain;
|
||||
}
|
||||
|
||||
.mx_AuthPage .mx_AuthHeaderLogo::after {
|
||||
content: "Tactical Media Broadcast Hub";
|
||||
color: #f5efed;
|
||||
font-size: 14px;
|
||||
font-weight: 600;
|
||||
line-height: 1.3;
|
||||
}
|
||||
|
||||
.mx_AuthPage .mx_AuthBody {
|
||||
box-sizing: border-box;
|
||||
width: 100%;
|
||||
min-width: 0;
|
||||
min-height: 0;
|
||||
padding: 24px;
|
||||
border-radius: inherit;
|
||||
background: #0f0a09 !important;
|
||||
color: #c0b4af;
|
||||
font-size: 14px;
|
||||
line-height: 1.5;
|
||||
}
|
||||
|
||||
.mx_AuthPage .mx_AuthBody h1 {
|
||||
margin: 0 0 20px;
|
||||
color: #f5efed;
|
||||
font-size: 20px;
|
||||
line-height: 1.3;
|
||||
}
|
||||
|
||||
.mx_AuthPage .mx_Register_mainContent {
|
||||
min-height: 0;
|
||||
}
|
||||
|
||||
/* With disable_custom_urls=true this is only a redundant homeserver label.
|
||||
* Keep the picker visible if a future config allows editing the server.
|
||||
*/
|
||||
.mx_AuthPage .mx_ServerPicker:not(:has(.mx_ServerPicker_change)) {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.mx_AuthPage .mx_Field:not(.mx_Field_valid):not(.mx_Field_invalid) {
|
||||
border-color: #3a322d;
|
||||
}
|
||||
|
||||
.mx_AuthPage .mx_Field:focus-within {
|
||||
border-color: #ff1610;
|
||||
}
|
||||
|
||||
.mx_AuthPage .mx_Field :is(input, select, textarea) {
|
||||
background: #0f0a09 !important;
|
||||
color: #f5efed !important;
|
||||
font-family: inherit;
|
||||
font-size: 16px; /* Avoid iOS zoom when focusing a field. */
|
||||
}
|
||||
|
||||
.mx_AuthPage .mx_Field label {
|
||||
background-color: #0f0a09 !important;
|
||||
color: #c0b4af;
|
||||
font-family: inherit;
|
||||
}
|
||||
|
||||
.mx_AuthPage :is(a, .mx_AccessibleButton_kind_link, .mx_AccessibleButton_kind_link_inline) {
|
||||
color: #c0b4af !important;
|
||||
}
|
||||
|
||||
.mx_AuthPage :is(a, button, [role="button"]):focus-visible {
|
||||
outline: 2px solid #ff1610;
|
||||
outline-offset: 3px;
|
||||
}
|
||||
|
||||
/* Compound's data-kind is stable; Element's submit class covers older buttons. */
|
||||
.mx_AuthPage :is(button[type="submit"], .mx_Login_submit, [data-kind="primary"]) {
|
||||
min-height: 36px;
|
||||
height: auto;
|
||||
border: 1px solid transparent;
|
||||
border-radius: 6px;
|
||||
background: #ff1610 !important;
|
||||
color: #fff !important;
|
||||
font-family: inherit;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.mx_AuthPage :is(button[type="submit"], .mx_Login_submit, [data-kind="primary"]):hover:not(:disabled):not([aria-disabled="true"]) {
|
||||
background: #e3130e !important;
|
||||
}
|
||||
|
||||
.mx_AuthPage :is(button[type="submit"], .mx_Login_submit, [data-kind="primary"]):is(:disabled, [aria-disabled="true"]) {
|
||||
opacity: 0.45;
|
||||
}
|
||||
|
||||
.mx_AuthPage .mx_AuthFooter {
|
||||
box-sizing: border-box;
|
||||
margin-top: 24px;
|
||||
padding: 0;
|
||||
background: none;
|
||||
font-family: inherit;
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
.mx_AuthPage .mx_AuthFooter a {
|
||||
display: inline-block;
|
||||
margin: 4px 10px;
|
||||
}
|
||||
|
||||
/* Defensive fallback while config is being rolled out: no welcome hero. */
|
||||
.mx_AuthPage .mx_DefaultWelcome {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.mx_AuthPage .mx_DefaultWelcome > :is(h1, p),
|
||||
.mx_AuthPage .mx_DefaultWelcome_logo {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.mx_AuthPage .mx_DefaultWelcome_buttons {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
border: 0;
|
||||
}
|
||||
|
||||
.mx_AuthPage .mx_DefaultWelcome_buttons a {
|
||||
box-sizing: border-box;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
@media (max-width: 480px) {
|
||||
.mx_AuthPage {
|
||||
padding-inline: 16px;
|
||||
}
|
||||
|
||||
.mx_AuthPage .mx_AuthHeader {
|
||||
inset-inline-start: 16px;
|
||||
max-width: calc(100% - 32px);
|
||||
}
|
||||
|
||||
.mx_AuthPage .mx_AuthBody {
|
||||
padding: 20px;
|
||||
}
|
||||
|
||||
.mx_AuthPage .mx_Register_footerActions {
|
||||
flex-wrap: wrap;
|
||||
gap: 12px;
|
||||
}
|
||||
|
||||
.mx_AuthPage .mx_AuthBody_fieldRow {
|
||||
flex-direction: column;
|
||||
gap: 12px;
|
||||
}
|
||||
|
||||
.mx_AuthPage .mx_AuthBody_fieldRow > .mx_Field {
|
||||
margin: 0;
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue