Cards are the concept media card: .media-art > button.image-open with the image or video, and .media-info with the D10 title (linked title only when the link is confirmed, else the filename; title attribute = path), the D11 subtitle "W x H · EXT · Seed N" (seed shown as the listing's string) and an Inspect info button. The byte size and the Preview button are gone. Activating the image (click, Enter, Space) opens the viewer and focus returns to it on Escape; Info selects the image into the panel (D19). Arrow, Home and End navigation, bounded rendering and scroll restoration are kept. Columns and gap now come from the concept grid's computed style (gridMetrics) instead of a production breakpoint table, so the concept breakpoints apply; a 120px minimum card bounds extreme zoom (D3, D31). images.css card rules are retired into marked overlay rules. The scope chip reads "All output folders" when no folder is chosen (D14).
110 lines
8.5 KiB
CSS
110 lines
8.5 KiB
CSS
/* Production overlay on the verbatim concept base (concept.css, D1 of #249). Only production-only states and recorded
|
|
deviations live here; a rule on a selector the concept also styles carries its decision marker. */
|
|
|
|
/* Production-only shell states. */
|
|
main:focus-visible { outline: 2px solid var(--ca-focus); outline-offset: 4px; }
|
|
/* The page title takes focus after a save or route change (concept app.js 1168); a keyboard user sees where it went. */
|
|
#page-title:focus { outline: none; }
|
|
#page-title:focus-visible { outline: 2px solid var(--ca-focus); outline-offset: 4px; }
|
|
/* D28: the sidebar shows no connection state, so its dot is neutral instead of the concept's demo green. */
|
|
.connection i { background: var(--ca-muted); }
|
|
/* D31: bounded rendering reads the grid's real width, so at extreme zoom the one-column shell must not grow to the
|
|
sidebar's min-content (the concept's `1fr`); the column is capped at the viewport as production's shell was. */
|
|
@media (max-width: 950px) {
|
|
.app-shell { grid-template-columns: minmax(0, 1fr); /* D31 */ }
|
|
}
|
|
@media (forced-colors: active) {
|
|
nav a[aria-current="page"] { border: 2px solid Highlight; color: LinkText; }
|
|
}
|
|
|
|
/* Overview: real library statistics and the legacy tool cards inside a concept `.surface`. */
|
|
.stat-grid { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 16px; margin: 0 0 26px; }
|
|
.stat { padding: 22px; background: var(--ca-surface); border: 1px solid var(--line); border-radius: 7px; }
|
|
.stat dt { color: var(--ca-muted); font-size: 12px; }
|
|
.stat dd { margin: 8px 0 0; font-size: 32px; font-weight: 600; }
|
|
.overview-stats > [role="status"], .overview-stats > [role="alert"], .empty-state { padding: 18px 0; color: var(--ca-muted); }
|
|
.overview-stats > [role="alert"] { color: var(--ca-error-text); }
|
|
.overview-stats > button { margin-bottom: 24px; }
|
|
.tool-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(100%, 250px), 1fr)); gap: 12px; margin-top: 22px; }
|
|
.tool-card { border: 1px solid var(--line); background: var(--ca-field); border-radius: 8px; padding: 20px; display: flex; flex-direction: column; gap: 10px; }
|
|
.tool-card p { flex: 1; margin: 0 0 12px; }
|
|
.workspace-link { display: inline-flex; align-items: center; min-height: 44px; padding: 8px 0; font-size: 12px; overflow-wrap: anywhere; }
|
|
.handoff .workspace-link { margin-top: 12px; }
|
|
@media (max-width: 700px) {
|
|
.stat-grid { gap: 8px; }
|
|
.stat { padding: 16px; }
|
|
.stat dd { font-size: 26px; }
|
|
}
|
|
|
|
/* Tags & categories (#245): real vocabulary has unbounded names and bounded lists, which the concept's short samples
|
|
never show. Proven by the 390px layout and long-name cases in workspace-vocabulary.spec.mjs. */
|
|
.vocabulary-main :where(.two-col, .surface, .table-wrap, .operation > div) { min-width: 0; }
|
|
.vocabulary-main .operation h3 { overflow-wrap: anywhere; }
|
|
/* Long tag names wrap inside the Tag cell so the Actions column keeps its intrinsic width; on two-column screens the
|
|
minimum keeps the concept's longest sample ("architecture", about 5em) on one line. */
|
|
.vocabulary-main td:first-child { overflow-wrap: anywhere; min-width: calc(6em + 20px); }
|
|
/* Tags & categories (#245 decision 5): bounded lists continue with Load more; never a scroll anchor, so appended rows push the end away. */
|
|
.vocabulary-main .vocabulary-continuation { display: flex; flex-wrap: wrap; align-items: center; gap: 12px; padding-block: 15px 0; overflow-anchor: none; }
|
|
.vocabulary-main .vocabulary-continuation p { margin: 0; flex: 1 1 200px; font-size: 12px; color: var(--ca-muted); }
|
|
.vocabulary-main .vocabulary-continuation .vocabulary-error { color: var(--ca-error-text); }
|
|
@media (max-width: 700px) {
|
|
/* One column: the Tag column has no fixed minimum and Actions asks only for its stacked width (the concept's 390px
|
|
rows stack Browse over Rename / merge), so a wider fallback font wraps the name instead of hiding an action. */
|
|
.vocabulary-main td:first-child { min-width: 0; }
|
|
.vocabulary-main td .row-actions { width: min-content; margin-inline-start: auto; }
|
|
}
|
|
|
|
/* Images (#249 C2). Production-only continuation states the concept never shows: a failed page and a load in flight. */
|
|
.infinite-continuation [role="alert"] { color: var(--ca-error-text); }
|
|
.infinite-continuation button[aria-disabled="true"] { opacity: .55; cursor: wait; }
|
|
/* #249 D14: the scope chip names real sources and folders, which can be far longer than "All output folders". */
|
|
.filter-row span.chip { max-width: 100%; min-width: 0; overflow-wrap: anywhere; }
|
|
/* #249 D32: at extreme zoom the 390px shell is narrower than the concept's three layout buttons; they wrap instead of
|
|
scrolling the page sideways (they never wrap while they fit). */
|
|
.segmented { flex-wrap: wrap; max-width: 100%; }
|
|
/* #249 D32: likewise the continuation's text and Load more wrap instead of pushing the button out of the column. */
|
|
.infinite-continuation { flex-wrap: wrap; }
|
|
|
|
/* Images cards (#249 C3). #249 D3: bounded rendering mounts only the visible cards and places each one itself, in every
|
|
layout (the concept places only masonry cards), so the grid reserves the collection's height and every card is
|
|
absolute. Columns and gap still come from the concept's `.image-grid` tracks. */
|
|
.image-grid { position: relative; /* D3 */ }
|
|
.image-grid > .media-card { position: absolute; }
|
|
/* #249 D3: a list row's info keeps its own height so it can be measured; centred, it looks as the stretched concept row.
|
|
#249 D31: it may also shrink below a long nowrap title (the h3 ellipsis then applies, as in the grid). */
|
|
.list-grid .media-info { align-self: center; min-width: 0; /* D3, D31 */ }
|
|
/* #249 D31: at extreme zoom a list row is narrower than the concept's 160px art; the art yields so the info stays inside. */
|
|
.list-grid .media-art { width: min(160px, 45%); /* D31 */ }
|
|
/* #249 D31: at extreme zoom the subtitle wraps inside its column instead of running under the Inspect button. */
|
|
.media-info p { overflow-wrap: anywhere; /* D31 */ }
|
|
/* #249 D31: below the narrowest bounded card (120px, reached only at extreme zoom; images.mjs marks the grid) the info
|
|
row stacks its text above Inspect, so neither the title nor the subtitle collapses to nothing beside the button. */
|
|
.narrow-cards .media-info { flex-wrap: wrap; }
|
|
.narrow-cards .media-info > div { flex: 1 0 100%; }
|
|
/* A list row beside its art keeps room for Inspect. */
|
|
.narrow-cards.list-grid .media-art { width: 40%; }
|
|
.narrow-cards.list-grid .media-info { padding-inline: 4px; }
|
|
|
|
/* Legacy video media (the mock does not drop it) takes the concept's image rules in each layout. */
|
|
.image-open video { display: block; width: 100%; height: auto; aspect-ratio: 1.33; object-fit: cover; }
|
|
.masonry-grid .image-open video { aspect-ratio: var(--media-ratio); object-fit: contain; }
|
|
.list-grid .image-open video { height: 95px; aspect-ratio: auto; }
|
|
|
|
/* Interim page guards: concept element rules (`.ca-tools dialog`, `pre`) now reach production dialogs and prompt text
|
|
that keep their own design until their page PR rebuilds them in concept markup. */
|
|
.panel { background: var(--ca-surface); border: 1px solid var(--line); } /* PR D: Images side panel (padding and radius in images.css) becomes `.detail-panel` */
|
|
.ca-tools dialog.image-preview { width: min(1500px, 96%); max-height: 94%; padding: 18px; overflow: hidden; } /* PR C: viewer becomes `#viewer-dialog` */
|
|
.ca-tools dialog.prompt-sender { width: min(760px, calc(100% - 32px)); max-width: none; max-height: calc(100dvh - 32px); padding: 22px; border-color: var(--ca-line); border-radius: 12px; } /* PR D */
|
|
.ca-tools dialog.prompt-sender::backdrop { background: #000b; } /* PR D */
|
|
.ca-tools dialog.recorded-run-dialog { width: min(1100px, calc(100% - 32px)); max-width: calc(100% - 32px); max-height: calc(100dvh - 32px); padding: 22px; border-radius: 7px; } /* PR F */
|
|
pre.prompt-text { background: none; padding: 0; border: 0; border-radius: 0; max-height: none; overflow: visible; } /* PR D: prompt text becomes `p.prompt-text` */
|
|
.viewer-container .viewer-hide { display: none; } /* PR C: the concept's own `.viewer-toolbar` would reveal Viewer.js's hidden toolbar */
|
|
.ca-tools .prompt-actions .ca-icon-button { min-width: 30px; } /* PR D: the concept's 28px prompt action would shrink the toolkit icon button */
|
|
@media (pointer: coarse) {
|
|
.ca-tools .recorded-history .history-toolbar button { min-height: 44px; } /* PR F: concept coarse buttons are 40px */
|
|
}
|
|
@media (max-width: 700px) {
|
|
.ca-tools dialog.image-preview { overflow: auto; } /* PR C */
|
|
.ca-tools dialog.recorded-run-dialog { padding: 16px; } /* PR F */
|
|
}
|