1
Fork 0
mirror of https://github.com/thegeneralist01/archivr synced 2026-10-09 12:55:00 +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

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View file

@ -6,8 +6,8 @@
<title>Archivr</title>
<link rel="icon" type="image/svg+xml" href="/favicon.svg">
<link rel="icon" type="image/x-icon" href="/favicon.ico">
<script type="module" crossorigin src="/assets/index-CthL4K20.js"></script>
<link rel="stylesheet" crossorigin href="/assets/index-DicH9MNh.css">
<script type="module" crossorigin src="/assets/index-CQcpPA_I.js"></script>
<link rel="stylesheet" crossorigin href="/assets/index-BLxoi9rt.css">
</head>
<body>
<div id="root"></div>

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;
}