Files
intotheeast-com-content/themes/intotheeast/js/src/post-form.css
T
m038andClaude Opus 4.8 034db29e66 fix(post-form): commit photo thumbnail grid + overlay styling
Renders FilePond items as a 3-up square-thumbnail grid on create+edit,
disables native image-drag so FilePond owns reorder, and hides the
file-info overlay on already-uploaded (idle) items. This is the styling
QA'd and approved on the worktree dev server; it was previously left
uncommitted (mis-tagged as unrelated WIP in earlier handovers).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Mpdu3Dt1iVoozHwAMyjrbn
2026-07-07 23:44:20 +02:00

522 lines
17 KiB
CSS
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/*
* /post form bundle CSS. U3 scope: make the EasyMDE editor usable without the
* FontAwesome dependency (toolbar glyphs supplied here). Field Notes theming,
* mobile layout, and the "More options" disclosure land in U5.
*/
/* Edit-mode prefill-failure banner (U5, D7): shown between the heading and the
first field when the entry can't be loaded for editing. */
.post-edit-error {
margin: 1rem 0;
padding: 0.75rem 1rem;
border: 1px solid #E5786A;
border-radius: 8px;
background: rgba(229, 120, 106, 0.12);
color: #E5786A;
font-size: 0.9rem;
line-height: 1.4;
}
/* EasyMDE toolbar glyphs — replace the FontAwesome icons EasyMDE expects. */
.editor-toolbar .mde-btn::before {
font-style: normal;
font-weight: 400;
font-family: inherit;
}
.editor-toolbar .mde-bold::before { content: 'B'; font-weight: 700; }
.editor-toolbar .mde-italic::before { content: 'I'; font-style: italic; }
.editor-toolbar .mde-ul::before { content: '\2022\2002\2014'; } /* • — */
.editor-toolbar .mde-link::before { content: '\1F517'; } /* 🔗 */
.editor-toolbar .mde-preview::before { content: '\1F441'; } /* 👁 */
.EasyMDEContainer .CodeMirror {
min-height: 180px;
}
/* ── Photo HEIC-conversion feedback (U4) ────────────────────
* FilePond renders the thumbnails/progress; these are the pre-FilePond
* "converting…" status line and the draft photos-reselect hint (U6).
*/
.photo-convert-status:empty { display: none; }
.photo-convert-status {
font-size: var(--text-sm);
margin-top: var(--space-2);
}
.photo-reauth-hint {
display: none;
font-size: var(--text-sm);
color: var(--color-ink-muted);
margin-top: var(--space-2);
}
.photo-reauth-hint.is-shown { display: block; }
/* ── Field Notes styling for the new controls (U5, R11/R12) ── */
/* Select fields (weather condition, transport mode) match the text inputs. */
.post-form-wrap select {
width: 100%;
font-family: var(--font-ui);
font-size: var(--text-base);
padding: 0.875rem 1rem;
min-height: 44px;
border: 1px solid var(--color-border);
border-radius: var(--radius-md);
background: var(--color-canvas);
color: var(--color-ink);
-webkit-appearance: none;
appearance: none;
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='8' viewBox='0 0 12 8'%3E%3Cpath fill='%2390887E' d='M1 1l5 5 5-5'/%3E%3C/svg%3E");
background-repeat: no-repeat;
background-position: right 1rem center;
padding-right: 2.5rem;
}
.post-form-wrap select:focus {
outline: 2px solid var(--color-accent);
outline-offset: 1px;
border-color: var(--color-accent);
}
.post-form-wrap input[type="number"] {
width: 100%;
font-family: var(--font-ui);
font-size: var(--text-base);
padding: 0.875rem 1rem;
min-height: 44px;
border: 1px solid var(--color-border);
border-radius: var(--radius-md);
background: var(--color-canvas);
color: var(--color-ink);
-webkit-appearance: none;
appearance: none;
}
.post-form-wrap input[type="number"]:focus {
outline: 2px solid var(--color-accent);
outline-offset: 1px;
border-color: var(--color-accent);
}
/* "More options" disclosure */
.more-options {
margin-bottom: var(--space-5);
border: 1px solid var(--color-border);
border-radius: var(--radius-md);
background: var(--color-canvas);
}
.more-options__summary {
cursor: pointer;
padding: 0.875rem 1rem;
min-height: 44px;
display: flex;
align-items: center;
font-family: var(--font-ui);
font-size: var(--text-sm);
font-weight: 600;
color: var(--color-ink);
list-style: none;
user-select: none;
}
.more-options__summary::-webkit-details-marker { display: none; }
.more-options__summary::before {
content: '▸';
margin-right: var(--space-2);
color: var(--color-ink-muted);
transition: transform 0.15s;
}
.more-options[open] .more-options__summary::before { transform: rotate(90deg); }
.more-options[open] .more-options__summary { border-bottom: 1px solid var(--color-border); }
.more-options > .form-field { padding: 0 1rem; }
.more-options > .form-field:first-of-type { padding-top: var(--space-4); }
.more-options > .form-field:last-child { padding-bottom: var(--space-4); margin-bottom: 0; }
/* Button loading spinner (Get Location / Get Weather) */
.btn-action.is-loading { position: relative; color: transparent; pointer-events: none; }
.btn-action.is-loading::after {
content: '';
position: absolute;
top: 50%;
left: 50%;
width: 16px;
height: 16px;
margin: -8px 0 0 -8px;
border: 2px solid var(--color-ink-muted);
border-top-color: var(--color-accent);
border-radius: 50%;
animation: post-spin 0.7s linear infinite;
}
.btn-action[disabled] { opacity: 0.5; cursor: not-allowed; }
@keyframes post-spin { to { transform: rotate(360deg); } }
/* Grav renders form status as <div class="notices success|error green|red">.
The theme doesn't style .notices, so on the dark background it was nearly
invisible — style it prominently here. */
.post-form-wrap .notices {
padding: 1rem 1.1rem;
border-radius: var(--radius-md);
font-size: var(--text-base);
margin: 0 0 var(--space-5);
background: var(--color-canvas);
color: var(--color-ink);
border-left: 4px solid var(--color-accent);
}
.post-form-wrap .notices p { margin: 0; }
.post-form-wrap .notices.error,
.post-form-wrap .notices.red { border-left-color: var(--color-error); }
.post-form-wrap .notices.success,
.post-form-wrap .notices.green { border-left-color: var(--color-accent); }
/* Post-success confirmation CTA (injected by post-form.js). */
.post-success {
margin: 0 0 var(--space-5);
padding: 1.1rem;
border-radius: var(--radius-md);
background: var(--color-accent-light);
border: 1px solid var(--color-accent);
}
.post-success__title {
font-family: var(--font-ui);
font-size: var(--text-md);
font-weight: 600;
color: var(--color-ink);
margin: 0 0 var(--space-3);
}
.post-success__actions { display: flex; flex-wrap: wrap; gap: var(--space-3); }
.post-success__view {
flex: 1;
min-width: 140px;
text-align: center;
padding: 0.8rem 1rem;
min-height: 44px;
border-radius: var(--radius-md);
background: var(--color-accent);
color: var(--color-accent-on);
font-weight: 600;
text-decoration: none;
}
.post-success__again {
flex: 1;
min-width: 140px;
text-align: center;
padding: 0.8rem 1rem;
min-height: 44px;
border-radius: var(--radius-md);
background: transparent;
color: var(--color-ink);
border: 1px solid var(--color-border);
font-weight: 600;
text-decoration: none;
}
/* Hide FilePond's "Powered by PQINA" credit. */
.filepond--credits { display: none !important; }
/* Field Notes dark theme for the FilePond widget — the default is a light/cream
panel that clashes with the site's warm near-black palette. Repaint the drop
zone, thumbnails and actions with the design tokens. */
.filepond--root { font-family: var(--font-ui); font-size: var(--text-base); }
.filepond--panel-root {
background-color: var(--color-canvas);
border: 1px solid var(--color-border);
border-radius: var(--radius-md);
}
.filepond--drop-label,
.filepond--drop-label label { color: var(--color-ink-muted); }
.filepond--label-action {
color: var(--color-accent);
text-decoration-color: var(--color-accent);
}
.filepond--item-panel {
background-color: var(--color-surface-raised);
border-radius: var(--radius-md);
}
.filepond--drip-blob { background-color: var(--color-accent); }
.filepond--file { color: var(--color-ink); }
.filepond--file-action-button {
color: var(--color-ink);
background-color: rgba(0, 0, 0, 0.45);
}
.filepond--file-action-button:hover { background-color: rgba(0, 0, 0, 0.65); }
/* Issue #2: FilePond's completed thumbnail carries a murky gradient tint + the
filename overlay, which reads as "something's wrong". Strip those overlays
and show a single clean green ✓ badge so a finished upload is unambiguous.
The remove (×) action button is left untouched so photos stay removable. */
.filepond--image-preview-overlay { display: none !important; }
.filepond--item[data-filepond-item-state="processing-complete"] .filepond--file-info,
.filepond--item[data-filepond-item-state="processing-complete"] .filepond--file-status {
opacity: 0;
}
.filepond--item[data-filepond-item-state="processing-complete"]::after {
content: '✓';
position: absolute;
top: 8px;
right: 8px;
z-index: 5;
width: 24px;
height: 24px;
line-height: 24px;
text-align: center;
border-radius: 50%;
background: var(--color-accent);
color: #fff;
font-size: 15px;
font-weight: 700;
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.35);
pointer-events: none;
}
/* ── Photo thumbnail grid (edit + create) ─────────────────────────────────
Render FilePond items as a compact square-thumbnail grid so existing photos
(loaded on edit) and new uploads are visible and reorderable without the
full-width, overflowing vertical list the default produced. Setting a fixed
item width is FilePond's supported way to switch its layout engine to a grid. */
.filepond--list.filepond--list {
/* FilePond positions items absolutely; the wrapper needs a little inset so
the 3-up grid doesn't butt against the drop-zone edge. */
margin: 0.25rem;
}
.filepond--item {
width: calc(33.333% - 0.5rem);
}
/* Square thumbnails regardless of source aspect ratio. */
.filepond--item .filepond--panel-root,
.filepond--item .filepond--image-preview-wrapper { border-radius: var(--radius-sm); }
/* Native image dragging hijacked FilePond's reorder: dragging a thumbnail
started a browser ghost-image / page scroll instead of moving the item.
Disable user-drag on the preview so FilePond owns the gesture. */
.filepond--image-preview,
.filepond--image-preview-wrapper,
.filepond--image-clip,
.filepond--image-preview canvas,
.filepond--image-bitmap,
.filepond--file img {
-webkit-user-drag: none;
-khtml-user-drag: none;
user-drag: none;
}
/* Existing photos loaded for editing sit in FilePond's 'idle' state (they are
already on the server, never uploaded). Give them the same clean look as a
completed upload — hide the filename/size overlay so the grid reads as photos,
not a list of filenames. */
.filepond--item[data-filepond-item-state="idle"] .filepond--file-info,
.filepond--item[data-filepond-item-state="idle"] .filepond--file-status {
opacity: 0;
}
/* Issue #3: photo section auto-collapses to a summary bar after upload — same
<details> affordance as "More options" above. */
.photos-collapse {
margin-bottom: var(--space-5);
border: 1px solid var(--color-border);
border-radius: var(--radius-md);
background: var(--color-canvas);
}
.photos-collapse__summary {
cursor: pointer;
padding: 0.875rem 1rem;
min-height: 44px;
display: flex;
align-items: center;
font-family: var(--font-ui);
font-size: var(--text-sm);
font-weight: 600;
color: var(--color-ink);
list-style: none;
user-select: none;
}
.photos-collapse__summary::-webkit-details-marker { display: none; }
.photos-collapse__summary::before {
content: '▸';
margin-right: var(--space-2);
color: var(--color-ink-muted);
transition: transform 0.15s;
}
.photos-collapse[open] .photos-collapse__summary::before { transform: rotate(90deg); }
.photos-collapse[open] .photos-collapse__summary { border-bottom: 1px solid var(--color-border); }
.photos-collapse > :not(summary) { padding-left: 1rem; padding-right: 1rem; }
.photos-collapse[open] .filepond--root,
.photos-collapse[open] .filepond-root { margin: var(--space-4) 0; }
.photos-collapse[open] > .photo-convert-status:last-child,
.photos-collapse[open] > .photo-reauth-hint:last-child { padding-bottom: var(--space-4); }
/* ── EasyMDE — Field Notes dark theme (U5) ─────────────────── */
.EasyMDEContainer .CodeMirror {
background: var(--color-canvas);
color: var(--color-ink);
border: 1px solid var(--color-border);
border-radius: 0 0 var(--radius-md) var(--radius-md);
font-family: var(--font-ui);
font-size: var(--text-base);
line-height: var(--leading-normal);
padding: var(--space-1);
}
.EasyMDEContainer .CodeMirror-cursor { border-color: var(--color-ink); }
.EasyMDEContainer .CodeMirror-selected { background: var(--color-accent-light) !important; }
.EasyMDEContainer .editor-toolbar {
background: var(--color-surface-raised);
border: 1px solid var(--color-border);
border-bottom: none;
border-radius: var(--radius-md) var(--radius-md) 0 0;
opacity: 1;
}
.EasyMDEContainer .editor-toolbar button {
color: var(--color-ink) !important;
min-width: 34px;
height: 34px;
}
.EasyMDEContainer .editor-toolbar button:hover,
.EasyMDEContainer .editor-toolbar button.active {
background: var(--color-accent-light);
border-color: var(--color-border);
}
.EasyMDEContainer .editor-toolbar i.separator { border-color: var(--color-border); }
.EasyMDEContainer .editor-preview,
.EasyMDEContainer .editor-preview-side {
background: var(--color-canvas);
color: var(--color-ink);
}
.EasyMDEContainer .editor-preview a { color: var(--color-accent); }
/* ── Photo editor (edit mode only) ────────────────────────────────────────
Own thumbnail grid that talks straight to the media API (add/delete/reorder
live), replacing the FilePond photo path when editing. */
.photo-editor {
margin-bottom: var(--space-5);
}
.photo-editor__head {
display: flex;
align-items: center;
justify-content: space-between;
gap: var(--space-3);
margin-bottom: var(--space-2);
}
.photo-editor__label {
font-family: var(--font-ui);
font-size: var(--text-base);
font-weight: 600;
color: var(--color-ink);
}
.photo-editor__add {
font-family: var(--font-ui);
font-size: var(--text-sm);
background: var(--color-accent);
color: #fff;
border: none;
border-radius: var(--radius-sm);
padding: var(--space-2) var(--space-4);
cursor: pointer;
}
.photo-editor__add:disabled { opacity: 0.5; cursor: default; }
.photo-editor__status {
font-size: var(--text-sm);
color: var(--color-ink-muted);
min-height: 1.2em;
margin: 0 0 var(--space-2);
}
.photo-editor__status.error { color: var(--color-error); }
.photo-editor__grid {
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: var(--space-2);
}
@media (min-width: 600px) {
.photo-editor__grid { grid-template-columns: repeat(4, 1fr); }
}
.photo-editor__loading,
.photo-editor__empty {
grid-column: 1 / -1;
color: var(--color-ink-muted);
font-size: var(--text-sm);
padding: var(--space-4) 0;
}
.photo-editor__cell {
position: relative;
aspect-ratio: 1 / 1;
border-radius: var(--radius-sm);
overflow: hidden;
background: var(--color-surface-raised);
cursor: grab;
touch-action: none; /* let SortableJS own the touch-drag gesture */
}
.photo-editor__cell:active { cursor: grabbing; }
.photo-editor__img {
width: 100%;
height: 100%;
object-fit: cover;
display: block;
-webkit-user-drag: none;
user-select: none;
pointer-events: none; /* the cell, not the image, is the drag handle */
}
/* First thumbnail is the feed cover. */
.photo-editor__cell:first-child::after {
content: 'Cover';
position: absolute;
left: var(--space-1);
bottom: var(--space-1);
font-family: var(--font-ui);
font-size: var(--text-xs, 0.7rem);
font-weight: 600;
color: #fff;
background: var(--color-accent);
padding: 1px 6px;
border-radius: var(--radius-sm);
pointer-events: none;
}
.photo-editor__del {
position: absolute;
top: var(--space-1);
right: var(--space-1);
width: 24px;
height: 24px;
line-height: 1;
display: flex;
align-items: center;
justify-content: center;
border: none;
border-radius: 50%;
background: rgba(0, 0, 0, 0.55);
color: #fff;
font-size: 0.85rem;
cursor: pointer;
}
.photo-editor__del:hover { background: rgba(0, 0, 0, 0.75); }
.photo-editor__del:disabled { opacity: 0.4; cursor: default; }
/* Inline delete confirm — covers the cell (option a: live delete, deliberate step). */
.photo-editor__confirm {
position: absolute;
inset: 0;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
gap: var(--space-1);
padding: var(--space-2);
background: rgba(0, 0, 0, 0.72);
text-align: center;
}
.photo-editor__confirm-q {
color: #fff;
font-family: var(--font-ui);
font-size: var(--text-sm);
}
.photo-editor__confirm button {
font-family: var(--font-ui);
font-size: var(--text-xs, 0.72rem);
border: none;
border-radius: var(--radius-sm);
padding: 3px 10px;
cursor: pointer;
}
.photo-editor__confirm-yes { background: var(--color-error); color: #fff; }
.photo-editor__confirm-no { background: #fff; color: var(--color-ink); }
.photo-editor__confirm button:disabled { opacity: 0.5; cursor: default; }
/* SortableJS drag feedback. */
.photo-editor__cell.sortable-ghost { opacity: 0.4; }
.photo-editor__cell.sortable-chosen { outline: 2px solid var(--color-accent); }