| 7450 |
7450 |
|
.discover-sidebar { font-size: 0.85rem; }
|
| 7451 |
7451 |
|
.filter-section { margin-bottom: 1.25rem; }
|
| 7452 |
7452 |
|
.filter-title { font-family: var(--font-heading); font-weight: bold; font-size: 0.85rem; margin-bottom: 0.5rem; color: var(--content); }
|
| 7453 |
|
- |
.filter-browse-link { font-size: 0.75rem; opacity: 0.5; font-weight: normal; }
|
| 7454 |
7453 |
|
.filter-list { list-style: none; }
|
| 7455 |
7454 |
|
/* The row carries selection (`.is-selected` recipe) and hover; the filter itself
|
| 7456 |
7455 |
|
is a real <button> child so Enter/Space work without scripting. */
|
| 7458 |
7457 |
|
.filter-item:hover { opacity: 0.6; }
|
| 7459 |
7458 |
|
.filter-item.is-selected { font-weight: bold; }
|
| 7460 |
7459 |
|
.filter-item .count { opacity: 0.4; font-size: 0.8rem; }
|
| 7461 |
|
- |
/* Strip the bare-button chrome: filters switch the view rather than commit
|
| 7462 |
|
- |
anything, so they carry no fill, border, or depth (charter: docs/design-system.md). */
|
| 7463 |
|
- |
.filter-btn { flex: 1; display: flex; justify-content: space-between; align-items: center; gap: 0.5rem; padding: 0.25rem 0; background: none; border: none; box-shadow: none; font: inherit; color: inherit; text-align: left; cursor: pointer; }
|
| 7464 |
|
- |
.filter-btn:hover { box-shadow: none; }
|
| 7465 |
|
- |
.filter-btn:active { box-shadow: none; transform: none; }
|
| 7466 |
7460 |
|
.tag-follow-btn { background: none; border: 1px solid var(--border); cursor: pointer; font-family: var(--font-mono); font-size: 0.7rem; opacity: 0.55; padding: 0.1rem 0.45rem; color: var(--content); }
|
| 7467 |
7461 |
|
.tag-follow-btn:hover { opacity: 1; }
|
| 7468 |
7462 |
|
.tag-follow-btn.is-selected { opacity: 0.85; border-color: var(--focus-ring); background: color-mix(in oklch, var(--action) 8%, transparent); }
|
| 7471 |
7465 |
|
.price-inputs { display: flex; gap: 0.25rem; align-items: center; margin-bottom: 0.5rem; }
|
| 7472 |
7466 |
|
.price-inputs input { width: 60px; padding: 0.3rem; font-size: 0.8rem; background: var(--surface-sunken); border: none; }
|
| 7473 |
7467 |
|
.price-inputs span { opacity: 0.4; }
|
| 7474 |
|
- |
.price-distribution { margin-top: 0.5rem; }
|
| 7475 |
|
- |
.price-distribution-item { font-size: 0.8rem; opacity: 0.6; padding: 0.1rem 0; }
|
| 7476 |
7468 |
|
.discover-main { min-width: 0; }
|
|
7469 |
+ |
|
|
7470 |
+ |
/* ---- Discover sidebar: tag spine ----------------------------------------
|
|
7471 |
+ |
Tags are the sidebar's structure, not one facet among several, so the spine
|
|
7472 |
+ |
reads as the primary surface and .filter-refine below it is subordinate.
|
|
7473 |
+ |
Everything here composes existing primitives: .filter-item carries the row
|
|
7474 |
+ |
and its .is-selected recipe, .search-suggestions carries the dropdown shell,
|
|
7475 |
+ |
.breadcrumb carries the crumb idiom. */
|
|
7476 |
+ |
.tag-spine { padding-bottom: var(--space-4); border-bottom: 1px solid var(--border); }
|
|
7477 |
+ |
|
|
7478 |
+ |
/* Selected tags. Also the active-filter summary, so they use the canonical
|
|
7479 |
+ |
selected tint rather than a new colour. */
|
|
7480 |
+ |
.tag-chips { list-style: none; display: flex; flex-wrap: wrap; gap: var(--space-1); margin-bottom: var(--space-3); }
|
|
7481 |
+ |
.tag-chip { display: flex; align-items: center; gap: var(--space-1); padding: 0.15rem 0.4rem; font-size: 0.8rem; background: color-mix(in oklch, var(--action) 8%, transparent); border: 1px solid var(--focus-ring); }
|
|
7482 |
+ |
.tag-chip-label { overflow-wrap: anywhere; }
|
|
7483 |
+ |
.tag-chip-remove { text-decoration: none; color: var(--content-secondary); font-size: 1rem; line-height: 1; padding: 0 0.1rem; }
|
|
7484 |
+ |
.tag-chip-remove:hover { color: var(--content); }
|
|
7485 |
+ |
.tag-chip-clear { background: none; border: 1px dashed var(--border-strong); }
|
|
7486 |
+ |
.tag-chip-clear a { text-decoration: none; color: var(--content-secondary); font-size: 0.8rem; }
|
|
7487 |
+ |
.tag-chip-clear a:hover { color: var(--content); }
|
|
7488 |
+ |
|
|
7489 |
+ |
/* Typeahead. Shares the .search-suggestions shell; it toggles with the
|
|
7490 |
+ |
`hidden` attribute rather than an inline display, so the shared rule's
|
|
7491 |
+ |
display:none has to be overridden when open. */
|
|
7492 |
+ |
.tag-combobox { position: relative; margin-bottom: var(--space-3); }
|
|
7493 |
+ |
.tag-combobox-input { width: 100%; padding: 0.3rem; font-size: 0.8rem; background: var(--surface-sunken); border: none; }
|
|
7494 |
+ |
.tag-suggest-list { list-style: none; }
|
|
7495 |
+ |
.tag-suggest-list:not([hidden]) { display: block; }
|
|
7496 |
+ |
.tag-suggest-item { gap: var(--space-2); }
|
|
7497 |
+ |
.tag-suggest-label { overflow-wrap: anywhere; }
|
|
7498 |
+ |
|
|
7499 |
+ |
/* Drill-down. A rung either selects (assignable leaf) or navigates (category);
|
|
7500 |
+ |
rows with both put the chevron after the label. */
|
|
7501 |
+ |
.tag-crumbs { list-style: none; display: flex; flex-wrap: wrap; font-family: var(--font-mono); font-size: 0.75rem; color: var(--content-muted); margin-bottom: var(--space-2); }
|
|
7502 |
+ |
.tag-crumbs li + li::before { content: "/"; opacity: 0.4; margin: 0 0.3rem; }
|
|
7503 |
+ |
.tag-crumbs a { color: var(--content); text-decoration: none; }
|
|
7504 |
+ |
.tag-crumbs a:hover { text-decoration: underline; }
|
|
7505 |
+ |
.tag-drill-select { flex: 1; display: flex; align-items: center; gap: var(--space-2); cursor: pointer; padding: 0.15rem 0; }
|
|
7506 |
+ |
.tag-drill-select input { width: auto; margin: 0; }
|
|
7507 |
+ |
.tag-drill-select span:first-of-type { flex: 1; }
|
|
7508 |
+ |
.tag-drill-into { display: flex; align-items: center; gap: var(--space-2); flex: 1; text-decoration: none; color: inherit; padding: 0.15rem 0; }
|
|
7509 |
+ |
.tag-drill-into span:first-child { flex: 1; }
|
|
7510 |
+ |
.tag-drill-chevron { opacity: 0.4; }
|
|
7511 |
+ |
|
|
7512 |
+ |
/* ---- Discover sidebar: refine block -------------------------------------
|
|
7513 |
+ |
Subordinate to the spine: same controls, quieter. */
|
|
7514 |
+ |
.filter-refine { margin-top: var(--space-4); }
|
|
7515 |
+ |
.filter-fieldset { border: none; padding: 0; margin: 0; min-width: 0; }
|
|
7516 |
+ |
.filter-check { flex: 1; display: flex; align-items: center; gap: var(--space-2); cursor: pointer; padding: 0.15rem 0; }
|
|
7517 |
+ |
.filter-check input { width: auto; margin: 0; }
|
|
7518 |
+ |
.filter-check span:first-of-type { flex: 1; }
|
|
7519 |
+ |
|
|
7520 |
+ |
/* A zero-count facet stays visible but inert, so the shape of the catalog
|
|
7521 |
+ |
stays legible as filters narrow. No existing rule covers a disabled input
|
|
7522 |
+ |
inside a label, so this is the checkbox counterpart of the button rule. */
|
|
7523 |
+ |
.filter-item:has(input:disabled) { opacity: 0.5; }
|
|
7524 |
+ |
.filter-item:has(input:disabled) .filter-check { cursor: not-allowed; }
|
|
7525 |
+ |
|
|
7526 |
+ |
/* Price buckets are links carrying a range, not form state. */
|
|
7527 |
+ |
.price-buckets { margin-top: var(--space-2); }
|
|
7528 |
+ |
.price-bucket { flex: 1; display: flex; align-items: center; justify-content: space-between; gap: var(--space-2); text-decoration: none; color: inherit; padding: 0.15rem 0; }
|
|
7529 |
+ |
|
| 7477 |
7530 |
|
.mode-toggle { display: flex; gap: 0.5rem; margin-bottom: 0.75rem; }
|
| 7478 |
7531 |
|
.toggle-btn { background: var(--surface-sunken); border: none; padding: 0.4rem 0.8rem; font-size: 0.85rem; font-family: inherit; cursor: pointer; transition: background 0.1s ease, opacity 0.1s ease; }
|
| 7479 |
7532 |
|
.toggle-btn:hover { opacity: 0.7; }
|
| 7544 |
7597 |
|
margin-bottom: 1rem;
|
| 7545 |
7598 |
|
}
|
| 7546 |
7599 |
|
|
|
7600 |
+ |
.discover-filter-toggle.active { background: var(--surface-sunken); border-color: var(--border-strong); }
|
|
7601 |
+ |
|
| 7547 |
7602 |
|
.discover-filter-toggle .filter-count {
|
| 7548 |
7603 |
|
background: var(--action);
|
| 7549 |
7604 |
|
color: var(--primary-light);
|
| 7557 |
7612 |
|
.discover-filter-toggle { display: inline-block; }
|
| 7558 |
7613 |
|
.discover-layout { grid-template-columns: 1fr; }
|
| 7559 |
7614 |
|
.discover-sidebar { display: none; }
|
| 7560 |
|
- |
.discover-sidebar.show { display: block; margin-bottom: 1rem; }
|
|
7615 |
+ |
/* Open state lives on the layout, not the sidebar: the sidebar is replaced
|
|
7616 |
+ |
by an out-of-band swap on every filter change and would lose the class. */
|
|
7617 |
+ |
.discover-layout.filters-open .discover-sidebar { display: block; margin-bottom: 1rem; }
|
| 7561 |
7618 |
|
.table-header, .table-row { grid-template-columns: 40px 1fr 60px; }
|
| 7562 |
7619 |
|
.table-row-item { grid-template-columns: 1fr 30px; }
|
| 7563 |
7620 |
|
.table-row-item .table-row-link { grid-template-columns: 40px 1fr 60px; }
|
| 7706 |
7763 |
|
display: block;
|
| 7707 |
7764 |
|
}
|
| 7708 |
7765 |
|
|
| 7709 |
|
- |
.suggestion-item {
|
|
7766 |
+ |
.suggestion-item,
|
|
7767 |
+ |
.tag-suggest-item {
|
| 7710 |
7768 |
|
padding: 0.5rem 0.75rem;
|
| 7711 |
7769 |
|
cursor: pointer;
|
| 7712 |
7770 |
|
font-size: 0.9rem;
|
| 7850 |
7908 |
|
=========================================== */
|
| 7851 |
7909 |
|
|
| 7852 |
7910 |
|
.search-wrapper { position: relative; flex: 1; min-width: 0; }
|
| 7853 |
|
- |
.search-suggestions {
|
|
7911 |
+ |
.search-suggestions,
|
|
7912 |
+ |
.tag-suggest-list {
|
| 7854 |
7913 |
|
display: none; position: absolute; left: 0; right: 0; top: 100%; z-index: 50;
|
| 7855 |
7914 |
|
background: var(--surface-page); border: 1px solid var(--border); border-top: none;
|
| 7856 |
7915 |
|
box-shadow: 0 4px 12px rgba(0,0,0,0.1); max-height: 280px; overflow-y: auto;
|
| 7860 |
7919 |
|
padding: 0.5rem 0.75rem; text-decoration: none; color: var(--content);
|
| 7861 |
7920 |
|
font-size: 0.85rem; cursor: pointer;
|
| 7862 |
7921 |
|
}
|
| 7863 |
|
- |
.suggestion-item:hover, .suggestion-item.highlighted { background: var(--surface-sunken); }
|
|
7922 |
+ |
.suggestion-item:hover, .suggestion-item.highlighted,
|
|
7923 |
+ |
.tag-suggest-item:hover, .tag-suggest-item.highlighted { background: var(--surface-sunken); }
|
| 7864 |
7924 |
|
.suggestion-category { font-size: 0.75rem; opacity: 0.5; text-transform: uppercase; letter-spacing: 0.05em; }
|
| 7865 |
7925 |
|
|
| 7866 |
7926 |
|
/* ===========================================
|