release: v0.17.0 (#677)

See CHANGELOG.md, section [0.17.0] — 2026-09-23.
This commit is contained in:
Ralksta
2026-09-23 12:09:08 +02:00
committed by GitHub
parent a3a6319c29
commit 89a8fac564
78 changed files with 9485 additions and 2050 deletions

View File

@@ -0,0 +1,676 @@
/* ── Journal Studio & Editor CSS ──────────────────────────────────── */
/*
* The studio is a full-width workspace: it breaks out of the 1120px
* `.admin-main` column so the split view has room for editor *and* preview.
*/
.admin-main:has(> .journal-studio),
.admin-main:has(> .journal-editor-container) {
max-width: none;
padding: 0;
}
/* ── Form controls ─────────────────────────────────────────────────
* Local field styling for the studio. Scoped so the generic class name
* cannot leak into the rest of the admin panel.
*/
.journal-studio .admin-input,
.journal-editor-container .admin-input,
.journal-modal-card .admin-input {
display: block;
width: 100%;
padding: 0.55rem 0.7rem;
background: var(--admin-bg-input, #161616);
border: 1px solid var(--admin-border, #2e2e2e);
border-radius: 8px;
color: var(--admin-text, #f0f0f0);
font-family: inherit;
font-size: 0.875rem;
line-height: 1.5;
transition:
border-color 0.15s ease,
background 0.15s ease;
}
.journal-studio .admin-input:hover,
.journal-editor-container .admin-input:hover,
.journal-modal-card .admin-input:hover {
border-color: var(--admin-border-hover, #444);
}
.journal-studio .admin-input:focus-visible,
.journal-editor-container .admin-input:focus-visible,
.journal-modal-card .admin-input:focus-visible {
outline: var(--admin-focus-ring);
outline-offset: 1px;
border-color: var(--admin-border-focus, #6366f1);
}
.journal-studio .admin-input::placeholder,
.journal-editor-container .admin-input::placeholder,
.journal-modal-card .admin-input::placeholder {
color: var(--admin-text-secondary, #a0a0a0);
opacity: 0.7;
}
.journal-editor-container textarea.admin-input,
.journal-modal-card textarea.admin-input {
resize: vertical;
min-height: 88px;
}
.journal-editor-container select.admin-input {
cursor: pointer;
appearance: none;
padding-right: 2rem;
background-image:
linear-gradient(45deg, transparent 50%, currentColor 50%),
linear-gradient(135deg, currentColor 50%, transparent 50%);
background-position:
calc(100% - 16px) calc(50% + 1px),
calc(100% - 11px) calc(50% + 1px);
background-size: 5px 5px;
background-repeat: no-repeat;
}
.journal-level-select {
width: 5.5rem;
flex-shrink: 0;
}
.journal-studio {
display: flex;
flex-direction: column;
height: 100%;
min-height: calc(100vh - 70px);
}
.journal-studio-header {
display: flex;
align-items: center;
justify-content: space-between;
padding: 1.5rem 2rem;
border-bottom: 1px solid var(--admin-border, rgba(255, 255, 255, 0.08));
}
.journal-studio-header h2 {
margin: 0;
font-size: 1.5rem;
font-weight: 700;
display: flex;
align-items: center;
gap: 10px;
}
.journal-list-grid {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(320px, 1fr));
gap: 1.5rem;
padding: 2rem;
}
.journal-admin-card {
background: var(--admin-surface, rgba(255, 255, 255, 0.03));
border: 1px solid var(--admin-border, rgba(255, 255, 255, 0.08));
border-radius: 10px;
overflow: hidden;
display: flex;
flex-direction: column;
transition:
border-color 0.2s ease,
transform 0.2s ease;
}
.journal-admin-card:hover {
border-color: var(--admin-accent, #6366f1);
transform: translateY(-2px);
}
.journal-admin-card-cover {
position: relative;
width: 100%;
aspect-ratio: 16 / 9;
background: rgba(0, 0, 0, 0.2);
display: flex;
align-items: center;
justify-content: center;
}
.journal-admin-card-cover img {
width: 100%;
height: 100%;
object-fit: cover;
}
.journal-admin-card-body {
padding: 1.25rem;
display: flex;
flex-direction: column;
flex-grow: 1;
}
.journal-admin-card-title {
font-size: 1.15rem;
font-weight: 600;
margin: 0 0 0.4rem;
}
.journal-admin-card-slug {
font-size: 0.75rem;
font-family: monospace;
opacity: 0.6;
margin-bottom: 0.75rem;
}
.journal-admin-card-meta {
display: flex;
align-items: center;
gap: 8px;
font-size: 0.75rem;
opacity: 0.7;
margin-bottom: 1rem;
flex-wrap: wrap;
}
.journal-admin-card-actions {
display: flex;
align-items: center;
gap: 8px;
margin-top: auto;
padding-top: 1rem;
border-top: 1px solid var(--admin-border, rgba(255, 255, 255, 0.06));
}
/* ── Split-Screen Studio Editor ────────────────────────────────────── */
.journal-editor-container {
display: flex;
flex-direction: column;
height: calc(100vh - 65px);
overflow: hidden;
}
.journal-editor-topbar {
display: flex;
align-items: center;
justify-content: space-between;
padding: 0.75rem 1.5rem;
background: var(--admin-surface, #18181b);
border-bottom: 1px solid var(--admin-border, rgba(255, 255, 255, 0.08));
gap: 1rem;
z-index: 10;
}
.journal-editor-topbar-left {
display: flex;
align-items: center;
gap: 1rem;
flex-grow: 1;
}
.journal-editor-title-input {
font-size: 1.1rem;
font-weight: 600;
background: transparent;
border: 1px solid transparent;
border-radius: 6px;
color: inherit;
padding: 4px 8px;
max-width: 400px;
width: 100%;
}
.journal-editor-title-input:focus {
border-color: var(--admin-accent, #6366f1);
background: rgba(255, 255, 255, 0.05);
}
.journal-editor-topbar-right {
display: flex;
align-items: center;
gap: 0.75rem;
}
.journal-editor-split {
display: grid;
/* Left width is driven by the draggable divider; the preview takes the rest. */
grid-template-columns: var(--journal-split-left, 46%) 7px minmax(0, 1fr);
flex-grow: 1;
overflow: hidden;
height: 100%;
}
/* Kill text selection and pointer flicker while the divider is being dragged. */
.journal-editor-split.is-dragging {
user-select: none;
cursor: col-resize;
}
.journal-editor-split.is-dragging .journal-editor-pane-right {
pointer-events: none;
}
.journal-editor-resizer {
position: relative;
cursor: col-resize;
background: var(--admin-border, rgba(255, 255, 255, 0.08));
transition: background 0.15s ease;
touch-action: none;
}
.journal-editor-resizer:hover,
.journal-editor-resizer:focus-visible,
.journal-editor-split.is-dragging .journal-editor-resizer {
background: var(--admin-accent, #6366f1);
}
/* The resizer used to change colour on focus exactly as it does on hover,
so from the keyboard there was no telling whether it had the focus or the
mouse was merely resting on it. */
.journal-editor-resizer:focus-visible {
outline: var(--admin-focus-ring);
outline-offset: 2px;
}
/* Grip dots, and a widened invisible hit area so the divider is easy to grab. */
.journal-editor-resizer-grip {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
width: 15px;
height: 44px;
border-radius: 4px;
background: repeating-linear-gradient(to bottom, currentColor 0 2px, transparent 2px 5px);
color: rgba(255, 255, 255, 0.35);
background-clip: content-box;
padding: 0 6px;
}
.journal-editor-resizer:hover .journal-editor-resizer-grip {
color: #fff;
}
.journal-editor-pane-left {
display: flex;
flex-direction: column;
overflow-y: auto;
padding: 1.5rem 2rem 4rem;
background: var(--admin-bg, #09090b);
}
.journal-editor-pane-right {
display: flex;
flex-direction: column;
overflow-y: auto;
background: var(--admin-bg, #111);
position: relative;
}
.journal-preview-bar {
display: flex;
align-items: center;
justify-content: space-between;
padding: 0.5rem 1rem;
background: rgba(0, 0, 0, 0.4);
border-bottom: 1px solid rgba(255, 255, 255, 0.05);
font-size: 0.75rem;
position: sticky;
top: 0;
z-index: 5;
backdrop-filter: blur(8px);
}
.journal-preview-frame {
padding: 2.5rem 2rem;
max-width: 1080px;
margin: 0 auto;
width: 100%;
transition: max-width 0.3s ease;
}
/*
* The essay's full-bleed and wide figures are sized against the viewport on the
* live site. Inside the preview pane that overshoots — the photo would bleed out
* of the pane and drift as the split is dragged — so they are re-anchored to the
* frame. 100% is the container's content box, so reaching the pane edges means
* adding back both horizontal paddings: 4rem for this frame plus 3rem for
* .essay-container. Keep in sync if either padding changes.
*/
.journal-preview-frame .essay-container {
--essay-bleed: calc(100% + 7rem);
--essay-wide: 100%;
}
.journal-preview-frame.mobile {
max-width: 380px;
border-left: 1px solid rgba(255, 255, 255, 0.1);
border-right: 1px solid rgba(255, 255, 255, 0.1);
min-height: 100%;
background: var(--background, #000);
}
.journal-raw-markdown-editor {
width: 100%;
height: 100%;
min-height: 500px;
font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace;
font-size: 0.9rem;
line-height: 1.6;
background: rgba(0, 0, 0, 0.3);
color: #f4f4f5;
border: 1px solid var(--admin-border, rgba(255, 255, 255, 0.1));
border-radius: 8px;
padding: 1.25rem;
resize: none;
}
.journal-raw-markdown-editor:focus-visible {
outline: var(--admin-focus-ring);
outline-offset: 1px;
border-color: var(--admin-accent, #6366f1);
}
/* Modal styling for Entry creation / Metadata */
.journal-modal-overlay {
position: fixed;
inset: 0;
background: rgba(0, 0, 0, 0.75);
display: flex;
align-items: center;
justify-content: center;
z-index: 100;
backdrop-filter: blur(4px);
}
.journal-modal-card {
background: var(--admin-surface, #18181b);
border: 1px solid var(--admin-border, rgba(255, 255, 255, 0.1));
border-radius: 12px;
width: 90%;
max-width: 620px;
max-height: 88vh;
overflow-y: auto;
padding: 1.75rem;
box-shadow: 0 20px 40px rgba(0, 0, 0, 0.5);
}
/* ── Template picker (Create modal) ──────────────────────────────── */
.journal-template-grid {
display: grid;
grid-template-columns: repeat(2, 1fr);
gap: 0.5rem;
max-height: 260px;
overflow-y: auto;
padding: 2px;
}
.journal-template-card {
display: flex;
flex-direction: column;
gap: 2px;
align-items: flex-start;
text-align: left;
padding: 0.55rem 0.7rem;
background: var(--admin-bg-input, #161616);
/* <button> does not inherit color or font from its parent — without these
the cards render in the UA default, black on the dark admin surface. */
color: var(--admin-text, #f0f0f0);
font: inherit;
border: 2px solid transparent;
border-radius: 8px;
cursor: pointer;
transition: border-color 0.15s ease;
}
.journal-template-card:hover {
border-color: var(--admin-border-hover, #444);
}
.journal-template-card.is-selected {
border-color: var(--admin-accent, #6366f1);
}
.journal-template-card-name {
font-size: 0.85rem;
font-weight: 600;
}
.journal-template-card-desc {
font-size: 0.75rem;
opacity: 0.65;
}
/* ── Photo grid block (editor tiles) ─────────────────────────────── */
.journal-grid-tiles {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(110px, 1fr));
gap: 8px;
}
.journal-grid-tile {
position: relative;
}
.journal-grid-tile-pick {
height: 80px;
background: rgba(0, 0, 0, 0.3);
border: 1px dashed rgba(255, 255, 255, 0.15);
border-radius: 6px;
overflow: hidden;
display: flex;
align-items: center;
justify-content: center;
cursor: pointer;
font-size: 0.8rem;
opacity: 0.85;
}
.journal-grid-tile-pick img {
width: 100%;
height: 100%;
object-fit: cover;
}
.journal-grid-tile-remove {
position: absolute;
top: 4px;
right: 4px;
padding: 2px 5px;
}
/* ── Facts block (editor rows) ───────────────────────────────────── */
.journal-facts-row {
display: grid;
grid-template-columns: 1fr 2fr auto;
gap: 8px;
align-items: center;
}
/* ── Album block (editor) ────────────────────────────────────────── */
.journal-album-row {
display: flex;
gap: 8px;
align-items: center;
flex-wrap: wrap;
}
.journal-album-field {
display: flex;
flex-direction: column;
gap: 2px;
font-size: 0.7rem;
opacity: 0.85;
flex: 1 1 120px;
min-width: 0;
}
.journal-album-field .admin-input {
width: 100%;
}
/* ── Map block (editor pin rows) ─────────────────────────────────── */
.journal-map-row {
display: flex;
gap: 6px;
align-items: center;
flex-wrap: wrap;
}
.journal-map-row .admin-input {
flex: 1 1 140px;
width: auto;
min-width: 0;
}
.journal-map-row .journal-map-coord {
flex: 0 1 110px;
}
.journal-map-index {
width: 1.4rem;
font-size: 0.7rem;
opacity: 0.6;
text-align: right;
flex: none;
}
.journal-map-photo {
width: 96px;
height: 64px;
flex: none;
background: rgba(0, 0, 0, 0.3);
border: 1px dashed rgba(255, 255, 255, 0.15);
border-radius: 6px;
overflow: hidden;
display: flex;
align-items: center;
justify-content: center;
cursor: pointer;
font-size: 0.75rem;
opacity: 0.85;
}
.journal-map-photo img {
width: 100%;
height: 100%;
object-fit: cover;
}
.journal-map-all {
flex: 1;
font-size: 0.8rem;
opacity: 0.8;
}
.journal-map-line-toggle {
margin-left: auto;
display: flex;
align-items: center;
gap: 6px;
font-size: 0.8rem;
cursor: pointer;
}
/* ── Card meta & status ───────────────────────────────────────────── */
.journal-admin-card-meta span {
display: inline-flex;
align-items: center;
gap: 4px;
}
.journal-card-cover-placeholder {
opacity: 0.25;
}
.journal-status-pill {
padding: 0.15rem 0.5rem;
border-radius: 9999px;
font-size: 0.7rem;
font-weight: 600;
text-transform: uppercase;
letter-spacing: 0.04em;
opacity: 1;
}
.journal-status-pill.is-draft {
background: rgba(234, 179, 8, 0.15);
color: #eab308;
border: 1px solid rgba(234, 179, 8, 0.3);
}
.journal-status-pill.is-published {
background: rgba(34, 197, 94, 0.15);
color: #22c55e;
border: 1px solid rgba(34, 197, 94, 0.3);
}
.journal-preview-bar-label {
display: inline-flex;
align-items: center;
gap: 6px;
}
/* ── Block field rows ─────────────────────────────────────────────
* The generic `.admin-input { width: 100% }` would blow these rows apart,
* so the fixed-width controls are pinned here (higher specificity wins).
*/
.journal-heading-row,
.journal-photo-layout-row {
display: flex;
align-items: center;
gap: 8px;
}
.journal-editor-container .journal-heading-row .journal-level-select {
flex: 0 0 5.5rem;
width: 5.5rem;
}
.journal-editor-container .journal-heading-row input {
flex: 1 1 auto;
min-width: 0;
}
.journal-editor-container .journal-photo-layout-row select {
flex: 1 1 auto;
min-width: 0;
}
.journal-photo-layout-row .admin-btn {
flex-shrink: 0;
}
/* Stack the split view on narrow screens instead of squeezing both panes. */
@media (max-width: 1100px) {
.journal-editor-split {
grid-template-columns: 1fr;
grid-template-rows: minmax(0, 1fr) minmax(0, 1fr);
}
.journal-editor-resizer {
display: none;
}
.journal-editor-pane-left {
border-bottom: 1px solid var(--admin-border, rgba(255, 255, 255, 0.08));
}
}
/* An unresolvable photo reference — shown in the block editor, not to visitors. */
.journal-block-warning {
margin: 0 0 0.75rem;
padding: 0.55rem 0.7rem;
border-radius: 8px;
font-size: 0.78rem;
line-height: 1.45;
color: #fca5a5;
background: rgba(239, 68, 68, 0.1);
border: 1px solid rgba(239, 68, 68, 0.3);
}