1
Fork 0
mirror of https://github.com/thegeneralist01/archivr synced 2026-10-09 21:03:17 +02:00

fix(frontend): give text-capture row real CSS

The text row shipped with semantic classnames (`capture-text-inputs`,
`capture-text-title`, `capture-text-body`, `capture-text-mime`,
`capture-text-icon`) but no CSS rules. Falling through to the parent
`.capture-row-main` flex-row (`display: flex; align-items: center`)
meant the title, textarea, and mime-select stacked as intrinsic-width
boxes centered on the tall body, producing a layout where the body
floated to the top-right, the title box appeared BELOW it, and the mime
selector rendered as an unstyled OS dropdown.

Fix:
- `.capture-text-row .capture-row-main` uses `align-items: flex-start`
  so the leading icon and trailing × pin to the top of the block.
- `.capture-text-inputs` is now a full-width column-flex container with
  proper gaps.
- `.capture-text-title` reuses the 44px input height and typography of
  `.capture-input`; `.capture-text-body` gets a 140px min-height,
  vertical resize, and matching border/focus treatment.
- `.capture-text-mime` is styled as a small chip with a custom caret
  so it matches `.capture-quality` and stops looking like a raw
  `<select>`. Sits in a right-aligned footer under the body.
- `.capture-text-icon` gets a 44px column so it aligns with the title
  input; remove button gets a small top-margin for the same reason.

Rebuilt static bundle bumped as well (`index-BLxoi9rt.css`,
`index-CQcpPA_I.js`).
This commit is contained in:
archivr-qa 2026-08-23 18:49:15 +02:00
parent e97a31c0d1
commit 067d766819
No known key found for this signature in database
5 changed files with 197 additions and 30 deletions

View file

@ -302,10 +302,10 @@ select {
border-bottom: 1px solid var(--line-soft);
}
#entries-body > div > div { padding: 7px 10px; flex-shrink: 0; overflow: hidden; }
/* Skeleton rows (no index class) fall back to nth-child; real rows use explicit classes. */
/* Pending capture rows (no index class) fall back to nth-child; real rows use explicit classes. */
#entries-body > div:not(.entry-row-outer):nth-child(even) { background: #f2ede5; }
#entries-body > div:not(.entry-row-outer):nth-child(odd) { background: var(--paper-3); }
/* Index-based stripes for real entry rows — immune to skeleton sibling count. */
/* Index-based stripes for real entry rows — immune to pending-capture sibling count. */
#entries-body > .entry-row-outer--light { background: var(--paper-3); }
#entries-body > .entry-row-outer--dark { background: #f2ede5; }
#entries-body > div.is-selected {
@ -952,6 +952,104 @@ select {
line-height: 1.45;
}
/* ── Text-capture row ───────────────────────────────────────────────────
A text row breaks the [dot][one-line-input][×] shape used by URL and
file rows: it stacks a title, a multi-line body, and a small footer
(mime selector). Everything lives inside .capture-text-inputs so the
outer flex-row still gives us [icon][content][×] alignment. */
.capture-text-row > .capture-row-main {
/* Icon and remove button sit at the top of the block, not centered on
the tall textarea. */
align-items: flex-start;
}
.capture-text-icon {
flex-shrink: 0;
width: 20px;
height: 44px; /* matches .capture-text-title height */
display: grid;
place-items: center;
color: var(--muted);
}
.capture-text-inputs {
flex: 1 1 auto;
min-width: 0; /* let the textarea shrink inside flex */
display: flex;
flex-direction: column;
gap: 8px;
}
.capture-text-input {
width: 100%;
border: 1px solid var(--line);
background: var(--field);
color: var(--ink);
border-radius: var(--r2);
outline: none;
transition: border-color .15s ease, box-shadow .15s ease;
font-family: inherit;
}
.capture-text-input:focus {
border-color: var(--accent);
box-shadow: 0 0 0 3px color-mix(in srgb, var(--accent) 14%, transparent);
}
.capture-text-title {
height: 44px;
padding: 0 14px;
font-size: 15px;
}
.capture-text-body {
min-height: 140px;
padding: 10px 14px;
font-size: 14px;
line-height: 1.55;
resize: vertical;
}
.capture-text-body::placeholder,
.capture-text-title::placeholder {
color: var(--muted);
}
.capture-text-footer {
display: flex;
align-items: center;
gap: 8px;
justify-content: flex-end; /* mime selector sits under the body */
}
/* Mime selector: reuse the small chip styling of .capture-quality. */
.capture-text-mime {
flex-shrink: 0;
height: 28px;
padding: 0 26px 0 10px;
border: 1px solid var(--line);
border-radius: var(--r);
background: var(--paper);
color: var(--ink);
font-size: 12px;
cursor: pointer;
outline: none;
transition: border-color .15s;
/* Custom caret so it doesn't look like an unstyled OS dropdown. */
appearance: none;
-webkit-appearance: none;
background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 12 12' fill='none' stroke='%23888' stroke-width='1.75' stroke-linecap='round' stroke-linejoin='round'><path d='M3 4.5l3 3 3-3'/></svg>");
background-repeat: no-repeat;
background-position: right 8px center;
}
.capture-text-mime:hover { border-color: var(--accent-2); }
.capture-text-mime:focus { border-color: var(--accent); }
/* Remove button on text row: pin to top so tall bodies don't push it. */
.capture-text-row .capture-row-action {
margin-top: 8px;
}
/* Add-another button */
.capture-add-row {
display: flex;
@ -2836,36 +2934,44 @@ google-cast-launcher.video-tv-btn {
/* Push content above the fixed AudioBar when it is visible */
body.has-audio-bar { padding-bottom: 56px; }
/* ── Skeleton entry row ─────────────────────────────────────────────────── */
@keyframes skeleton-shimmer {
0% { background-position: 200% center; }
100% { background-position: -200% center; }
/* ── In-progress entry row ──────────────────────────────────────────────── */
.in-progress-entry-row {
box-sizing: border-box;
min-width: 0;
padding: 7px 22px;
gap: 9px;
color: var(--muted);
white-space: nowrap;
}
.skeleton-cell {
display: inline-block;
border-radius: 3px;
background: linear-gradient(90deg, var(--paper-2) 25%, var(--line-soft) 50%, var(--paper-2) 75%);
background-size: 200% 100%;
animation: skeleton-shimmer 1.8s ease-in-out infinite;
}
/* Row container — flex row matching #entries-body > div layout */
.skeleton-row {
display: flex;
align-items: center;
background: var(--paper-3);
}
.skeleton-row > div {
padding: 7px 10px;
.in-progress-entry-row__spinner {
width: 16px;
height: 16px;
border-width: 2px;
color: var(--accent);
flex-shrink: 0;
overflow: hidden;
}
.skeleton-row .col-added { padding-left: 22px; }
.skeleton-row > div:last-child { padding-right: 22px; }
.in-progress-entry-row__locator {
min-width: 0;
overflow: hidden;
text-overflow: ellipsis;
font-family: ui-monospace, "SF Mono", Menlo, monospace;
font-size: 11.5px;
}
.in-progress-entry-row__status {
display: inline-flex;
align-items: center;
gap: 5px;
flex-shrink: 0;
color: var(--muted-2);
font-size: 11.5px;
}
.in-progress-entry-row__kind {
font-size: 10.5px;
opacity: 0.85;
}
@media (pointer: coarse) {
.skeleton-row .col-added { padding-left: 10px; }
.in-progress-entry-row { padding-inline: 10px; }
}
/* ── Child entry expansion ───────────────────────────────────────────────── */
@ -3118,3 +3224,64 @@ body.has-audio-bar { padding-bottom: 56px; }
cursor: pointer;
}
.capture-sync-row input[type=checkbox] { cursor: pointer; }
/* ── Summary rail section ────────────────────────────────────────────────── */
/* Reuses .rail-section spacing and .rail-rearchive-btn for the action button;
only the summary-specific typography and the provider row are new here. */
.rail-summary-body { margin-bottom: 10px; }
.rail-summary-tldr {
margin: 0 0 8px;
font-size: 13.5px;
font-weight: 600;
color: var(--ink);
line-height: 1.45;
}
.rail-summary-text {
margin: 0 0 8px;
font-size: 13px;
color: var(--ink);
line-height: 1.55;
}
.rail-summary-tags { display: flex; flex-wrap: wrap; gap: 5px; margin-bottom: 8px; }
.rail-summary-tag {
font-size: 11px;
padding: 2px 7px;
border: 1px solid var(--line);
border-radius: 999px;
color: var(--muted);
}
.rail-summary-provider {
margin: 0;
font-size: 11px;
color: var(--muted-2);
letter-spacing: 0.02em;
}
.rail-summary-status {
display: flex; align-items: center; gap: 7px;
margin: 0 0 8px;
font-size: 12.5px;
color: var(--muted);
}
.rail-summary-spinner {
width: 11px; height: 11px;
border: 1.5px solid var(--line);
border-top-color: var(--muted);
border-radius: 50%;
animation: rail-summary-spin 0.7s linear infinite;
flex-shrink: 0;
}
@keyframes rail-summary-spin { to { transform: rotate(360deg); } }
/* Respect a reduced-motion preference: the text alone still conveys the state. */
@media (prefers-reduced-motion: reduce) {
.rail-summary-spinner { animation: none; }
}
.rail-summary-controls { display: flex; flex-direction: column; gap: 6px; }
.rail-summary-select {
width: 100%;
padding: 5px 8px;
font-size: 12.5px;
color: var(--ink);
background: var(--paper);
border: 1px solid var(--line);
border-radius: 4px;
}