/*
    Global bas för portalen.

    Tokens (färger, linjer, skuggor, fokusmarkering och täthet) skrivs ut som
    CSS-variabler av ThemeProvider enligt ADR 0003 och 0005 — de hör inte hemma här,
    och inga färgvärden får skrivas i komponenternas scoped CSS.

    Reglerna här får bara referera variabler, aldrig egna färgvärden. Att filen är global
    ändrar inte regeln.
*/

/*
    ── Typsnitten ──────────────────────────────────────────────

    Montserrat för rubriker, Inter för gränssnittstext, som i Prototypen.

    Det här saknades helt. `--lk-font-display` och `--lk-font-ui` namngav båda familjerna,
    med `"Segoe UI"` som reserv, men ingenting laddade dem — `document.fonts.size` var 0.
    Följden var att hela portalen renderades i reservtypsnittet på varje maskin som inte
    råkade ha familjerna installerade. Mätt med canvas: `Inter` och `Montserrat` gav exakt
    samma textbredd som ett påhittat familjenamn, medan Prototypen gav en annan. Det syns
    inte som ett fel någonstans — sidan renderar, bara i fel typsnitt.

    Filerna ligger lokalt i stället för hos Google Fonts, som Prototypen använder
    (`portal/src/LykerKey.Portal/Components/App.razor:18`). Beslut av @martin 2026-09-02:
    inga anrop från användarens webbläsare till en tredjepart bara för att hämta ett
    typsnitt. De är konverterade till woff2 ur de TTF-filer som redan låg i repot, i
    `LykerKey.Keybox.SharedUI/wwwroot/fonts/`, så ingenting är hämtat utifrån. Licenserna
    följer med som OFL-*.txt, vilket OFL kräver.

    **Variabla filer, inte statiska vikter.** Två filer på 542 KB i stället för sju på 759 KB,
    och — det som avgjorde — Inters `opsz`-axel följer med. Google Fonts serverar den variabla
    Inter, så textens bredd ändras med grovleken. Med den statiska `Inter_18pt` mätte samma
    sträng 187,3 px mot Prototypens 190,5. Med den variabla: 190,5 mot 190,5. Montserrat
    stämde redan, och blir en fil i stället för tre.

    `font-display: swap` så att text syns direkt i reservtypsnittet och byts när filen
    landat — hellre det än en tom sida medan filerna hämtas.
*/

@font-face {
    font-family: "Inter";
    font-style: normal;
    font-weight: 100 900;
    font-display: swap;
    src: url("fonts/inter-var.woff2") format("woff2-variations");
}

@font-face {
    font-family: "Montserrat";
    font-style: normal;
    font-weight: 100 900;
    font-display: swap;
    src: url("fonts/montserrat-var.woff2") format("woff2-variations");
}

*,
*::before,
*::after {
    box-sizing: border-box;
}

html,
body {
    margin: 0;
    padding: 0;
}

body {
    /* Canvas målas av ThemeProvider. Här sätts den bara så att ytan under skalet
       får rätt färg när sidan scrollas förbi innehållets slut. */
    background: var(--lk-canvas, #F7F8FB);
    -webkit-font-smoothing: antialiased;
}

a {
    color: var(--lk-magenta-ink);
}

/*
    tabindex="-1" undantas medvetet.

    FocusOnNavigate i Routes.razor flyttar fokus till sidans h1 efter varje navigering, så
    att den som läser med skärmläsare eller tangentbord landar i det nya innehållet i stället
    för att stå kvar där den gamla sidan slutade. Blazor gör rubriken fokuserbar genom att
    sätta tabindex="-1" på den — attributet står alltså inte i vår markup och går inte att ta
    bort där.

    Följden var att [tabindex] fångade rubriken och målade fokusringen runt varje h1 vid
    navigering. Ett element med tabindex="-1" går inte att nå med tabb; det fokuseras bara
    programmatiskt, och då finns inget tangentbordsfokus att visa. WCAG 2.4.7 gäller det som
    är tangentbordsstyrt, så undantaget tar inte bort någon markering som krävs.

    Samma symptom löstes i LykerKey.Keybox.MauiApp genom att ta bort FocusOnNavigate helt.
    Det är rätt där — en pekskärm utan tangentbord förlorar ingenting — men fel här: portalen
    styrs med tangentbord, och rubrikfokus är det enda som säger att sidan har bytts.

    tabindex="0" behåller sin ring. Villkorstexten i LoanApprovalPage är ett sådant element
    och ska ha den.
*/
a:focus-visible,
button:focus-visible,
input:focus-visible,
[tabindex]:not([tabindex="-1"]):focus-visible {
    outline: none;
    box-shadow: 0 0 0 var(--lk-focus-ring-width) var(--lk-focus);
    border-radius: var(--lk-radius-sm);
}

/*
    The rule above keeps the portal's ring off a heading focused by FocusOnNavigate — but it
    never touched the browser's own. Chrome still drew its blue rectangle around every h1 after
    every navigation, and around the sign-in screens' headings (#465, seen again on staging
    2026-09-22). The heading is focused for a screen reader's benefit, not for the eye: WCAG
    2.4.7 covers keyboard-operable elements, and a tabindex="-1" heading is not one. The
    Prototype switches the browser ring off for exactly this case, and so does this.
*/
h1:focus,
h1:focus-visible,
[tabindex="-1"]:focus,
[tabindex="-1"]:focus-visible,
dialog:focus,
dialog:focus-visible {
    outline: none;
    box-shadow: none;
}

/* Scrollbar i portalens manér, som .lk-scroll i designen. */
* {
    scrollbar-width: thin;
    scrollbar-color: var(--lk-line-strong) transparent;
}

*::-webkit-scrollbar {
    width: 8px;
    height: 8px;
}

*::-webkit-scrollbar-thumb {
    background: var(--lk-line-strong);
    border-radius: 8px;
}

*::-webkit-scrollbar-track {
    background: transparent;
}

/*
    The reconnect dialog is a component now — Components/ReconnectDialog.razor, with its own
    scoped CSS and the portal's texts (#197). Nothing global is needed for it, and a global
    display rule on the dialog's id would fight the <dialog> element's own open state.
*/

/*
    A list table with fixed column sizes (2026-09-23). Under the default auto layout the browser
    weighs every column by its content, and the cabinet list's Version column took 523px of the
    table while ID took 179 (structure agent, staging). With table-layout: fixed the <col>
    elements decide: the sized columns are exactly their size, the rest share what is left.

    The sizes are shared here, one class per kind of column, so the cabinet and kiosk tables —
    and any list that adopts them — cannot drift apart. The widths include the cell's padding.
*/
.lk-list-table-fixed {
    table-layout: fixed;
    /* Below this the sized columns would squeeze the name to nothing, so the table keeps its
       width and scrolls inside its card instead (.lk-table-scroll) — structure agent, ~800px. */
    min-width: 52rem;
}

/* Nothing in a fixed-layout table draws outside its cell: what does not fit after wrapping is
   clipped at the cell's edge rather than painted over the neighbour. */
.lk-list-table-fixed th,
.lk-list-table-fixed td {
    overflow: hidden;
}

/*
    The upper part of a list page stays while the rows scroll (#1284, Niklas 2026-10-16: "hela
    övre delen lär ju stå kvar"): the title (SectionHeader at level 1), the tab row, the toolbar
    and the loan screen's selection bar each carry .lk-sticky-head, and StickyHeadsComponent gives
    each its offset (top, inline) so they stack instead of covering one another, and the headings
    above theirs.

    Only on a page with a list, which :has() reads off the page itself: a form or a detail page
    keeps its full height, and nothing has to opt in. A list is a table or a ListLayout — the
    layout too, since a card view and an empty list have no table and lost their filters as the
    page scrolled (#1386). Here and not in the components' own
    stylesheets, because whether a title sticks is the page's business and not the title's, and
    the rule has to see the list to decide.

    A stuck head paints the canvas over the rows, and over the gap under it too: the gap is a
    margin, which paints nothing, so a shadow the size of that margin (--lk-sticky-gap, measured
    with the offset) carries the canvas the rest of the way. The tab row keeps its own rule under
    the tabs that way, where turning the margin into padding would have moved it.

    The title gets a little air above it when it is stuck, since the page's own top padding has
    scrolled away by then: padding of its own, and, when it is the first thing on the page, a
    negative margin of the same size so nothing moves while it is not stuck. On a page that opens
    with something else — a back link, the terms notice — it adds that much to the gap instead.

    The first title on the page takes all of the page's top padding, not part of it (#1386,
    Martin 2026-10-21: "Still collapsing on scroll. Look above the page header"). With 16px of
    a 32px padding, the other 16px scrolled away before the title stuck, and the title and
    everything under it slid up by that much on the first turn of the wheel. The layouts name
    their padding --lk-main-padding-top for this; it changes with the window's width.

    A stuck head paints the canvas over the page's side padding too (#1386, Martin 2026-10-21:
    "Scrolling goes behind the top now, kinda visible"): its own box ends where the column does,
    and the cards and their shadows showed in the strips beside it. Two more copies of the box,
    one shifted each way by the side padding (--lk-main-padding-inline), and two more under the
    gap, cover them. Copies and not a spread: a spread reaches upwards too, over the head above.
*/
.lk-main:has(.lk-list-table, .lk-list-layout) .lk-sticky-head {
    position: sticky;
    top: 0;
    z-index: 2;
    background: var(--lk-canvas);
    box-shadow:
        0 var(--lk-sticky-gap, 0) 0 var(--lk-canvas),
        calc(-1 * var(--lk-main-padding-inline, 0px)) 0 0 var(--lk-canvas),
        var(--lk-main-padding-inline, 0px) 0 0 var(--lk-canvas),
        calc(-1 * var(--lk-main-padding-inline, 0px)) var(--lk-sticky-gap, 0) 0 var(--lk-canvas),
        var(--lk-main-padding-inline, 0px) var(--lk-sticky-gap, 0) 0 var(--lk-canvas);
}

.lk-main:has(.lk-list-table, .lk-list-layout) .lk-section-header.lk-sticky-head {
    padding-top: var(--lk-space-4);
}

.lk-main:has(.lk-list-table, .lk-list-layout) .lk-section-header.lk-sticky-head:first-child {
    padding-top: var(--lk-main-padding-top, var(--lk-space-4));
    margin-top: calc(-1 * var(--lk-main-padding-top, var(--lk-space-4)));
}

/* The wrapper a fixed-layout table sits in, so a narrow window scrolls the table sideways
   inside the card rather than the page. */
.lk-table-scroll {
    overflow-x: auto;
}

/*
    A scroll container is the scrollport of every sticky element inside it, and this one never
    scrolls up or down — so inside it the headings above cannot stick to the window (#1284). From
    90rem the wrapper lets the table through instead: the widest fixed-layout table, the cabinet
    list at 68rem for all organisations, fits the content column there (90rem less the rail's
    15.625rem and the column's padding), so nothing is lost by not scrolling it. A narrower window
    keeps the sideways scroll inside the card, and its headings are pinned by StickyHeadsComponent
    instead (#1393, below).
*/
@media (min-width: 90rem) {
    .lk-table-scroll {
        overflow-x: visible;
    }
}

/*
    Not sticky inside the wrapper (#1387): there a heading counts its top — the height of the title,
    tabs and toolbar — from the top of the table's own box, and slides that far down into the rows:
    on a short table it covers the only row, and the box grows a scrollbar of its own. So below 90rem
    the headings leave their row only by the script: StickyHeadsComponent moves the cells down as
    the page scrolls (#1393, option 2, Niklas 2026-10-27), which keeps the columns and the sideways
    scroll and still holds the headings under the toolbar. Relative rather than static: the band is
    the cell's ::before, which needs the cell to place it.
*/
@media not all and (min-width: 90rem) {
    .lk-table-scroll .lk-list-table thead th {
        position: relative;
        top: 0;
    }
}

/*
    The other lists have no such wrapper, and on a phone their tables are wider than the window:
    the key table is 595px in a 343px card at 375px (#1400, lyker/arenden#25). The card did not
    clip them, so the whole page scrolled sideways, and the stuck title and toolbar, as wide as the
    window, left the rows showing beside and behind them. Below 60rem, where the layouts drop the
    rail, ListLayout's card scrolls its content sideways instead, and its headings are pinned by the
    same script as above (#1393), not by CSS. From 60rem these lists fit and keep their sticky
    headings.

    Positioned too: a scroll container clips only what it contains the position of, and the linked
    rows' full-width link is placed against the nearest positioned ancestor, which was outside the
    card. On the event log it kept the page 594px wide with the table already scrolling.
*/
/*
    A heading the script has pinned rides over the rows, so it has to be above what in a row is
    raised to be pressed (.lk-row-above and the controls of a linked row, z-index 1, later in the
    page). It never reaches the stuck parts above it: the script stops it at their bottom edge.
*/
.lk-list-table thead.lk-list-head-pinned th {
    z-index: 2;
}

@media not all and (min-width: 60rem) {
    .lk-list-layout > .lk-card {
        position: relative;
        overflow-x: auto;
    }

    .lk-list-layout > .lk-card .lk-list-table thead th {
        position: relative;
        top: 0;
    }
}

.lk-col-reference {
    width: 6.875rem;
}

.lk-col-status {
    width: 7.5rem;
}

.lk-col-kind {
    width: 10rem;
}

.lk-col-slots {
    width: 11.25rem;
}

.lk-col-version {
    width: 13.75rem;
}

/*
    Every heading in a list table, plain <th> or SortableColumnHeader's, in one style: the muted
    small caps the key list set first and the sort button repeats. Here so the two cannot
    differ — on the cabinet's event log they did, twice, in opposite directions (structure
    agent, staging 2026-09-23). Since #649 it is the only copy: the eight modules' own
    *-table-heading classes are gone, so a new list's headings are right without a class.
*/
.lk-list-table thead th {
    font-family: var(--lk-font-ui);
    font-size: var(--lk-font-size-label);
    font-weight: 600;
    color: var(--lk-text-mut);
}

/*
    Listornas rubrikrad, en gång för alla åtta listskärmarna.

    Martin 2026-09-08: "Other lists will use the same component for a header. The lists are
    identical in look, differ in columns." Rubriken hör alltså inte till en skärm utan till
    listan som form, och låg tidigare som en kopierad `*-table-heading`-regel i fem moduler.

    Globalt och inte scoped, därför att åtta komponenter delar utseendet och det snävaste
    scope som fungerar för något åtta komponenter delar är det globala. `SortableColumnHeader`
    kan inte bära det själv: den renderar en `th`, och bandet, radien och versalerna hör till
    raden.

    `text-transform` och `letter-spacing` ärvs, så de når in i `SortableColumnHeader`s knapp
    utan att någon regel behöver peka på en annan komponents markup.

    Prototypens `.lrow-head` (app.css:154) är förlagan: --surface-alt bakom, kortets radie på
    de övre hörnen, 0.3px och versaler.
*/
.lk-list-table thead tr {
    background: var(--lk-surface-alt);
    text-transform: uppercase;
    letter-spacing: 0.3px;
}

/*
    The headings stay at the top of the window while the rows scroll under them (#1284, Niklas
    2026-10-16: "där vill man att övre delen inkl. rubrikerna skall vara låsta"). The page scrolls
    as one document (#1270), so top: 0 is the window's edge.

    Three things a sticky cell needs that the row above gave the heading for free: its own
    background, since a cell that has left its row paints only itself and the rows would show
    through the band; its own rule underneath, drawn as a shadow because a collapsed table border
    stays where the row was rather than travelling with the cell; and a level, so the rows' own
    positioned bits (an icon in a field, a chevron) do not come up through it.

    top is where the page's own sticky parts end — title, tabs, toolbar — measured and written on
    the main element by StickyHeadsComponent; 0 until it has, and on a page with none of them.

    It does not work inside a box that scrolls sideways (.lk-table-scroll below 90rem, ListLayout's
    card below 60rem); there StickyHeadsComponent pins the headings instead (#1393).
*/
.lk-list-table thead th {
    position: sticky;
    top: var(--lk-sticky-heads, 0);
    z-index: 1;
    /*
        The canvas, square, and not the band's colour (#1293, Niklas 2026-10-16: "de rundade hörnen
        blir fel vid rubrikerna"). The band with its rounded top corners is the ::before below. A
        cell's own background cannot stop at a rounded corner and go on behind it in another colour,
        and both are needed: at the top of the card the corner notch lies outside the card's own
        rounded corner, where the canvas already is, so the canvas there changes nothing; stuck
        mid-list the notch would otherwise be a hole the rows scroll through, hairlines and all.
    */
    background: var(--lk-canvas);
    box-shadow: 0 var(--lk-border-hairline) 0 var(--lk-line);
}

/* The band itself, under the text: z-index -1 inside the cell's own stacking context puts it above
   the cell's background and below its content. */
.lk-list-table thead th::before {
    content: "";
    position: absolute;
    inset: 0;
    z-index: -1;
    background: var(--lk-surface-alt);
}

.lk-list-table thead th:first-child::before {
    border-top-left-radius: var(--lk-radius-card);
}

.lk-list-table thead th:last-child::before {
    border-top-right-radius: var(--lk-radius-card);
}

/*
    Cellerna. Blocket låg ordagrant likadant i alla åtta modulerna — samma padding, samma
    hårstreck, samma vertikala centrering — vilket är samma slutsats som rubrikraden ovan:
    listorna är en form, inte åtta.
*/
.lk-list-table th,
.lk-list-table td {
    text-align: left;
    padding: var(--lk-space-3) var(--lk-space-2);
    border-bottom: var(--lk-border-hairline) solid var(--lk-line);
    vertical-align: middle;
}

/*
    Prototypen drar in raden 20px från kortets kant (app.css `.lrow`, `padding: 13px 20px`).
    Lagt på första och sista cellen i stället för på alla, eftersom `padding: 0 20px` på varje
    cell hade gett 40px mellan kolumnerna i stället för 20px i ytterkant.
*/
.lk-list-table th:first-child,
.lk-list-table td:first-child {
    padding-left: var(--lk-space-5);
}

.lk-list-table th:last-child,
.lk-list-table td:last-child {
    padding-right: var(--lk-space-5);
}

/*
    The rest of what every list module wrote for itself, byte for byte, until #750: the table's
    base, the last row without a rule under it, the muted cell, the right-hand action column and
    the tile in front of a name. A new list gets them by carrying the classes, rather than by
    someone knowing which block to copy — which is how five lists came to draw their dates a size
    larger than the key list's (#750) and a new list drew browser-default headings (#649).

    Each module keeps only what is its own: column widths, and any cell with a reason to differ.
    The colleague and identity lists keep their own muted cells on purpose: the Prototype draws
    those columns as .mut (12.5px, text-mut), not .dim.
*/
.lk-list-table {
    width: 100%;
    border-collapse: collapse;
    font-family: var(--lk-font-ui);
    font-size: var(--lk-font-size-ui);
    color: var(--lk-text);
}

.lk-list-table tbody tr:last-child th,
.lk-list-table tbody tr:last-child td {
    border-bottom: none;
}

/* The Prototype's `.lrow .dim` (app.css:163): 13px as well as the secondary ink. */
.lk-list-table .lk-list-muted {
    font-size: var(--lk-font-size-label);
    color: var(--lk-text-sec);
}

/* The action column, heading and cells alike: one right-hand edge rather than a ragged one.
   Under .lk-list-table so it outranks the cells' own text-align: left above. */
.lk-list-table .lk-list-actions {
    text-align: right;
    white-space: nowrap;
}

/* The tile in front of a row's name: 9.5px on this 34px mark, the Prototype's .itile (9px). */
.lk-list-mark {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 34px;
    height: 34px;
    border-radius: var(--lk-radius-tile);
    background: var(--lk-navy-soft);
    color: var(--lk-ink);
    flex: none;
}

/*
    Present for a screen reader, gone for everyone else — a column heading the design leaves
    empty. clip-path rather than display: none, which would take the text out of the
    accessibility tree as well. Five list modules each had a copy (#750).
*/
.lk-visually-hidden {
    position: absolute;
    width: 1px;
    height: 1px;
    margin: -1px;
    padding: 0;
    overflow: hidden;
    clip-path: inset(50%);
    white-space: nowrap;
}

/*
    A row that opens something, once for every list that has somewhere to go.

    The Prototype makes the whole row the target and says so with a class of its own:
    `.lrow.click { cursor: pointer }` and `.lrow.click:hover { background: var(--surface-alt) }`
    (portal `app.css:159-160`). Only the lists with a destination carry it. The events and the
    identities lists are plain `.lrow` and do not react to the pointer at all, which is why the
    hover moved in here from the eight modules rather than staying a default: a row that
    lights up under the pointer and then does nothing when clicked is a promise the screen
    cannot keep.

    Built as a stretched link and not as a handler on the `tr`. The list components already
    argue the point in their own markup, twice: *"Real links rather than buttons: a key list is
    somewhere people open rows in a new tab"* and *"A real anchor, not a row handler: ... it has
    to be reachable by keyboard."* A click handler on the row would take both away. Here the
    destination stays an ordinary `<a href>` in the name cell — focus, middle-click, ctrl-click
    and "copy link address" all keep working — and the overlay only widens where it can be hit.

    The cost, written down rather than found later: the overlay covers the row's text, so text
    in a linked row cannot be selected with the mouse. That is inherent to the pattern, and it
    is the reason the class goes only on rows that really are one destination.

    Global rather than scoped, for the same reason as the two blocks above: four list
    components share it today, and the rest join as they gain somewhere to go.

    `li.lk-row-linked` is the same mechanism for the lists drawn as `<ul>` rather than as a table
    — the shop administration's products and categories, whose rows open a dialog. Martin
    2026-09-15 (#679): every line in a list clickable as in the key list. Before that only the name cell
    opened the dialog there, while the Prototype's whole row did (ShopAdmin.razor:52 and :88).
*/
.lk-list-table tbody tr.lk-row-linked,
li.lk-row-linked {
    position: relative;
}

.lk-list-table tbody tr.lk-row-linked:hover,
li.lk-row-linked:hover {
    background: var(--lk-surface-alt);
}

.lk-list-table tbody tr.lk-row-linked .lk-row-link::after,
li.lk-row-linked .lk-row-link::after {
    content: "";
    position: absolute;
    inset: 0;
}

/*
    WebKit (Safari on macOS, and every browser on iOS) does not make a `<tr>` the containing
    block for absolutely positioned descendants, `position: relative` or not. The ::after above
    then measures from the next positioned ancestor up the tree, or from the viewport, and the
    last linked row lays a transparent link over the whole page: the sidebar menu, the toolbar and
    everything under the table open that row instead (#1230, /colleagues on staging 2026-10-14).
    Chromium honours the `tr` and never showed it.

    clip-path clips both painting and hit testing to the row's own box, so wherever the overlay
    measured from, only the part over its own row can be hit. Tried in WebKit and rejected:
    `transform` on the row anchors the overlay at the row's top but leaves it far too tall, so it
    still covers what is under the table; `contain: layout`, `contain: paint` and
    `will-change: transform` change nothing.

    The cost: nothing drawn from inside a linked row can reach outside it. Focus rings fit (the
    ring is inside the cells' padding), and no linked row holds a menu or a popover today; one
    added later has to render outside the row, or it is cut off at the row's edge.
    `li.lk-row-linked` needs none of this: WebKit honours `position: relative` on a list item.
*/
.lk-list-table tbody tr.lk-row-linked {
    clip-path: inset(0);
}

/*
    Everything else in the row stays hittable. An absolutely positioned overlay paints over
    in-flow content that is not itself positioned, so without this the pen, the booking link and
    the selection checkboxes would sit under the row link and quietly stop responding — and a
    covered control looks exactly like a working one.

    Selected by element rather than by class, so a control added to one of these rows later is
    above the overlay without whoever adds it having to know this rule exists. `.lk-row-above`
    is for the exceptions that are not controls, such as the key list's unavailable *Boka*,
    which is a span carrying the explanation in its title.

    Both `a` and `button` exclude `.lk-row-link` itself, because the row link is whichever of the
    two the row uses: a link where the row is one destination, a button where it expands in place
    (the loans list, #604). Without the exclusion the row link would be positioned, and `inset: 0`
    on its ::after would then measure from the control instead of from the row — the overlay
    shrinks to the size of the chevron and nothing goes red.
*/
.lk-list-table tbody tr.lk-row-linked a:not(.lk-row-link),
.lk-list-table tbody tr.lk-row-linked button:not(.lk-row-link),
.lk-list-table tbody tr.lk-row-linked input,
.lk-list-table tbody tr.lk-row-linked label,
.lk-list-table tbody tr.lk-row-linked select,
.lk-list-table tbody tr.lk-row-linked .lk-row-above,
li.lk-row-linked a:not(.lk-row-link),
li.lk-row-linked button:not(.lk-row-link),
li.lk-row-linked input,
li.lk-row-linked label,
li.lk-row-linked select,
li.lk-row-linked .lk-row-above {
    position: relative;
    z-index: 1;
}

/*
    The toolbar above a list: a search field that takes the room, and the filters beside it.

    Martin 2026-09-15 (#679): filters in every list should look and work the same as in the key
    list. The key list is the source and is not moved onto these rules — it keeps its own copy in
    KeyMainPage.razor.css, and the values here are that file's, property for property. Before this,
    the other screens each carried their own copy, and they had drifted: search fields between 22rem
    and 380px wide, filters from 11rem to 200px, some top-aligned with visible labels.

    Global rather than scoped, for the same reason as the list table above: the classes are handed
    to TextField and Select, so a page-scoped rule would need `::deep` on every screen, and a
    missing `::deep` fails silently (#568).

    center, not flex-end: every control's label is hidden, so they are all one height and there is
    no baseline left to line up against. Wrapping is on so that a toolbar with dates as well as
    selects (the event lists) takes a second line rather than squeezing the search field.
*/
.lk-list-toolbar {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--lk-space-3);
    margin-bottom: var(--lk-space-4);
}

/* The key list's search field: capped at the Prototype's 380px, the rest of the row left empty. */
.lk-list-toolbar .lk-list-toolbar-search {
    flex: 1;
    min-width: 12rem;
    max-width: 23.75rem;
}

/* The key list's select, 170px, fixed so the row does not move as the choice changes. */
.lk-list-toolbar .lk-list-toolbar-filter {
    width: 10.625rem;
    flex: none;
}

/* 180px, the Prototype's width for the event type and the role, whose longest words do not fit
   in 170px. The key list has no such select. */
.lk-list-toolbar .lk-list-toolbar-filter-wide {
    width: 11.25rem;
    flex: none;
}

/* 220px, for a select whose longest option does not fit in 180px: the report page's period
   ("Viimeiset 30 päivää", "Sérsniðið tímabil") and grouping ("Ingen gruppering"), and the event
   log's type ("Alla händelsetyper"), all clipped at 180px or less (project agent and Niklas
   2026-10-16). The frame cannot size to its options — the <select> is laid over it absolutely
   (Select.razor.css) — so the width is given, for the longest word in the six languages. */
.lk-list-toolbar .lk-list-toolbar-filter-wider {
    width: 13.75rem;
    flex: none;
}

/* The key list's narrow select, 150px, for a short set of choices such as a status. */
.lk-list-toolbar .lk-list-toolbar-filter-narrow {
    width: 9.375rem;
    flex: none;
}

/* A date field does not shrink: a browser sizes its picker from the control rather than the box,
   and narrower than this the placeholder clips on Firefox. */
.lk-list-toolbar .lk-list-toolbar-date {
    flex: none;
    width: 9.5rem;
}

/* One column well before a phone width: the search field is unusable at a third of a narrow
   screen, and a filter beside it makes both too small to read. */
@media (max-width: 48rem) {
    .lk-list-toolbar {
        flex-direction: column;
        align-items: stretch;
    }

    .lk-list-toolbar .lk-list-toolbar-filter,
    .lk-list-toolbar .lk-list-toolbar-filter-wide,
    .lk-list-toolbar .lk-list-toolbar-filter-wider,
    .lk-list-toolbar .lk-list-toolbar-filter-narrow,
    .lk-list-toolbar .lk-list-toolbar-date {
        width: 100%;
    }
}
