mirror of
https://github.com/kiddin9/op-packages.git
synced 2026-09-10 18:34:18 +08:00
99 lines
5.3 KiB
CSS
99 lines
5.3 KiB
CSS
@layer theme {
|
|
/* ==================================================================
|
|
* The page-search palette. Markup is built by fs-search.js and parented to <body>:
|
|
* the vertical .fs-sidebar is `overflow: auto`, which would clip a child of the trigger,
|
|
* and the overlay has to cover the whole viewport anyway.
|
|
* ================================================================== */
|
|
|
|
/* The scrim. --fs-scrim is the theme's one colour literal (plain black at .7) on purpose:
|
|
* it is the absence of light behind a dialog, not a tint of any palette token. */
|
|
.fs-search-ov {
|
|
position: fixed; inset: 0; z-index: var(--fs-z-popover);
|
|
/* `display` here is what the `hidden` attribute has to beat — base/10-reset.css does that for
|
|
* every element now, so this file no longer restates it for the overlay alone. */
|
|
display: flex; justify-content: center;
|
|
/* not centred vertically: the box grows DOWNWARD as results come in, and a centred one
|
|
* would slide the input out from under the user's eyes on every keystroke */
|
|
align-items: flex-start;
|
|
padding: max(8vh, var(--fs-space-6)) var(--fs-space-4) var(--fs-space-4);
|
|
background: var(--fs-scrim);
|
|
animation: fs-fade var(--fs-dur-fade);
|
|
}
|
|
|
|
/* The dialog itself. It is a SCROLL CONTAINER, and that is not decoration: without a cap the
|
|
* box grows past a short viewport (a phone in landscape is ~380px tall) and the rows at the
|
|
* bottom become unreachable — a `position: fixed` popup cannot be scrolled by the page. */
|
|
.fs-search-box {
|
|
display: flex; flex-direction: column; min-height: 0;
|
|
width: 100%; max-width: 560px; max-height: min(70dvh, 560px);
|
|
background: var(--fs-panel);
|
|
border: var(--fs-hairline); border-radius: var(--fs-radius-lg);
|
|
box-shadow: var(--fs-shadow-pop);
|
|
overflow: hidden;
|
|
}
|
|
|
|
.fs-search-row {
|
|
display: flex; align-items: center; gap: var(--fs-space-2-5); flex: 0 0 auto;
|
|
padding: var(--fs-space-3) var(--fs-space-3-5);
|
|
border-bottom: var(--fs-hairline);
|
|
}
|
|
.fs-search-ico { display: inline-flex; color: var(--fs-faint); }
|
|
.fs-search-ico .fs-ico { width: 18px; height: 18px; }
|
|
/* The input carries no frame of its own — the ROW is the field and the box around it is the
|
|
* dialog. Two classes (0,2,0) on purpose: the generic field box in 60-inputs.css is
|
|
* `input[type="text"], …` (0,1,1) and outranks a single class in the same layer whatever the
|
|
* source order — measured, it painted this input with the page-field border, the panel2 fill,
|
|
* 8px/11px of padding and a focus ring inside the dialog's own frame.
|
|
*
|
|
* 16px rather than the theme's body size, deliberately: a font-size below 16px makes iOS Safari
|
|
* zoom the page when the field takes focus, and this one takes focus as the palette opens. */
|
|
.fs-search-row .fs-search-input {
|
|
flex: 1 1 auto; min-width: 0;
|
|
margin: 0; padding: 0; border: 0; min-height: 0; background: transparent;
|
|
color: var(--fs-text);
|
|
font-family: inherit; font-size: var(--fs-type-lg); font-weight: var(--fs-weight); line-height: 1.4;
|
|
}
|
|
.fs-search-row .fs-search-input:focus { outline: none; box-shadow: none; }
|
|
/* one placeholder ink for the whole theme (03-palettes.css) — this row is not measured by
|
|
* `placeholder-ink`, the gallery having no search dialog, and must not drift from the fields
|
|
* that are */
|
|
.fs-search-row .fs-search-input::placeholder { color: var(--fs-placeholder); font-weight: var(--fs-weight); }
|
|
|
|
.fs-search-list { flex: 1 1 auto; min-height: 0; overflow-y: auto; padding: var(--fs-space-1-5); }
|
|
|
|
.fs-search-opt {
|
|
display: flex; align-items: baseline; gap: var(--fs-space-2-5);
|
|
padding: var(--fs-space-2) var(--fs-space-2-5); border-radius: var(--fs-radius);
|
|
color: var(--fs-text); text-decoration: none; cursor: pointer;
|
|
}
|
|
/* One highlight for both pointer and keyboard: `.active` is set by fs-search.js for the
|
|
* aria-activedescendant row AND on pointermove, so the mouse and the arrow keys can never
|
|
* disagree about which row Enter would open. */
|
|
.fs-search-opt.active { background: var(--fs-accent-soft); color: var(--fs-accent); }
|
|
.fs-search-opt-title { flex: 0 1 auto; font-weight: var(--fs-weight-bold); font-size: var(--fs-type); }
|
|
/* the breadcrumb: which section owns the page — the whole point of searching for it */
|
|
.fs-search-opt-path {
|
|
flex: 1 1 auto; min-width: 0;
|
|
color: var(--fs-faint); font-size: var(--fs-type); text-align: end;
|
|
overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
|
|
}
|
|
.fs-search-opt.active .fs-search-opt-path { color: inherit; }
|
|
|
|
/* "Recently visited" — the caption over the rows */
|
|
.fs-search-note {
|
|
flex: 0 0 auto;
|
|
padding: var(--fs-space-2-5) var(--fs-space-3-5) var(--fs-space-0-5);
|
|
color: var(--fs-eyebrow-color);
|
|
font-size: var(--fs-type-xs); font-weight: var(--fs-eyebrow-weight); letter-spacing: var(--fs-eyebrow-tracking); text-transform: uppercase;
|
|
}
|
|
|
|
/* …and the box's EMPTY STATE when there are no rows at all ("No pages found"), which reads as
|
|
* a sentence, not as an eyebrow label. :has() rather than a sibling combinator: the note sits
|
|
* ABOVE the list it describes, so `+` cannot reach back to it. */
|
|
.fs-search-box:has(.fs-search-list:empty) .fs-search-note {
|
|
padding: var(--fs-space-6) var(--fs-space-3-5) var(--fs-space-7);
|
|
text-align: center; text-transform: none; letter-spacing: 0;
|
|
font-size: var(--fs-type); font-weight: var(--fs-weight);
|
|
}
|
|
}
|