innhold/content/publiser/publiser.css
Ruben b609c8596c Add standalone /publiser admin application
Implement a minimal, dependency-free publishing tool to manage news
and articles. The app includes:

- A Markdown-based block editor with rich-text capabilities.
- Image upload and resizing using GD.
- Support for drafts, scheduled publishing, and a trash system.
- Integrated Basic Auth protection via PHP and .htpasswd.
- A global plugin for automatic execution of scheduled posts.

The tool reuses core site logic in custom/plugins/publiser-lib.php to
ensure consistency between the editor and the live site.
2026-08-30 21:54:17 +02:00

376 lines
8.4 KiB
CSS

/* /publiser admin app - reuses the site's CSS variables (base.css) for
brand consistency, but is otherwise a self-contained layout. Follows the
site convention of margin-top-only spacing (global reset zeroes
margin-bottom). */
/* Reuses the site's own .button class for nav/action links (base.css), so
they inherit real site styling instead of parallel custom classes. The
header bar itself has no site equivalent (the public site's header is a
narrower, logo-anchored layout) - .p-topbar-inner matches .p-main's width
instead, left-aligned. */
.p-app {
font-family: var(--font-body);
color: var(--color-grey);
background: var(--color-green-light);
min-height: 100vh;
}
.p-topbar {
background: #fff;
border-bottom: 3px #00000022 solid;
}
.p-topbar-inner {
max-width: 64rem;
margin: 0 auto;
padding: .8rem 1rem;
box-sizing: border-box;
}
.p-topbar-inner ul {
display: flex;
flex-wrap: wrap;
list-style: none;
gap: .6rem;
margin: 0;
padding: 0;
}
.p-main {
max-width: 64rem;
margin: 0 auto;
padding: 1.5rem 1rem 4rem;
}
h1 {
font-family: var(--font-heading);
color: var(--color-green);
font-size: 1.8rem;
font-weight: 400;
}
.p-muted { color: #777; font-size: .9rem }
.p-editor-topline {
display: flex;
flex-wrap: wrap;
justify-content: space-between;
align-items: center;
gap: 1rem;
}
.p-back, .p-view-live {
display: inline-block;
margin-top: 0;
font-size: .9rem;
}
.p-notice {
margin-top: .8rem;
padding: .6rem .9rem;
background: var(--color-green-light);
border: 1px solid var(--color-green);
border-radius: .4rem;
color: var(--color-grey);
}
.p-notice-error {
background: #fdecea;
border-color: #c0392b;
}
/* --- list view --- */
.p-header-row {
display: flex;
flex-wrap: wrap;
align-items: baseline;
gap: 1rem;
justify-content: space-between;
}
.p-section-switch a {
padding: .3rem .7rem;
border-radius: .4rem;
font-size: .9rem;
}
.p-section-switch a.active {
background: var(--color-green);
color: #fff !important;
}
.p-empty { margin-top: 2rem; color: #777 }
.p-list {
list-style: none;
margin-top: 1rem;
padding: 0;
display: flex;
flex-direction: column;
gap: .6rem;
}
.p-list-item {
display: flex;
align-items: center;
gap: 1rem;
background: #fff;
border-radius: .5rem;
padding: .6rem .9rem;
border: 1px solid #00000012;
}
.p-list-cover {
width: 4rem;
height: 4rem;
object-fit: cover;
border-radius: .4rem;
flex: none;
}
.p-list-cover-empty { background: #eee }
.p-list-info { flex: 1; min-width: 0 }
.p-list-title {
font-weight: 700;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.p-list-meta { font-size: .85rem; color: #777; margin-top: .1rem }
.p-list-actions form { margin: 0 }
/* --- buttons & forms --- */
/* base.css's .button has no destructive/danger variant - the one addition
needed on top of the site's real button styling. */
.button.danger { outline-color: #c0392b; color: #c0392b }
.button.danger:hover, .button.danger:focus { background-color: #c0392b; color: #fff; outline: none }
.p-form label {
display: block;
margin-top: 1rem;
font-size: .82rem;
font-weight: 600;
color: #555;
}
.p-side-box .p-form label:first-of-type,
.p-side-box label:first-of-type { margin-top: .6rem }
.p-form input[type=text],
.p-form input[type=date],
.p-form input[type=datetime-local],
.p-form textarea,
.p-form select {
display: block;
width: 100%;
margin-top: .35rem;
padding: .5rem .6rem;
border: 1px solid #00000022;
border-radius: .4rem;
font-family: var(--font-body);
font-size: .95rem;
color: var(--color-grey);
background: #fbfbfa;
box-sizing: border-box;
transition: border-color .15s, background .15s;
}
.p-form input[type=text]:focus,
.p-form input[type=date]:focus,
.p-form input[type=datetime-local]:focus,
.p-form textarea:focus,
.p-form select:focus {
outline: none;
border-color: var(--color-green);
background: #fff;
}
.p-form textarea { resize: vertical }
/* .p-form textarea's `display: block` above outranks the browser's native
[hidden] { display: none }, which un-hides this fallback field (it holds
the untouched block's raw content and must never actually show). Force it
back off with higher specificity. */
.p-form textarea.p-block-hidden { display: none }
.p-form-new { max-width: 28rem }
.p-form-new button { margin-top: 1.5rem }
/* --- editor --- */
.p-editor-grid {
display: grid;
grid-template-columns: minmax(0, 1fr) 18rem;
gap: 1.5rem;
margin-top: 1rem;
align-items: start;
}
@media (max-width: 55rem) {
.p-editor-grid { grid-template-columns: 1fr }
}
.p-title-input {
width: 100%;
font-family: var(--font-heading);
font-size: 1.8rem;
border: none;
border-bottom: 2px solid #00000015;
padding: .3rem 0;
background: transparent;
box-sizing: border-box;
}
.p-title-input:focus { outline: none; border-bottom-color: var(--color-green) }
.p-blocks {
display: flex;
flex-direction: column;
gap: 1rem;
margin-top: 1.5rem;
}
.p-block {
background: #fff;
border: 1px solid #00000015;
border-radius: .5rem;
overflow: hidden;
}
.p-block-toolbar {
display: flex;
flex-wrap: wrap;
align-items: center;
gap: .2rem;
padding: .4rem;
background: #fafaf8;
border-bottom: 1px solid #00000012;
}
.p-block-toolbar button {
border: 1px solid transparent;
background: transparent;
padding: .3rem .55rem;
border-radius: .3rem;
cursor: pointer;
font-size: .9rem;
color: var(--color-grey);
font-family: var(--font-body);
}
.p-block-toolbar button:hover { background: #eee }
.p-block-toolbar button.danger { color: #c0392b }
.p-block-toolbar button.danger:hover { background: #fdecea }
.p-block-spacer { flex: 1 }
.p-block-label { font-size: .85rem; color: #777; padding: 0 .4rem }
.p-richtext {
min-height: 6rem;
padding: 1rem;
line-height: 1.5;
}
.p-richtext:focus { outline: none; background: #fffef8 }
.p-richtext h2, .p-richtext h3 { margin-top: .6em; color: var(--color-green) }
.p-richtext p { margin-top: .8em }
.p-richtext p:first-child { margin-top: 0 }
.p-richtext img { max-width: 100%; border-radius: .3rem; margin-top: .5em }
.p-richtext blockquote {
margin-top: .8em;
padding-left: 1rem;
border-left: 3px solid var(--color-green);
color: #555;
}
.p-richtext ul, .p-richtext ol { margin-top: .5em; padding-left: 1.4rem }
.p-raw-html {
margin-top: .8em;
padding: .6rem;
border: 1px dashed #00000030;
border-radius: .4rem;
background: #fafaf8;
cursor: default;
position: relative;
}
.p-raw-html::before {
content: "Innebygd kode - kan flyttes/slettes, men ikke redigeres her";
display: block;
margin-bottom: .5em;
font-size: .75rem;
color: #888;
font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
}
.p-code {
width: 100%;
box-sizing: border-box;
border: none;
padding: 1rem;
font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
font-size: .85rem;
resize: vertical;
}
.p-code:focus { outline: none; background: #fffef8 }
.p-add-block {
display: flex;
flex-wrap: wrap;
gap: .6rem;
margin-top: 1rem;
}
.p-extra-files {
margin-top: 1.5rem;
padding: .8rem;
background: #fafaf8;
border-radius: .4rem;
font-size: .9rem;
}
.p-extra-files ul { margin-top: .3rem; padding-left: 1.2rem }
.p-editor-sidebar {
display: flex;
flex-direction: column;
gap: 1rem;
}
.p-side-box {
background: #fff;
border: 1px solid #00000015;
border-radius: .6rem;
padding: 1.1rem;
box-shadow: 0 1px 2px #00000008;
}
.p-side-label {
font-family: var(--font-heading);
font-size: 1rem;
font-weight: 400;
color: var(--color-green);
padding-bottom: .5rem;
border-bottom: 1px solid #00000012;
}
.p-actions-box { display: flex; flex-direction: column; gap: .6rem }
.p-actions-box .button { width: 100%; text-align: center; box-sizing: border-box }
.p-actions-box label { margin-top: .8rem }
.p-actions-box .p-muted { margin-top: 0 }
.p-cover-drop {
margin-top: .5rem;
border: 2px dashed #00000030;
border-radius: .4rem;
min-height: 6rem;
display: flex;
align-items: center;
justify-content: center;
text-align: center;
font-size: .85rem;
color: #777;
cursor: pointer;
padding: .5rem;
overflow: hidden;
}
.p-cover-drop.dragover { border-color: var(--color-green); background: var(--color-green-light) }
.p-cover-drop img { width: 100%; height: 8rem; object-fit: cover; border-radius: .3rem }
@media (max-width: 30rem) {
.p-main { padding: 1rem .7rem 4rem }
.p-list-item { flex-wrap: wrap }
}