More things
This commit is contained in:
@@ -1,3 +1,32 @@
|
||||
@use 'mixins' as *;
|
||||
|
||||
// ---------- The dashboard's two tabs: the requests and the accounts ----------
|
||||
// The same segmented control the sign-in popup and the settings switch wear
|
||||
// (the mixins in _mixins.scss); the panels they open are the two sections.
|
||||
.admin-tabs { @include segmented; margin-bottom: 22px; }
|
||||
|
||||
.admin-tab {
|
||||
@include segmented-tab(7px 14px, 0.84rem);
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 7px;
|
||||
}
|
||||
|
||||
// how many requests are still waiting, so the pile is visible even while the
|
||||
// admin is reading the accounts — the tally's shape from the sidebar's count
|
||||
.admin-tab-count {
|
||||
min-width: 18px;
|
||||
height: 18px;
|
||||
padding: 0 5px;
|
||||
display: inline-grid;
|
||||
place-items: center;
|
||||
border-radius: 9px;
|
||||
background: color-mix(in srgb, var(--accent) 14%, transparent);
|
||||
color: var(--accent);
|
||||
font-size: 0.7rem;
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
// ---------- Admin dashboard: the list of accounts ----------
|
||||
// One row per account, read left to right: who, what they may do, when they
|
||||
// arrived, and the one thing an admin can change about them.
|
||||
|
||||
@@ -3,11 +3,68 @@
|
||||
// ---------- Articles index ----------
|
||||
.topic-tally { font-size: 0.85rem; color: var(--muted); }
|
||||
|
||||
.topic-dropdown {
|
||||
@include dropdown-panel;
|
||||
left: 0;
|
||||
right: 0;
|
||||
max-height: 280px;
|
||||
// ---------- Folders: the shelf filed by topic ----------
|
||||
.folder-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fill, minmax(240px, 1fr));
|
||||
gap: 14px;
|
||||
}
|
||||
|
||||
.folder-card {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 12px;
|
||||
padding: 15px 18px;
|
||||
border-radius: 14px;
|
||||
border: 1px solid var(--border);
|
||||
background: var(--surface);
|
||||
text-decoration: none;
|
||||
color: inherit;
|
||||
box-shadow: var(--shadow-sm);
|
||||
transition: transform 0.18s ease, border-color 0.18s, box-shadow 0.18s;
|
||||
|
||||
svg { flex: none; color: var(--accent); opacity: 0.85; transition: opacity 0.15s; }
|
||||
|
||||
&:hover {
|
||||
transform: translateY(-2px);
|
||||
border-color: color-mix(in srgb, var(--accent) 45%, var(--border));
|
||||
box-shadow: var(--shadow-lg);
|
||||
svg { opacity: 1; }
|
||||
}
|
||||
|
||||
&:focus-visible { box-shadow: var(--ring); }
|
||||
}
|
||||
|
||||
.folder-name {
|
||||
min-width: 0;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
font-size: 0.95rem;
|
||||
font-weight: 700;
|
||||
letter-spacing: -0.01em;
|
||||
// the facet tally lowercases every topic; folders wear their names capitalized
|
||||
text-transform: capitalize;
|
||||
}
|
||||
|
||||
.folder-count { flex: none; margin-left: auto; }
|
||||
|
||||
// the folder grid's loading row: a shorter skeleton than an article card's
|
||||
.folder-skeleton { height: 60px; border-radius: 14px; @include shimmer; }
|
||||
|
||||
// closing a folder: the quiet way back onto the topics
|
||||
.back-link {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 7px;
|
||||
margin-bottom: 14px;
|
||||
color: var(--muted);
|
||||
font-size: 0.85rem;
|
||||
font-weight: 650;
|
||||
text-decoration: none;
|
||||
transition: color 0.15s;
|
||||
|
||||
&:hover { color: var(--accent); }
|
||||
}
|
||||
|
||||
.topic-option {
|
||||
@@ -18,45 +75,6 @@
|
||||
&:hover, &.active { background: color-mix(in srgb, var(--accent) 12%, transparent); }
|
||||
}
|
||||
|
||||
.topic-dropdown-none {
|
||||
padding: 8px 12px;
|
||||
margin: 0;
|
||||
font-size: 0.85rem;
|
||||
color: var(--muted);
|
||||
}
|
||||
|
||||
.topic-search-wrap {
|
||||
position: relative;
|
||||
margin-bottom: 14px;
|
||||
|
||||
svg {
|
||||
position: absolute;
|
||||
left: 14px;
|
||||
top: 50%;
|
||||
translate: 0 -50%;
|
||||
color: var(--faint);
|
||||
pointer-events: none;
|
||||
}
|
||||
}
|
||||
|
||||
.topic-search {
|
||||
width: 100%;
|
||||
height: 40px;
|
||||
padding: 0 14px 0 40px;
|
||||
border-radius: 12px;
|
||||
border: 1px solid var(--border);
|
||||
background: var(--surface);
|
||||
box-shadow: var(--shadow-sm);
|
||||
font-size: 0.9rem;
|
||||
transition: border-color 0.15s, box-shadow 0.2s;
|
||||
|
||||
&:focus {
|
||||
outline: none;
|
||||
border-color: color-mix(in srgb, var(--accent) 55%, var(--border));
|
||||
box-shadow: 0 0 0 3px color-mix(in srgb, var(--accent) 14%, transparent);
|
||||
}
|
||||
}
|
||||
|
||||
.topic-count {
|
||||
padding: 1px 7px;
|
||||
border-radius: 999px;
|
||||
|
||||
@@ -7,6 +7,16 @@
|
||||
gap: 20px;
|
||||
}
|
||||
|
||||
// the shelf's last line: reaching it brings the next batch of cards in, and
|
||||
// while that batch is on its way it says so
|
||||
.shelf-sentinel {
|
||||
display: grid;
|
||||
place-items: center;
|
||||
padding-top: 24px;
|
||||
color: var(--faint);
|
||||
font-size: 0.85rem;
|
||||
}
|
||||
|
||||
.article-card {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
||||
@@ -90,6 +90,11 @@
|
||||
|
||||
// editor body
|
||||
.editor-body {
|
||||
// One height for the writing field and the preview side by side: each holds
|
||||
// its text in a box of this height and scrolls it inside, so a long article
|
||||
// never makes the editor taller than the field the writer is looking at.
|
||||
--editor-pane-h: 480px;
|
||||
|
||||
border: 1px solid var(--border);
|
||||
border-radius: 15px;
|
||||
background: var(--bg-elev);
|
||||
@@ -141,6 +146,7 @@
|
||||
.editor-grid {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr 1fr;
|
||||
height: var(--editor-pane-h);
|
||||
|
||||
&.mode-write {
|
||||
grid-template-columns: 1fr;
|
||||
@@ -158,11 +164,11 @@
|
||||
textarea.md-input {
|
||||
display: block;
|
||||
width: 100%;
|
||||
min-height: 480px;
|
||||
height: 100%;
|
||||
padding: 22px;
|
||||
border: 0;
|
||||
background: transparent;
|
||||
resize: vertical;
|
||||
resize: none;
|
||||
font-size: 0.9rem;
|
||||
line-height: 1.75;
|
||||
tab-size: 2;
|
||||
@@ -176,13 +182,24 @@ textarea.md-input {
|
||||
border-left: 1px solid var(--border);
|
||||
padding: 22px 26px;
|
||||
min-width: 0;
|
||||
overflow-y: auto;
|
||||
// and reaching the end of a long preview doesn't start scrolling the page
|
||||
overscroll-behavior: contain;
|
||||
overflow-wrap: break-word;
|
||||
}
|
||||
|
||||
.preview-label { @include eyebrow; margin-bottom: 14px; }
|
||||
|
||||
@media (max-width: 900px) {
|
||||
.editor-grid { grid-template-columns: 1fr; }
|
||||
.editor-grid {
|
||||
grid-template-columns: 1fr;
|
||||
height: auto;
|
||||
}
|
||||
|
||||
// stacked, the two panes keep the height the split gives them — each still
|
||||
// scrolls its own text rather than stretching the editor
|
||||
.write-pane,
|
||||
.preview-pane { height: var(--editor-pane-h); }
|
||||
|
||||
.preview-pane { border-left: 0 !important; border-top: 1px solid var(--border); }
|
||||
}
|
||||
@@ -265,6 +282,21 @@ textarea.md-input {
|
||||
|
||||
@include popup-anim('confirm-popup', '.confirm-modal', 0.18s, transform 0.18s ease, 10px);
|
||||
|
||||
// sent-request popup — the discard popup's shape in a success temper: it
|
||||
// confirms a proposal filed with the admins, and closing it ends the edit
|
||||
.sent-check {
|
||||
display: grid;
|
||||
place-items: center;
|
||||
width: 46px;
|
||||
height: 46px;
|
||||
margin-bottom: 14px;
|
||||
border-radius: 50%;
|
||||
background: color-mix(in srgb, var(--success) 14%, transparent);
|
||||
color: var(--success);
|
||||
font-size: 1.3rem;
|
||||
font-weight: 800;
|
||||
}
|
||||
|
||||
// fullscreen editor
|
||||
.editor-body.is-fullscreen {
|
||||
position: fixed;
|
||||
@@ -278,9 +310,10 @@ textarea.md-input {
|
||||
|
||||
.editor-toolbar { flex: 0 0 auto; }
|
||||
|
||||
.editor-grid { flex: 1; min-height: 0; }
|
||||
.editor-grid { flex: 1; height: auto; min-height: 0; }
|
||||
|
||||
.write-pane, .preview-pane { min-height: 0; overflow-y: auto; }
|
||||
// the screen decides how tall a pane is here, not --editor-pane-h
|
||||
.write-pane, .preview-pane { height: auto; min-height: 0; overflow-y: auto; }
|
||||
|
||||
textarea.md-input { height: 100%; min-height: 0; resize: none; }
|
||||
}
|
||||
|
||||
@@ -8,10 +8,24 @@
|
||||
inset: -120px -20% auto -20%;
|
||||
height: 480px;
|
||||
pointer-events: none;
|
||||
background:
|
||||
radial-gradient(38% 60% at 30% 30%, color-mix(in srgb, var(--accent) 18%, transparent), transparent 70%),
|
||||
radial-gradient(34% 55% at 72% 22%, color-mix(in srgb, var(--accent-2) 14%, transparent), transparent 70%);
|
||||
filter: blur(30px);
|
||||
}
|
||||
}
|
||||
|
||||
// the index page hangs its hero off the middle of the reading surface: only
|
||||
// `/` carries `.is-home`, so the stretch below stays here and the other pages
|
||||
// that share `.home-main` (the shelf, the two admin desks) are untouched.
|
||||
// `.app-main` already owns the viewport's height (flex: 1 beside the sidebar
|
||||
// on desktop, under the top bar on mobile); the container grows into it and
|
||||
// centres the page's block in what's left.
|
||||
.app-main:has(.home-main.is-home) {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
||||
.container {
|
||||
display: flex;
|
||||
flex: 1;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -88,6 +102,18 @@
|
||||
&:focus { outline: none; border-color: var(--accent); box-shadow: var(--ring); }
|
||||
}
|
||||
|
||||
// the hero box opens the search popup (the Ctrl/⌘+K one) instead of taking
|
||||
// text, so it is a button wearing the search bar: the label sits where typed
|
||||
// text would, in the placeholder's colour
|
||||
.search-input.search-trigger {
|
||||
font: inherit;
|
||||
text-align: left;
|
||||
cursor: pointer;
|
||||
color: var(--faint);
|
||||
|
||||
&:hover { border-color: var(--accent); }
|
||||
}
|
||||
|
||||
.search-kbd {
|
||||
position: absolute;
|
||||
right: 16px;
|
||||
|
||||
@@ -183,6 +183,15 @@
|
||||
min-height: 39px; // 8+8 padding + 14.4px x 1.6 label line
|
||||
}
|
||||
|
||||
// the waiting count is not carried off with the labels: pinned to the
|
||||
// icon's corner, it stays a dot on the rail
|
||||
.sidebar-requests .requests-count {
|
||||
position: absolute;
|
||||
top: 2px;
|
||||
right: 2px;
|
||||
margin-left: 0;
|
||||
}
|
||||
|
||||
.sidebar-nav .btn {
|
||||
min-height: 35px; // 7+7 padding + 13.12px x 1.6 label line
|
||||
}
|
||||
@@ -211,13 +220,14 @@
|
||||
html.sidebar-collapsed .hide-collapsed { display: none; transition: none; }
|
||||
}
|
||||
|
||||
// ---------- "Open" articles: the count beside the button that shows them ----------
|
||||
// ---------- Sidebar tallies: articles open, requests waiting ----------
|
||||
.sidebar-open.is-current {
|
||||
color: var(--accent);
|
||||
background: color-mix(in srgb, var(--accent) 9%, transparent);
|
||||
}
|
||||
|
||||
.tabs-count {
|
||||
.tabs-count,
|
||||
.requests-count {
|
||||
margin-left: auto;
|
||||
min-width: 18px;
|
||||
height: 18px;
|
||||
@@ -232,6 +242,10 @@
|
||||
font-variant-numeric: tabular-nums;
|
||||
}
|
||||
|
||||
// the waiting pile is the very reason to open the desk, so its number stays
|
||||
// on the collapsed rail — the link is the frame it rides the corner of
|
||||
.sidebar-requests { position: relative; }
|
||||
|
||||
.logo {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
@@ -3,11 +3,13 @@
|
||||
// ---------- Profile popup ----------
|
||||
// The account row in the sidebar opens it; it draws and closes in the same
|
||||
// shape as the settings popup. Holds the profile picture (a data URL kept on
|
||||
// the account), the username, the password, and the way out.
|
||||
// the account), the username, the password, the interface language, and the
|
||||
// way out. Cut wider than the settings sheet so the language's five choices
|
||||
// fit in one row, and taller so the sections need no scrolling.
|
||||
.profile-overlay { @include overlay(120); }
|
||||
|
||||
.profile-modal {
|
||||
@include sheet(460px, min(620px, calc(100vh - 110px)));
|
||||
@include sheet(540px, min(720px, calc(100vh - 110px)));
|
||||
|
||||
&:focus, &:focus-visible { outline: none; }
|
||||
}
|
||||
|
||||
214
frontend/app/assets/css/_proposals.scss
Normal file
214
frontend/app/assets/css/_proposals.scss
Normal file
@@ -0,0 +1,214 @@
|
||||
// ---------- Admin dashboard: the edit requests members have sent in ----------
|
||||
// One entry per request: who wants what, which parts of the page it touches,
|
||||
// the reviewers' buttons while it waits — and, opened up, the change itself
|
||||
// laid out as two pages side by side.
|
||||
|
||||
.proposal-list {
|
||||
display: grid;
|
||||
gap: 10px;
|
||||
margin: 0 0 4px;
|
||||
padding: 0;
|
||||
list-style: none;
|
||||
}
|
||||
|
||||
.proposal-entry {
|
||||
padding: 12px 16px;
|
||||
border-radius: 14px;
|
||||
border: 1px solid var(--border);
|
||||
background: var(--surface);
|
||||
box-shadow: var(--shadow-sm);
|
||||
|
||||
// a waiting request is the accent one, so the pile reads at a glance
|
||||
&.is-pending { border-color: color-mix(in srgb, var(--accent) 34%, var(--border)); }
|
||||
|
||||
// decided entries recede: the record stays, the call is already made
|
||||
&.is-approved,
|
||||
&.is-rejected { background: color-mix(in srgb, var(--surface-2) 45%, var(--surface)); }
|
||||
}
|
||||
|
||||
.proposal-row {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 12px;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
.proposal-summary {
|
||||
flex: 1;
|
||||
min-width: 0;
|
||||
font-size: 0.9rem;
|
||||
color: var(--muted);
|
||||
|
||||
.proposal-proposer { color: var(--text); font-weight: 650; }
|
||||
|
||||
.proposal-article-link {
|
||||
color: var(--accent);
|
||||
font-weight: 650;
|
||||
text-decoration: none;
|
||||
|
||||
&:hover { text-decoration: underline; text-underline-offset: 2px; }
|
||||
}
|
||||
|
||||
// a requested page has no address to follow yet: its title is written as
|
||||
// plain text, not as a link to something that is not there
|
||||
.proposal-new { color: var(--text); font-weight: 650; }
|
||||
}
|
||||
|
||||
// the mark on a request for a page the wiki does not have: dashed rather than
|
||||
// filled, because the page is only a promise until somebody approves it
|
||||
.proposal-kind {
|
||||
flex: none;
|
||||
padding: 2px 9px;
|
||||
border: 1px dashed color-mix(in srgb, var(--accent) 45%, var(--border));
|
||||
border-radius: 999px;
|
||||
color: var(--accent);
|
||||
font-size: 0.66rem;
|
||||
font-weight: 700;
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 0.07em;
|
||||
}
|
||||
|
||||
.proposal-status {
|
||||
flex-shrink: 0;
|
||||
padding: 3px 11px;
|
||||
border-radius: 999px;
|
||||
background: var(--surface-2);
|
||||
color: var(--muted);
|
||||
font-size: 0.75rem;
|
||||
font-weight: 700;
|
||||
|
||||
&.status-pending {
|
||||
background: color-mix(in srgb, var(--accent) 14%, transparent);
|
||||
color: var(--accent);
|
||||
}
|
||||
|
||||
&.status-approved {
|
||||
background: color-mix(in srgb, var(--success) 14%, transparent);
|
||||
color: var(--success);
|
||||
}
|
||||
|
||||
&.status-rejected {
|
||||
background: color-mix(in srgb, var(--danger) 12%, transparent);
|
||||
color: var(--danger);
|
||||
}
|
||||
}
|
||||
|
||||
.proposal-date { flex-shrink: 0; font-size: 0.78rem; color: var(--faint); }
|
||||
|
||||
.proposal-decided { flex-shrink: 0; font-size: 0.76rem; font-style: italic; color: var(--faint); }
|
||||
|
||||
.proposal-actions {
|
||||
margin-left: auto;
|
||||
flex: none;
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
}
|
||||
|
||||
// applying a proposal is the yes of the pair — solid, the way the wiki's
|
||||
// other primary asks are; refusing stays the quiet ghost beside it
|
||||
.btn-approve {
|
||||
background: var(--success);
|
||||
color: #fff;
|
||||
box-shadow: 0 6px 18px -8px color-mix(in srgb, var(--success) 65%, transparent);
|
||||
|
||||
&:hover { filter: brightness(1.08); }
|
||||
}
|
||||
|
||||
// the page moved after the request was sent — approving overwrites that
|
||||
.proposal-stale { font-size: 0.78rem; font-style: italic; color: var(--danger); }
|
||||
|
||||
.proposal-diff {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr 1fr;
|
||||
gap: 18px;
|
||||
margin-top: 14px;
|
||||
padding-top: 14px;
|
||||
border-top: 1px dashed var(--border);
|
||||
}
|
||||
|
||||
.proposal-diff-col { min-width: 0; }
|
||||
|
||||
.diff-heading {
|
||||
margin: 0 0 10px;
|
||||
font-size: 0.72rem;
|
||||
font-weight: 700;
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 0.08em;
|
||||
|
||||
&.is-before { color: var(--faint); }
|
||||
&.is-after { color: var(--success); }
|
||||
}
|
||||
|
||||
.diff-title {
|
||||
margin: 0 0 8px;
|
||||
font-size: 1rem;
|
||||
color: var(--text);
|
||||
|
||||
del { color: var(--faint); text-decoration-color: color-mix(in srgb, var(--danger) 60%, transparent); }
|
||||
}
|
||||
|
||||
.diff-tags {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: 6px;
|
||||
margin: 0 0 12px;
|
||||
}
|
||||
|
||||
.diff-tag {
|
||||
padding: 2px 9px;
|
||||
border-radius: 7px;
|
||||
background: var(--surface-2);
|
||||
color: var(--muted);
|
||||
font-size: 0.72rem;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
// the two pages: tall articles scroll inside their frame rather than
|
||||
// stretching the dashboard out without end
|
||||
.diff-body {
|
||||
max-height: 420px;
|
||||
overflow-y: auto;
|
||||
padding: 2px 16px 14px;
|
||||
border: 1px solid var(--border);
|
||||
border-radius: 12px;
|
||||
background: var(--bg-elev);
|
||||
}
|
||||
|
||||
// the half of a creation's diff where a page would go: the frame the other
|
||||
// side fills with text, holding only the words that say it is not written yet
|
||||
.diff-absent {
|
||||
margin: 16px 0;
|
||||
font-size: 0.85rem;
|
||||
font-style: italic;
|
||||
color: var(--faint);
|
||||
}
|
||||
|
||||
// the fold over the decided requests: a heading you open, nothing louder
|
||||
.proposal-history-toggle {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
margin: 20px 0 12px;
|
||||
padding: 4px 2px;
|
||||
border: none;
|
||||
background: none;
|
||||
color: var(--muted);
|
||||
font-size: 0.85rem;
|
||||
font-weight: 700;
|
||||
letter-spacing: -0.01em;
|
||||
cursor: pointer;
|
||||
|
||||
&:hover { color: var(--text); }
|
||||
|
||||
svg { transition: transform 0.18s ease; }
|
||||
svg.turned { transform: rotate(90deg); }
|
||||
}
|
||||
|
||||
// the request row's skeleton, in the shape of one entry
|
||||
.proposal-skeleton { height: 74px; }
|
||||
|
||||
@media (max-width: 720px) {
|
||||
.proposal-diff { grid-template-columns: 1fr; }
|
||||
.proposal-actions { margin-left: 0; }
|
||||
}
|
||||
@@ -32,8 +32,9 @@
|
||||
|
||||
.settings-group-hint { font-size: 0.8rem; color: var(--muted); }
|
||||
|
||||
// segmented light / dark switch
|
||||
.theme-switch { @include segmented; }
|
||||
// segmented control: the settings' light / dark switch and the profile's
|
||||
// language row; wraps so a narrow screen never clips the last choice
|
||||
.theme-switch { @include segmented; flex-wrap: wrap; }
|
||||
|
||||
.theme-option {
|
||||
display: inline-flex;
|
||||
|
||||
@@ -16,6 +16,14 @@
|
||||
h3 { margin: 0 0 6px; color: var(--text); font-size: 1.15rem; }
|
||||
|
||||
p { margin: 0 auto 22px; max-width: 42ch; font-size: 0.93rem; }
|
||||
|
||||
// two ways forward from a dead end, side by side
|
||||
.empty-actions {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
flex-wrap: wrap;
|
||||
gap: 12px;
|
||||
}
|
||||
}
|
||||
|
||||
.banner {
|
||||
@@ -37,6 +45,32 @@
|
||||
border-radius: 5px;
|
||||
font-size: 0.85em;
|
||||
}
|
||||
|
||||
// a rule the same size and shape, in another temper: green once a change
|
||||
// has landed somewhere, blue for what the page wants you to know first
|
||||
&.banner-success {
|
||||
border-color: color-mix(in srgb, var(--success) 35%, var(--border));
|
||||
background: color-mix(in srgb, var(--success) 7%, var(--surface));
|
||||
|
||||
.glyph { color: var(--success); }
|
||||
}
|
||||
|
||||
&.banner-info {
|
||||
border-color: color-mix(in srgb, var(--accent) 30%, var(--border));
|
||||
background: color-mix(in srgb, var(--accent) 6%, var(--surface));
|
||||
|
||||
.glyph { color: var(--accent); }
|
||||
}
|
||||
|
||||
.banner-link {
|
||||
color: var(--accent);
|
||||
font-weight: 650;
|
||||
text-decoration: underline;
|
||||
text-underline-offset: 2px;
|
||||
white-space: nowrap;
|
||||
|
||||
&:hover { color: var(--accent-strong); }
|
||||
}
|
||||
}
|
||||
|
||||
.skeleton { border-radius: 16px; height: 172px; @include shimmer; }
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
--accent-strong: #3d4dd6;
|
||||
--accent-2: #0ea5c9;
|
||||
--danger: #d1344b;
|
||||
--success: #189a5c;
|
||||
--code-bg: #f4f6fa;
|
||||
--shadow-sm: 0 1px 2px rgb(16 24 40 / 6%), 0 1px 3px rgb(16 24 40 / 8%);
|
||||
--shadow-lg: 0 4px 12px rgb(16 24 40 / 8%), 0 16px 40px -12px rgb(16 24 40 / 18%);
|
||||
@@ -58,6 +59,7 @@
|
||||
--accent-strong: #99a5ff;
|
||||
--accent-2: #38d3ee;
|
||||
--danger: #f47085;
|
||||
--success: #3fce8b;
|
||||
--code-bg: #0c0f16;
|
||||
--shadow-sm: 0 1px 2px rgb(0 0 0 / 30%);
|
||||
--shadow-lg: 0 4px 16px rgb(0 0 0 / 40%), 0 24px 48px -16px rgb(0 0 0 / 55%);
|
||||
|
||||
@@ -20,6 +20,7 @@
|
||||
@use 'langs'; // badges, chips, version & language menus
|
||||
@use 'states'; // empty, banner, skeleton
|
||||
@use 'admin'; // the accounts dashboard
|
||||
@use 'proposals'; // the dashboard's edit requests from members
|
||||
@use 'article'; // article page, ⋮ menu, TOC, recently viewed
|
||||
@use 'prose'; // rendered markdown, highlight.js, KaTeX
|
||||
@use 'editor'; // editor, cheatsheet, confirm, fullscreen
|
||||
|
||||
Reference in New Issue
Block a user