syntheogenesis / dee /static /workspaces.css
github-actions[bot]
Deploy 70383d2
47a84d0
Raw History Blame Contribute Delete
14.8 kB
/* Engine theme tokens only. The header stays reachable while content scrolls.
*
* 2026-10-19: this dialog had been written as a form and looked like one β€”
* default-weight headings, plain rows, and a boxed button at the end of each
* one, so a researcher's shared projects read as rows in an admin panel. It
* now speaks the same ink-and-amber language as the referral ticket and the
* credits readout: an amber edge on the dialog, mono kickers over each
* section, rows that respond where the pointer is, and ONE amber action β€”
* accepting an invitation, the only thing on that screen worth doing.
* Amber's two legibility rules hold throughout (accent.css): on an amber
* fill text is --amber-ink, and amber is only ever text on ink. */
.ws-dialog {
position: fixed;
inset: 0;
margin: auto;
height: fit-content;
width: min(820px, calc(100vw - 32px));
max-width: calc(100vw - 32px);
max-height: calc(100dvh - 40px);
padding: 0;
box-sizing: border-box;
border: 1px solid var(--line-strong);
border-radius: var(--r-5);
background: var(--bg-card);
color: var(--ink);
box-shadow: var(--elev-5);
font: var(--t-2)/1.6 var(--font-ui);
overflow: hidden;
}
.ws-dialog[open] { display: flex; flex-direction: column; }
.ws-dialog::backdrop { background: rgba(0, 0, 0, .55); }
/* The brand edge, as on the Invite & earn panel: this dialog is the other
half of the same promise β€” work shared with people you choose. */
.ws-dialog::before {
content: "";
position: absolute;
inset: 0 0 auto;
height: 3px;
background: var(--amber);
z-index: 2;
}
.ws-dialog header {
display: flex; align-items: flex-start; justify-content: space-between; gap: 16px;
flex: 0 0 auto; padding: 22px 24px 18px; border-bottom: 1px solid var(--line);
}
.ws-dialog header > div { min-width: 0; }
.ws-dialog h2, .ws-dialog h3 { color: var(--ink-strong); }
.ws-dialog h2 {
margin: 5px 0 0;
font: italic 600 var(--t-5)/1.15 var(--font-display);
letter-spacing: -.015em;
}
/* Section heads are kickers, not headlines: a short ink rule, then mono
capitals β€” the same device the page titles and Mission Control use. */
.ws-dialog h3 {
display: flex; align-items: center; gap: 12px;
margin: 28px 0 14px;
font: 600 var(--t-1)/1.3 var(--font-mono);
letter-spacing: .16em;
text-transform: uppercase;
overflow-wrap: anywhere;
}
.ws-dialog h3::before { content: ""; flex: 0 0 22px; height: 1px; background: currentColor; }
.ws-eyebrow {
display: block;
color: var(--ink-faint);
font: 600 var(--t-1)/1.4 var(--font-mono);
letter-spacing: .14em;
text-transform: uppercase;
}
.ws-body { min-height: 0; padding: 4px 24px 24px; overflow: auto; overscroll-behavior: contain; }
/* What this dialog is for, said once at the top and then got out of the way. */
.ws-body > p:first-child { margin: 14px 0 4px; max-width: 64ch; color: var(--ink-soft); }
/* What just happened, in the margin rather than in a grey band. */
.ws-dialog .ws-status {
margin: 0; padding: 12px 24px; flex: 0 0 auto;
color: var(--ink); background: var(--bg-subtle);
border-bottom: 1px solid var(--line);
box-shadow: inset 3px 0 0 var(--amber);
font: 500 var(--t-2)/1.5 var(--font-ui);
overflow-wrap: anywhere;
}
.ws-dialog .ws-status:empty { display: none; }
.ws-note, .ws-dialog small { color: var(--ink-soft); font-size: var(--t-2); line-height: 1.6; }
.ws-dialog small { display: block; }
/* One project per line, and the line answers the pointer: an amber bar where
the sidebar puts it, so the row you are about to open is the lit one. */
.ws-row {
display: flex; align-items: center; justify-content: space-between; gap: 12px;
margin: 0 -14px;
padding: 14px;
border-bottom: 1px solid var(--line);
border-radius: var(--r-2);
transition: background-color var(--t-fast) var(--ease), box-shadow var(--t-fast) var(--ease);
}
.ws-row:hover { background: var(--bg-subtle); box-shadow: inset 2px 0 0 var(--amber); }
.ws-row > div { min-width: 0; }
.ws-row strong {
display: block;
color: var(--ink-strong); font-size: var(--t-3); font-weight: 500; line-height: 1.4;
letter-spacing: -.005em;
overflow-wrap: anywhere;
}
.ws-row small {
margin-top: 3px;
font: 500 var(--t-1)/1.4 var(--font-mono);
letter-spacing: .04em;
color: var(--ink-faint);
text-transform: uppercase;
}
.ws-row > div:last-child { display: flex; gap: 8px; flex-wrap: wrap; }
.ws-dialog p { line-height: 1.6; }
.ws-dialog label { display: grid; gap: 6px; margin: 14px 0; color: var(--ink); }
.ws-dialog input, .ws-dialog textarea, .ws-dialog select {
width: 100%; min-width: 0; box-sizing: border-box;
font: inherit; color: var(--ink-strong); background: var(--bg-subtle);
border: 1px solid var(--line-strong); border-radius: var(--r-2); padding: 10px 12px;
}
.ws-dialog textarea { height: 140px; resize: vertical; font-family: var(--font-mono); overflow-wrap: anywhere; }
.ws-dialog [readonly] { color: var(--ink-soft); }
/* Pills, like every other control on this surface. The default is quiet and
fills with ink under the pointer; the one key action is amber (accent.css). */
.ws-dialog button {
font: 500 var(--t-2)/1.4 var(--font-ui); background: none; color: var(--ink-soft);
border: 1px solid var(--line-strong); border-radius: var(--r-pill);
padding: 9px 16px; cursor: pointer; min-height: 44px;
transition: background-color var(--t-fast) var(--ease), color var(--t-fast) var(--ease),
border-color var(--t-fast) var(--ease);
}
.ws-dialog button:hover:not(:disabled) { background: var(--ink-strong); color: var(--on-ink); border-color: var(--ink-strong); }
/* The row's own verb: it belongs to the line, so it stays an outline until
the line is lit, and then it is the thing to press. */
.ws-row [data-ws=open] { color: var(--ink-strong); border-color: var(--line); }
.ws-dialog button[type=submit] { background: var(--ink-strong); color: var(--on-ink); border-color: var(--ink-strong); }
.ws-dialog button[type=submit]:hover:not(:disabled) { background: var(--hover-fill); color: var(--hover-text); border-color: var(--hover-fill); }
/* Close is a way out, not an action: no border, no weight. */
.ws-dialog header [data-ws=close] {
flex: 0 0 auto; min-height: 36px; padding: 6px 14px;
border-color: transparent; color: var(--ink-faint);
font: 600 var(--t-1)/1.3 var(--font-mono); letter-spacing: .12em; text-transform: uppercase;
}
.ws-dialog [data-ws=revoke] { color: var(--danger); }
.ws-dialog button:disabled { color: var(--ink-disabled); background: var(--bg-subtle); border-color: var(--line); cursor: wait; }
.ws-dialog :is(button, input, textarea, select, summary):focus-visible, .ws-entry:focus-visible { outline: 2px solid var(--brand); outline-offset: 3px; }
.ws-dialog .ws-consent { display: flex; align-items: flex-start; gap: 10px; line-height: 1.6; }
.ws-consent input { width: 18px; height: 18px; padding: 0; margin: 2px 0 0; flex: 0 0 18px; accent-color: var(--brand); }
.ws-dialog details { padding: 14px 0; border-top: 1px solid var(--line); }
.ws-dialog summary { cursor: pointer; color: var(--ink-strong); min-height: 28px; }
.ws-results, .ws-actions { display: flex; gap: 8px; flex-wrap: wrap; }
.ws-results > span { display: flex; gap: 6px; flex-wrap: wrap; }
.ws-actions { margin-top: 16px; }
.ws-dialog li { margin: 12px 0; }
/* The door to collaboration stands between the Mission Control headline and
the .mc-enter row, so it has to speak that row's language: a pill, not the
boxed dialog button it had been borrowing, which read as a stray form
control dropped under the title. Quieter than the primary CTA next to it β€”
this is somewhere to glance, not the main way in β€” so it takes the same
outline treatment as .mc-enter-find rather than competing with the fill. */
.ws-entry {
display: inline-flex; align-items: center; gap: 9px;
margin: 0 0 18px; padding: 10px 16px; min-height: 40px;
font: var(--t-2)/1.4 var(--font-ui); color: var(--ink-soft);
background: none; border: 1px solid var(--line-strong);
border-radius: var(--r-pill); cursor: pointer;
transition: border-color var(--t-fast) var(--ease), color var(--t-fast) var(--ease);
}
.ws-entry:hover { border-color: var(--ink-soft); color: var(--ink-strong); }
.ws-entry svg { width: 14px; height: 14px; flex: none; }
/* The count appears only when something is actually waiting. A permanent "0"
teaches people the region is empty and trains the glance away from it. */
.ws-entry-n {
font-family: var(--font-mono); font-size: var(--t-1); line-height: 1;
color: var(--on-ink); background: var(--brand);
border-radius: var(--r-pill); padding: 3px 7px;
}
#wsEdit { display: grid; grid-template-columns: minmax(0, 1fr) minmax(120px, .4fr); column-gap: 16px; }
#wsEdit > details, #wsEdit > button { grid-column: 1 / -1; }
#wsEdit > button { justify-self: start; }
.ws-table { max-width: 100%; overflow: auto; border: 1px solid var(--line); border-radius: var(--r-2); }
.ws-table table { width: 100%; border-collapse: collapse; font: inherit; }
.ws-table th, .ws-table td { padding: 9px 12px; text-align: left; border-bottom: 1px solid var(--line); max-width: 180px; overflow-wrap: anywhere; }
.ws-table th { color: var(--ink-soft); background: var(--bg-subtle); font-weight: 500; }
.ws-result-data { font: var(--t-2)/1.6 var(--font-mono); white-space: pre-wrap; overflow-wrap: anywhere; }
@media (max-width: 540px) {
.ws-dialog { width: calc(100vw - 16px); max-width: calc(100vw - 16px); max-height: calc(100dvh - 16px); }
.ws-dialog header { padding: 16px; }
.ws-body { padding: 0 16px max(16px, env(safe-area-inset-bottom)); }
.ws-dialog .ws-status { padding: 12px 16px; }
.ws-row { align-items: flex-start; flex-wrap: wrap; }
#wsEdit { grid-template-columns: minmax(0, 1fr); }
.ws-dialog input:not([type=checkbox]), .ws-dialog textarea, .ws-dialog select { font-size: var(--t-4); }
}
/* ── Collaboration surfaced in Mission Control ─────────────────────────────
These live beside the dialog's styles because they are the same feature,
not a new one: the data was always there, behind a button nobody had a
reason to press. Tokens only β€” this inherits the workspace's palette so a
shared project does not announce itself as a different product. */
.mc-cx-share {
display: inline-block;
margin-top: 4px;
font-family: var(--mono, ui-monospace, monospace);
font-size: var(--t-1);
letter-spacing: 0.08em;
text-transform: uppercase;
color: var(--accent, #2f6f6a);
border: 1px solid currentColor;
border-radius: var(--r-pill);
padding: 1px 8px;
opacity: 0.85;
}
.mc-inv {
display: flex;
align-items: center;
justify-content: space-between;
gap: 12px;
padding: 12px 14px;
border: 1px solid var(--line, #d9ded9);
border-radius: var(--r-1);
background: var(--card, transparent);
}
.mc-inv + .mc-inv { margin-top: 8px; }
.mc-inv-t { font-size: var(--t-3); }
.mc-inv-go {
flex: 0 0 auto;
font: inherit;
font-size: var(--t-2);
cursor: pointer;
background: none;
border: 1px solid var(--line, #d9ded9);
border-radius: var(--r-hair);
padding: 6px 12px;
color: inherit;
}
.mc-inv-go:hover { border-color: currentColor; }
.mc-act {
display: flex;
align-items: baseline;
gap: 10px;
padding: 7px 0;
border-bottom: 1px solid var(--line-soft, rgba(128,128,128,0.18));
font-size: var(--t-2);
}
.mc-act:last-child { border-bottom: 0; }
.mc-act-w { flex: 0 0 auto; }
.mc-act-p { flex: 1 1 auto; min-width: 0; overflow-wrap: anywhere; opacity: 0.75; }
.mc-act-t {
flex: 0 0 auto;
font-family: var(--mono, ui-monospace, monospace);
font-size: var(--t-1);
opacity: 0.6;
}
/* An emailed invitation lands here: one card, the one decision. Somebody
arriving from an email has come to answer it, so it is the only thing on
the screen and it is drawn as the ticket it is β€” ink panel, amber edge,
amber accept. */
.ws-invite {
position: relative;
margin: 20px 0 8px;
padding: 24px 24px 22px;
border: 0;
border-radius: var(--r-5);
background: var(--ws-plate, var(--amber-ink));
outline: 1px solid var(--ws-plate-line, transparent);
outline-offset: -1px;
color: rgba(255, 255, 255, .78);
overflow: hidden;
}
:root[data-theme="dark"] .ws-invite { --ws-plate: #0c1117; --ws-plate-line: rgba(255, 224, 92, .22); }
.ws-invite::before {
content: "";
position: absolute;
inset: 0 auto 0 0;
width: 4px;
background: var(--amber);
}
.ws-invite .ws-eyebrow { color: var(--amber); }
.ws-invite h3 {
display: block;
margin: 8px 0 12px;
font: italic 600 var(--t-4)/1.25 var(--font-display);
letter-spacing: -.012em;
text-transform: none;
color: #fff;
}
.ws-invite h3::before { content: none; }
.ws-invite strong { color: #fff; }
.ws-invite .ws-note { color: rgba(255, 255, 255, .6); }
.ws-invite .ws-actions { margin-top: 20px; }
/* On ink, a quiet button is an amber outline; the ink fill the rest of the
dialog uses would disappear into the panel. */
.ws-invite button { color: var(--amber); border-color: rgba(255, 224, 92, .45); }
.ws-invite button:hover:not(:disabled) { background: var(--amber); color: var(--amber-ink); border-color: var(--amber); }
/* Sign-in / sign-up from inside the frame: real links (target=_top), styled
as the dialog's buttons so the two doors read as equals. */
.ws-link-btn {
display: inline-flex; align-items: center; justify-content: center; min-height: 44px; padding: 9px 14px;
font: var(--t-2)/1.4 var(--font-ui); text-decoration: none; border-radius: var(--r-2);
background: var(--ink-strong); color: var(--on-ink); border: 1px solid var(--ink-strong);
}
.ws-link-btn:hover { background: var(--hover-fill); color: var(--hover-text); border-color: var(--hover-fill); text-decoration: none; }
.ws-link-btn--quiet { background: var(--bg-card); color: var(--ink-strong); border-color: var(--line-strong); }
.ws-link-btn--quiet:hover { background: var(--bg-hover); color: var(--ink-strong); border-color: var(--line-bold); }
.ws-link-btn:focus-visible { outline: 2px solid var(--brand); outline-offset: 3px; }
/* The free-plan deletion date. Said once, plainly, to everyone in the project. */
.ws-banner { margin: 12px 0 4px; padding: 12px 14px; border-radius: var(--r-2); background: var(--warning-light); color: var(--ink); border: 1px solid var(--line); }
.ws-banner a { color: var(--ink-strong); font-weight: 600; }
.ws-dialog [data-ws=leave] { color: var(--danger); }