/* kansli — budkavle's look (~/dev/budkavle/public/style.css), its sections
   taken as they are; kansli's own additions at the end. See DESIGN.md.
   The colours are kansli's own (ink blue, not budkavle's pine), so the two
   aren't mistaken for each other; the variable names stay budkavle's. */

/* Cozy (Viktor, 2026-10-22): Nunito's rounded ends for the interface,
   Literata — a warm serif made for screens — for what people write. */
@font-face {
    font-family: "Nunito";
    src: url("fonts/Nunito.ttf") format("truetype");
    font-weight: 200 1000;
    font-display: swap;
}
@font-face {
    font-family: "Literata";
    src: url("fonts/Literata.ttf") format("truetype");
    font-weight: 200 900;
    font-display: swap;
}

:root {
    --paper: #f7f1e8;
    --ink: #2f2620;
    --pine: #5d3f61;
    --pine-deep: #4a3150;
    --rule: #e7dccd;
    --muted: #7a6c60;
    --wax: #b0442c;
    --on-pine: #f6ece3;

    --ui: "Nunito", system-ui, sans-serif;
    --letter: "Literata", Charter, "Iowan Old Style", Georgia, serif;
    /* Everything the stylesheet paints, so a theme (theme-*.css) can
       repaint it: kansli's values. */
    --surface: #fffcf7;
    --on-label: #fffcf7;
    --zebra: #fbf7f1;
    --hover: #f1e7da;
    --picked: #eadfe6;
    --tint: #efe3dc;
    --thumb: #f5eee5;
    --rule-strong: #d9ccbc;
    --quote: #5e5248;
    --mark: #fbe9a8;
    --error-bg: #f8ecea;
    --error-ink: #7a2c19;
    --wax-deep: #93361f;
    --wax-ring: #ffd2cc;
    --ok-dot: #9fd0b6;
    /* Channels, for translucent shades: rgb(var(--shadow) / .15). */
    --shadow: 47 38 32;
    --on-pine-rgb: 246 236 227;
    --wax-rgb: 163 55 43;
    --pine-rgb: 93 63 97;
    --r: 6px;
    --r-lg: 8px;
    /* The rail is the accent's colour in kansli; a theme may part them. */
    --rail: var(--pine);
    --rail-deep: var(--pine-deep);
    --on-rail: var(--on-pine);
    --light: white;
    --rail-w: 11rem;
}

* { box-sizing: border-box; }

html { background: var(--paper); color: var(--ink); }

body {
    margin: 0;
    font: 400 .9375rem/1.45 var(--ui);
    -webkit-font-smoothing: antialiased;
}

a { color: var(--pine); }

:focus-visible { outline: 2px solid var(--pine); outline-offset: 2px; }

button, input, textarea { font: inherit; color: inherit; }

/* Display rules such as .stack's grid would otherwise override [hidden]. */
[hidden] { display: none !important; }

.sr { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); }

/* ── Shell: the rail is the stick, the current folder a notch cut into it */

.shell {
    display: grid;
    grid-template-columns: var(--rail-w) minmax(0, 1fr);
    min-height: 100vh;
}

.rail {
    background: var(--rail);
    color: var(--on-rail);
    padding: 1rem 0 1rem .75rem;
    display: flex;
    flex-direction: column;
    gap: .9rem;
}

.wordmark {
    color: var(--on-rail);
    text-decoration: none;
    font-weight: 800;
    font-size: 1.25rem;
    letter-spacing: .01em;
    padding-right: .75rem;
}

.write {
    margin-right: .75rem;
    padding: .35rem .75rem;
    border: 1px solid rgb(var(--on-pine-rgb) / .55);
    border-radius: var(--r);
    color: var(--on-rail);
    text-decoration: none;
    font-weight: 500;
    text-align: center;
}
.write:hover { background: var(--rail-deep); }

.folders { list-style: none; margin: 0; padding: 0; }

.folders a {
    display: flex;
    justify-content: space-between;
    align-items: baseline;
    padding: .3rem .75rem .3rem .6rem;
    color: var(--on-rail);
    text-decoration: none;
    border-radius: 8px 0 0 4px;
}
.folders a:hover { background: var(--rail-deep); }

.folders a.current {
    background: var(--paper);
    color: var(--ink);
    font-weight: 500;
}

.count {
    font-size: .8125rem;
    font-weight: 600;
    font-variant-numeric: tabular-nums;
}
.folders a.current .count { color: var(--wax); }

/* Search sits under Write, as a link like a folder's: the box lives on the
   search page, so the rail spends one line on it, not a field. */
.search-link {
    display: flex;
    align-items: center;
    padding: .3rem .75rem .3rem .6rem;
    margin-bottom: .35rem;
    color: var(--on-rail);
    text-decoration: none;
    border-radius: 8px 0 0 4px;
}
.search-link:hover { background: var(--rail-deep); }
.search-link .icon { opacity: .85; }
.search-link.current { background: var(--paper); color: var(--ink); font-weight: 500; }
.search-link.current .icon { opacity: 1; color: var(--pine); }

/* The box on the search page. */
.search-box { display: flex; gap: .5rem; margin: .25rem 0 1rem; max-width: 44rem; }
.search-box input {
    flex: 1;
    min-width: 0;
    padding: .4rem .6rem;
    border: 1px solid var(--rule);
    border-radius: var(--r);
    background: var(--surface);
}
.search-box input:focus { outline: 2px solid var(--pine); outline-offset: -1px; border-color: var(--pine); }

/* Wide screens: the rail is the window's height and stays put, so the
   account menu is always at its foot. */
@media (min-width: 44.01rem) and (min-height: 32rem) {
    .rail { position: sticky; top: 0; height: 100vh; height: 100dvh; box-sizing: border-box; }
}

/* Account menu: address plus a key dot; key status, Settings and Log out
   open above it (in the narrow top bar, below it). */
.account {
    position: relative;
    margin-top: auto;
    padding-right: .75rem;
    font-size: .8125rem;
}
.account summary {
    display: flex;
    align-items: center;
    gap: .45rem;
    padding: .3rem .5rem;
    border-radius: var(--r-lg);
    color: rgb(var(--on-pine-rgb) / .85);
    cursor: pointer;
    list-style: none;
}
.account summary::-webkit-details-marker { display: none; }
.account summary::after { content: "▾"; margin-left: auto; font-size: .7rem; }
.account[open] summary::after { content: "▴"; }
.account summary:hover, .account[open] summary { background: var(--rail-deep); color: var(--on-rail); }
.account .name { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.avatar {
    position: relative; flex: none; display: grid; place-items: center;
    width: 1.75rem; height: 1.75rem; border-radius: 50%;
    background: var(--paper); color: var(--pine); font-weight: 600; font-size: .9rem; line-height: 1;
}
.avatar .key-dot { position: absolute; right: -.1rem; bottom: -.1rem; width: .6rem; height: .6rem;
                   box-shadow: 0 0 0 2px var(--rail); }
.key-dot { flex: none; width: .5rem; height: .5rem; border-radius: 50%; background: rgb(var(--on-pine-rgb) / .4); }
.account[data-key="ok"] .key-dot { background: var(--ok-dot); }
.account[data-key="missing"] .key-dot { background: var(--wax); box-shadow: 0 0 0 2px var(--rail), 0 0 0 4px var(--wax-ring); }
.menu {
    position: absolute;
    bottom: calc(100% + .25rem);
    left: 0;
    right: .75rem;
    z-index: 10;
    min-width: 13rem;
    padding: .35rem 0;
    background: var(--surface);
    color: var(--ink);
    border: 1px solid var(--rule);
    border-radius: var(--r-lg);
    box-shadow: 0 4px 16px rgb(var(--shadow) / .15);
}
.menu > a, .menu button {
    display: block;
    width: 100%;
    padding: .4rem .8rem;
    border: 0;
    background: none;
    color: var(--ink);
    text-align: left;
    text-decoration: none;
}
.menu > a:hover, .menu button:hover { background: var(--paper); }
.menu .icon { opacity: .8; }
.menu .danger { color: var(--wax); }

/* ── Pane ───────────────────────────────────────────────────────────── */

.pane { padding: 1rem clamp(.75rem, 2.5vw, 1.75rem) 2rem; }

.pane-head {
    display: flex;
    justify-content: space-between;
    align-items: baseline;
    gap: 1rem;
    margin-bottom: .5rem;
}

h1 { font-weight: 750; font-size: 1.3rem; line-height: 1.25; margin: 0; }

.empty { color: var(--muted); padding: 1.25rem 0; max-width: 34rem; }

/* ── Folder list ────────────────────────────────────────────────────── */

.list { list-style: none; margin: 0; padding: 0; border-top: 1px solid var(--rule); }

.list li { display: flex; align-items: center; border-bottom: 1px solid var(--rule); }
/* Alternate rows a shade lighter than the paper; hover and ticked rows,
   further down, still win. */
.list li:nth-child(even) { background: var(--zebra); }
.list li:hover { background: var(--hover); }
.list li > a {
    flex: 1;
    min-width: 0;
    display: grid;
    grid-template-columns: minmax(6rem, 10rem) minmax(0, 1fr) auto;
    gap: .6rem;
    align-items: baseline;
    padding: .4rem .5rem .4rem .35rem;
    color: var(--ink);
    text-decoration: none;
}

.who, .what { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
/* How many messages an Inbox conversation holds. */
.thread-n { color: var(--muted); font-size: .8125rem; font-weight: 400; font-variant-numeric: tabular-nums; }
.snippet { color: var(--muted); }
/* Three lines a row: who, subject and time on the first, the start of
   the text under the subject on the next two. The lines are kept when
   there is no snippet (not decrypted, an old key), so rows stay one height. */
.list .snippet {
    display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 2; line-clamp: 2;
    white-space: normal; overflow: hidden; min-height: 2lh;
}
.list time { color: var(--muted); font-size: .8125rem; font-variant-numeric: tabular-nums; }

/* Ticking rows: the bar sits on the list's top rule, its box in line
   with the rows' boxes. */
.pick, .pick-all { margin: 0; accent-color: var(--pine); flex: none; }
.pick-area { display: flex; align-items: center; align-self: stretch; flex: none; padding: 0 .25rem 0 .5rem; cursor: pointer; }
/* In the list the unread seal stacks above the box, out of the text's way;
   the margin keeps the box centred on the row whether or not it shows. */
.list .pick-area { flex-direction: column; justify-content: center; gap: 1px; padding-right: 0; }
.list .pick-area .seal { margin-top: calc(-.5rem - 1px); }
.list .unread .seal { box-shadow: 0 0 0 1px rgb(var(--wax-rgb) / .18); }
.pick-area[hidden] { display: none; }
.list li.picked { background: var(--picked); }
.bulk {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: .4rem .6rem;
    min-height: 2.1rem;
    padding: .2rem 0;
    font-size: .875rem;
}
.bulk .picked { color: var(--muted); }
.bulk-actions { display: flex; flex-wrap: wrap; gap: .4rem; }
.pane-head .list-menu { align-self: center; }
.pane-head .list-menu .menu { min-width: 13rem; }
/* Show and Sort: a small heading per group, the current choice in pine. */
.list-menu .menu-head { padding: 0 .8rem; }
.list-menu .menu > a[aria-current], .list-menu .menu-choices button[aria-current] { color: var(--pine); font-weight: 600; }
.list-menu .menu > a[aria-current] .icon, .list-menu .menu-choices button[aria-current] .icon { opacity: 1; }
.list .size { color: var(--ink); }
.bulk button {
    background: none;
    border: 1px solid var(--rule);
    border-radius: var(--r);
    padding: .15rem .65rem;
}
.bulk button:hover { border-color: var(--muted); }
.bulk .danger { color: var(--wax); }

/* The wax seal: only unread mail carries one, and opening breaks it. */
.seal {
    width: .5rem;
    height: .5rem;
    align-self: center;
    border-radius: 50%;
}
.unread .seal {
    background: var(--wax);
    box-shadow: 0 0 0 2px rgb(var(--wax-rgb) / .18);
}
.unread .who, .unread .subject { font-weight: 800; }

/* ── One message: a letter, set for reading ─────────────────────────── */

.letter { max-width: 44rem; }

.actions {
    display: flex;
    flex-wrap: wrap;
    gap: .25rem 1.1rem;
    align-items: baseline;
    margin-bottom: 1rem;
    font-size: .875rem;
}
.actions form { margin: 0; }
.back::before { content: "‹ "; }

.letter h1 { font-size: 1.4rem; margin-bottom: .5rem; }

.meta {
    display: grid;
    grid-template-columns: auto 1fr;
    gap: .1rem 1rem;
    margin: 0 0 1.1rem;
    padding-bottom: .7rem;
    border-bottom: 1px solid var(--rule);
    font-size: .875rem;
}
.meta dt { color: var(--muted); }
.meta dd { margin: 0; }

.body {
    font-family: var(--letter);
    font-size: 1rem;
    line-height: 1.55;
    white-space: pre-wrap;
    overflow-wrap: anywhere;
    max-width: 38em;
}

/* ── Compose ────────────────────────────────────────────────────────── */

.compose { max-width: 44rem; }

.field {
    display: grid;
    grid-template-columns: 5rem 1fr;
    align-items: baseline;
    border-bottom: 1px solid var(--rule);
}
.field label { color: var(--muted); }
.field input {
    border: 0;
    background: transparent;
    padding: .4rem 0;
}
.field input:focus { outline: none; }
.field:focus-within { border-bottom-color: var(--pine); }

.compose textarea {
    width: 100%;
    margin-top: .75rem;
    padding: .6rem;
    border: 1px solid var(--rule);
    border-radius: var(--r);
    background: var(--surface);
    font-family: var(--letter);
    font-size: 1rem;
    line-height: 1.5;
    resize: vertical;
}
.compose textarea:focus { outline: none; border-color: var(--pine); }

/* ── Controls ───────────────────────────────────────────────────────── */

button { cursor: pointer; }


/* Line icons from public/img/icons.svg, in the text's own colour. */
.icon {
    width: 1.1em;
    height: 1.1em;
    flex: none;
    vertical-align: -.2em;
    margin-right: .4em;
}
.folders a > span:first-child { display: inline-flex; align-items: center; white-space: nowrap; min-width: 0; }
.folders a .icon { opacity: .85; }
.folders a.current .icon { opacity: 1; color: var(--pine); }
.label-list .icon { width: 1em; height: 1em; opacity: 1;
                    color: color-mix(in srgb, var(--label, currentColor) 70%, white); }
.label-list a.current .icon { color: var(--label, var(--pine)); }
.more-labels {
    background: none; border: 0; padding: .1rem .6rem; text-align: left;
    color: rgb(var(--on-pine-rgb) / .75); font-size: .8125rem; cursor: pointer;
}
.more-labels:hover { color: var(--on-rail); text-decoration: underline; }
.write .icon { margin-right: .35em; }
.actions .icon { color: var(--pine); }
.bulk button .icon { margin-right: .3em; }

.primary {
    background: var(--pine);
    color: var(--on-pine);
    border: 0;
    border-radius: var(--r);
    padding: .4rem 1.2rem;
    font-weight: 500;
}
.primary:hover { background: var(--pine-deep); }
.primary:disabled { background: var(--muted); cursor: progress; }

.quiet {
    background: none;
    border: 1px solid var(--rule);
    border-radius: var(--r);
    padding: .3rem .8rem;
    color: var(--muted);
}

.link {
    background: none;
    border: 0;
    padding: 0;
    color: var(--pine);
    text-decoration: underline;
}
.danger { color: var(--wax); }

.error {
    margin: 0 0 1rem;
    padding: .6rem .8rem;
    border-left: 3px solid var(--wax);
    background: var(--error-bg);
    color: var(--error-ink);
}

/* ── Login: a single card on paper ─────────────────────────────────── */

.gate {
    min-height: 100vh;
    display: grid;
    place-items: center;
    padding: 1rem;
}

.gate-card { width: min(22rem, 100%); }

.wordmark-large {
    font-size: 2.75rem;
    font-weight: 600;
    color: var(--pine);
    letter-spacing: -.01em;
}
/* Artwork is drawn at twice its display size, so it stays sharp on dense screens. */
.gate-art { display: block; width: min(18.75rem, 100%); height: auto; margin: 0 0 .25rem -.4rem; }
.empty-art { display: block; width: 10rem; height: auto; margin: 0 0 .5rem; }
.empty p { margin: 0; }

.tagline { margin: 0 0 1.75rem; color: var(--muted); font-family: var(--letter); font-style: italic; }

.stack { display: grid; gap: .35rem; }
.stack label { font-size: .875rem; color: var(--muted); margin-top: .5rem; }
.stack input {
    padding: .55rem .7rem;
    border: 1px solid var(--rule-strong);
    border-radius: var(--r);
    background: var(--surface);
}
.stack input:focus { outline: 2px solid var(--pine); outline-offset: -1px; border-color: var(--pine); }
.stack .primary { margin-top: 1rem; }

.note { font-size: .875rem; color: var(--muted); margin-top: 1.5rem; }

/* Writing: no folders or labels in the rail. */
.writing .rail .folders, .writing .rail .labels-nav { display: none; }

/* ── Narrow screens: the rail becomes a top bar ─────────────────────── */

@media (max-width: 44rem) {
    /* minmax(0, …): a long word in the pane must not widen the page. */
    .shell { grid-template-columns: minmax(0, 1fr); min-height: 0; }
    .rail {
        flex-direction: row;
        flex-wrap: wrap;
        align-items: center;
        gap: .5rem 1rem;
        padding: .75rem 1rem;
    }
    .write { margin: 0 0 0 auto; padding: .35rem .8rem; }
    .folders { display: flex; width: 100%; overflow-x: auto; gap: .25rem; }
    .folders a { border-radius: var(--r-lg); padding: .35rem .7rem; gap: .4rem; }
    /* One row: the wordmark, then Write, Search and the account menu as
       your initial (the address is its tooltip). */
    .wordmark { padding-right: 0; }
    .rail .search-link { margin-right: 0; }
    .account { margin: 0; padding: 0; }
    .account { order: 1; }
    .account .name { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); }
    .account summary { padding: .3rem .35rem; gap: .3rem; }
    .folders { order: 2; }
    /* On a phone, a small button beside Write instead of a whole row. */
    .search-link { margin: 0; padding: .35rem .55rem; border: 1px solid rgb(var(--on-pine-rgb) / .55); border-radius: var(--r); }
    .search-link .icon { margin: 0; }
    .search-link span { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); }
    .labels-nav { order: 4; width: 100%; flex-direction: row; align-items: center; gap: .75rem; }
    .label-list { order: 0; flex: 1; min-width: 0; width: auto; }
    .label-list:empty { display: none; }
    .label-list a { padding: .2rem .6rem; white-space: nowrap; }
    .label-list.nested li { padding-left: 0; }
    .label-toggle-space { display: none; }
    /* The toggle is the chip's own end, not a glyph loose before it, and a
       child says so with a "›": the row has no indent to show nesting. */
    .label-list.nested li { flex-direction: row-reverse; flex: 0 0 auto; align-items: stretch; }
    .label-list.nested li:has(.label-toggle) > a { border-top-right-radius: 0; border-bottom-right-radius: 0; }
    .rail .label-toggle {
        flex: 0 0 auto; min-width: 2rem; margin-left: 1px; border-radius: 0 4px 4px 0;
        background: color-mix(in srgb, var(--label, var(--pine-deep)) 70%, black); color: var(--on-label); font-size: 1rem;
    }
    .label-list .label-toggle .icon { width: 1rem; height: 1rem; opacity: 1; }
    .label-list li[data-child] > a::before { content: "↳"; margin-right: .3rem; opacity: .85; }
    .menu { bottom: auto; top: calc(100% + .25rem); left: auto; right: 0; }
    /* Narrowest phones: no ▾ either, so the top bar stays one row. */
    @media (max-width: 22.5rem) {
        .account summary::after, .account[open] summary::after { content: none; }
        .rail { gap: .5rem .6rem; }
    }
    /* Three lines: who, time and ⋯ on the first, the subject and snippet
       across the whole width on the next two. The seal lines up with the first, the
       box with the second; the pick area copies the link's padding, gap
       and line height so the two columns stay in step. */
    .list li { position: relative; }
    .list li > a { grid-template-columns: minmax(0, 1fr) auto; row-gap: .15rem; }
    .list .what { grid-column: 1 / -1; grid-row: 2; }
    .list .what {
        display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 2; line-clamp: 2;
        white-space: normal; min-height: 2lh;
    }
    .list .snippet { display: inline; min-height: 0; }
    .list time { grid-column: 2; grid-row: 1; margin-right: 1.75rem; }
    .list .msg-menu { position: absolute; top: 0; right: 0; }
    .list .pick-area {
        display: grid;
        grid-template-rows: 1lh 1lh;
        row-gap: .15rem;
        align-content: start;
        align-items: center;
        justify-items: center;
        padding-top: .4rem;
        padding-bottom: .4rem;
    }
    .list .pick-area .seal { margin-top: 0; }
}

/* ── Rail as buttons (trial, 2026-10-13) ─────────────────────────────
   Folders and Search as outlined buttons, the current one filled with
   paper; labels filled with their colour. Replaces the notch. Delete this
   block to go back. */
.rail .folders li + li { margin-top: .3rem; }
.rail .folders a, .rail .search-link {
    margin-right: .75rem;
    border: 1px solid rgb(var(--on-pine-rgb) / .28);
    border-radius: var(--r);
    align-items: center;
}
.rail .folders a:hover, .rail .search-link:hover { background: var(--rail-deep); border-color: rgb(var(--on-pine-rgb) / .5); }
.rail .folders a.current, .rail .search-link.current { background: var(--paper); color: var(--ink); border-color: var(--paper); }
.rail .label-list a {
    background: color-mix(in srgb, var(--label, var(--pine-deep)) 82%, black);
    border-color: transparent;
    color: var(--on-label);
}
.rail .label-list a:hover { background: color-mix(in srgb, var(--label, var(--pine-deep)) 65%, black); }
.rail .label-list a .icon { color: var(--on-label); opacity: .85; }
.rail .label-list a.current { box-shadow: 0 0 0 2px var(--paper); }
.rail .label-list a.current .icon { color: var(--label, var(--pine)); }
.rail .label-list a .count { color: var(--on-label); }
@media (max-width: 44rem) {
    .rail .folders li + li { margin-top: 0; }
    .rail .folders a { margin-right: 0; }
}

/* ── Touch: tap targets of at least about 36 px ─────────────────────── */

@media (max-width: 44rem), (pointer: coarse) {
    .pick-area { padding: 0 .6rem 0 .75rem; min-height: 2.25rem; }
    .list .pick-area { padding-right: .15rem; }
    .compose > .check { display: flex; align-items: center; gap: .5rem; min-height: 2.25rem; }
    .actions { gap: 0 1.1rem; }
    .actions > a, .actions > .link { padding: .55rem 0; }
    .msg-menu summary { min-width: 2.25rem; min-height: 2.25rem; display: flex; align-items: center; justify-content: center; }
    .search-link { padding: .5rem .6rem; }
    .account summary { padding-top: .45rem; padding-bottom: .45rem; }
    #discard, .thread-open { display: inline-block; padding: .5rem 0; }
    .search-help summary { padding: .5rem 0; }
    .remove { padding: .5rem .25rem .5rem .6rem; }
    .label-list a { padding-top: .45rem; padding-bottom: .45rem; }
    .label-toggle { flex-basis: 1.75rem; min-height: 2.25rem; }
}

/* ── Accounts: setup, key status, settings ─────────────────────────── */

.setup { width: min(26rem, 100%); }
.lead { font-size: 1.0625rem; margin: 0 0 .5rem; }

.warning {
    margin: 1rem 0 .25rem;
    padding: .7rem .8rem;
    border-left: 3px solid var(--wax);
    background: var(--error-bg);
    font-size: .875rem;
}
.warning p { margin: 0 0 .5rem; }
.check { display: flex; gap: .5rem; align-items: baseline; color: var(--ink); }
.stack .check { margin-top: 0; font-size: .875rem; }

.key-status { margin: 0 0 .25rem; padding: .3rem .8rem .5rem; border-bottom: 1px solid var(--rule); color: var(--muted); }
.key-status[data-state="ok"]::before { content: "● "; color: var(--pine); }
.key-status[data-state="missing"] { color: var(--wax); }

.settings { max-width: 40rem; }
.settings h2 { font-size: 1rem; font-weight: 600; margin: 1.5rem 0 .4rem; }
.settings p { margin: 0 0 .5rem; }
/* Passkeys: the list, adding one, and recovery codes shown once. */
.passkey-list { list-style: none; margin: .25rem 0 .5rem; padding: 0; }
.passkey-list li { display: flex; flex-wrap: wrap; align-items: baseline; gap: .25rem .75rem;
                   padding: .4rem 0; border-bottom: 1px solid var(--rule); }
.passkey-name { font-weight: 500; }
.passkey-list .passkey-remove { margin-left: auto; }
.passkey-add { display: flex; gap: .5rem; margin: .5rem 0; max-width: 30rem; }
.passkey-add input {
    flex: 1; min-width: 0; padding: .35rem .5rem;
    border: 1px solid var(--rule); border-radius: var(--r); background: var(--surface);
}
.recovery-codes { border-left: 3px solid var(--pine); padding: .25rem 0 .25rem 1rem; margin: 1rem 0; }
.recovery-codes h3 { font-size: 1rem; margin: 0 0 .25rem; }
.recovery-list { columns: 2; font-family: ui-monospace, "DejaVu Sans Mono", monospace; font-size: .9375rem;
                 margin: .5rem 0; padding-left: 1.5rem; }
.second-step .link { justify-self: start; margin-top: .25rem; }
.second-step .note { margin-top: .25rem; }
/* The ways through the second step, each with its icon; the link's
   underline stays on the words. */
.with-icon { display: inline-flex; align-items: center; justify-content: center; }
.link.with-icon { text-decoration: none; }
.link.with-icon span { text-decoration: underline; }
.with-icon .icon { width: 1.25em; height: 1.25em; }
.second-step #device-input { font-size: 1.25rem; letter-spacing: .3em; max-width: 8rem; }

/* A login elsewhere waiting for this device's code: on top of everything,
   where a phone's thumb and eye already are. */
.device-request {
    position: fixed; z-index: 50; top: .75rem; left: 50%; transform: translateX(-50%);
    width: min(24rem, calc(100% - 2rem)); box-sizing: border-box;
    background: var(--surface); border: 1px solid var(--rule); border-left: 4px solid var(--pine); border-radius: var(--r-lg);
    box-shadow: 0 6px 24px rgb(var(--shadow) / .18); padding: .75rem 1rem;
}
.device-request p { margin: 0 0 .35rem; }
.device-code { font-size: 2rem; font-weight: 600; letter-spacing: .35em; color: var(--pine);
               font-variant-numeric: tabular-nums; margin: .25rem 0 .5rem !important; }
.device-buttons { display: flex; align-items: center; justify-content: space-between; gap: .5rem; margin: 0 !important; }
.device-buttons .note { margin: 0; }
.settings-lists .check { display: flex; gap: .5rem; align-items: baseline; margin-bottom: .25rem; }
.key { font-family: ui-monospace, "DejaVu Sans Mono", monospace; font-size: .8125rem; overflow-wrap: anywhere; }
.narrow { max-width: 22rem; }

.ok {
    margin: 0 0 .5rem;
    padding: .5rem .8rem;
    border-left: 3px solid var(--pine);
    background: var(--tint);
}

/* ── Mail (stage 4) ─────────────────────────────────────────────────── */

.pager { display: flex; gap: 1.25rem; padding: .75rem .5rem; font-size: .875rem; }
.delivery { color: var(--muted); font-size: .8125rem; }
/* A header whose sender disagrees with the delivery record. */
.list li.mismatch .who::after { content: " ⚠"; color: var(--wax); }

/* ── Attachments ────────────────────────────────────────────────────── */

.files { list-style: none; margin: 0 0 1rem; padding: 0; display: flex; flex-wrap: wrap; gap: .4rem; }
.file {
    background: var(--surface);
    border: 1px solid var(--rule);
    border-radius: var(--r);
    padding: .3rem .7rem;
    color: var(--pine);
    font-size: .875rem;
}
.file:hover { border-color: var(--pine); }
.file.broken { color: var(--wax); border-color: var(--wax); }
.list li.has-files .subject::before { content: "📎 "; }
/* Picks add to the list rather than replace it: phone pickers often take
   one file at a time. The native input is hidden behind the label. */
.attach { display: flex; flex-wrap: wrap; align-items: center; gap: .4rem; padding: .35rem 0; }
.attached { display: contents; list-style: none; }
.field .add-file { color: var(--pine); cursor: pointer; }
.attach input:focus-visible + .add-file { outline: 2px solid var(--pine); outline-offset: 2px; }
.attached .file { color: var(--ink); }
.remove { background: none; border: 0; padding: 0 0 0 .4rem; color: var(--muted); font-size: 1rem; line-height: 1; }
.remove:hover { color: var(--wax); }
.forward-files { border: 0; margin: .5rem 0 0; padding: 0; font-size: .875rem; }
.forward-files legend { color: var(--muted); padding: 0; margin-bottom: .25rem; }
.forward-files ul { list-style: none; margin: 0; padding: 0; display: flex; flex-wrap: wrap; gap: .25rem 1rem; }

/* ── Search ─────────────────────────────────────────────────────────── */

.search-page { max-width: 60rem; }
.search-help code { overflow-wrap: anywhere; }
.search-page code, .search-help code { font-size: .8125rem; background: var(--rule); border-radius: var(--r); padding: 0 .25rem; }
#search-status[data-state="error"] { color: var(--wax); }
.empty-note { color: var(--muted); padding: 1rem .5rem; }
.search-help { margin-top: 1.5rem; font-size: .875rem; max-width: 44rem; }
.search-help summary { cursor: pointer; color: var(--pine); }
.search-help dl { display: grid; grid-template-columns: max-content 1fr; gap: .35rem 1rem; margin: .75rem 0; }
.search-help dd { margin: 0; }
@media (max-width: 44rem) {
    .search-help dl { grid-template-columns: 1fr; gap: 0; }
    .search-help dd { margin-bottom: .5rem; }
}


/* ══ kansli's own ═════════════════════════════════════════════════════ */

/* Bodies are rendered Markdown, not pre-wrapped text. */
.body { white-space: normal; }
.body p { margin: 0 0 .75em; }
.body h1, .body h2, .body h3, .body h4 { font-family: var(--ui); font-size: 1rem; font-weight: 600; margin: 1.1em 0 .4em; }
.body ul, .body ol { margin: 0 0 .75em; padding-left: 1.4em; }
.body blockquote { margin: 0 0 .75em .2em; padding-left: .8em; border-left: 3px solid var(--rule); color: var(--quote); }
.body table { border-collapse: collapse; font-family: var(--ui); font-size: .875rem; margin: 0 0 .75em; }
.body th, .body td { border: 1px solid var(--rule); padding: .25rem .5rem; text-align: left; }
.body pre { white-space: pre-wrap; background: var(--surface); border: 1px solid var(--rule); padding: .5rem; font-size: .875rem; }
.body code { font-size: .875em; }
.body > :last-child { margin-bottom: 0; }

/* A message and its conversation (budkavle's "Conversation" section,
   ~/dev/budkavle/public/style.css): the thread under the letter, oldest
   first. Bodies are rendered Markdown here, so no pre-wrap. */
.letter > .meta { margin-bottom: .8rem; }
.letter > .meta .from { display: flex; align-items: center; gap: .4rem; }
.thread { margin-top: 2.5rem; border-top: 1px solid var(--rule); padding-top: .75rem; }
.thread h2 { font-size: .9375rem; font-weight: 600; margin: 0 0 .4rem; }
.thread-count { color: var(--muted); font-weight: 400; margin-left: .35rem; }
.thread-list { list-style: none; margin: 0; padding: 0; font-size: .875rem; }
.thread-item { border-bottom: 1px solid var(--rule); }
.thread-item details { margin: 0; }
.thread-line {
    display: grid;
    grid-template-columns: .6rem minmax(5rem, 9rem) minmax(0, 1fr) auto;
    gap: .6rem;
    align-items: baseline;
    padding: .35rem .25rem;
    color: var(--ink);
    text-decoration: none;
    cursor: pointer;
    list-style: none;
}
.thread-line::-webkit-details-marker { display: none; }
a.thread-line:hover, summary.thread-line:hover { background: var(--hover); }
.thread-item.current .thread-line { cursor: default; background: var(--picked); }
.thread-item.unread .who { font-weight: 600; }
.thread-item .here { color: var(--pine); font-size: .8125rem; }
.thread-item time { color: var(--muted); font-size: .8125rem; font-variant-numeric: tabular-nums; }
.thread-item .what { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.thread-item .snippet { color: var(--muted); }
.thread-item .kind { color: var(--muted); font-style: italic; }
.thread-body { font-size: 1rem; padding: .5rem .25rem .25rem 1.45rem; max-width: 40rem; }
.thread-open { display: inline-block; font-size: .8125rem; margin: 0 0 .6rem 1.45rem; }
@media (max-width: 44rem) {
    .thread-line { grid-template-columns: .6rem minmax(0, 1fr) auto; }
    .thread-line .what { grid-column: 2 / -1; grid-row: 2; }
    .thread-body, .thread-open { padding-left: 0; margin-left: 0; }
}
.actions button.link { font-size: inherit; text-decoration: none; color: var(--pine); }
.actions button.link:hover { text-decoration: underline; }
.actions button.link.danger { color: var(--wax); }
.actions .icon { margin-right: .3em; }

/* Assistants are colleagues, marked so: the AI tag by their name. */
.ai-tag {
    display: inline-block; font-size: .6875rem; font-weight: 600; letter-spacing: .04em; line-height: 1.3;
    padding: 0 .3rem; border: 1px solid var(--pine); border-radius: var(--r); color: var(--pine); vertical-align: .1em;
}

/* Writing: recipients from the org chart. */
.field .chosen { padding: .4rem 0; min-height: 2rem; }
.field .chosen:empty::before { content: "–"; color: var(--muted); }
.orgchart { margin: .5rem 0 0; font-size: .9375rem; border-bottom: 1px solid var(--rule); padding-bottom: .5rem; }
.orgchart > summary { cursor: pointer; color: var(--pine); padding: .3rem 0; }
.orgchart h3 { margin: .9rem 0 .2rem; font-size: .8125rem; font-weight: 600; color: var(--muted); }
.orgchart ul { list-style: none; margin: 0; padding: 0; }
.contact { display: grid; grid-template-columns: minmax(0, 1fr) auto auto; gap: .2rem .9rem; align-items: center;
           padding: .35rem 0; border-bottom: 1px solid var(--rule); }
.contact:last-child { border-bottom: 0; }
.contact .who { display: flex; flex-direction: column; white-space: normal; }
.contact .title { font-size: .875rem; }
.contact small { color: var(--muted); font-size: .8125rem; }
.contact .check { font-size: .875rem; white-space: nowrap; }
.contact input { accent-color: var(--pine); }
.compose .field input[type=file] { padding: .4rem 0; }
.compose .hint { font-size: .8125rem; color: var(--muted); margin: .3rem 0 0; }

/* Lists: the snippet under the subject, as budkavle's `.what`. */
.list .what .subject + .snippet::before { content: " – "; color: var(--muted); }

/* Logins from other devices: budkavle's card, one per waiting login. */
#device-requests { position: fixed; z-index: 50; top: .75rem; left: 50%; transform: translateX(-50%);
                   width: min(24rem, calc(100% - 2rem)); display: grid; gap: .5rem; }
#device-requests .device-request { position: static; transform: none; width: auto; }

.settings .rows { list-style: none; padding: 0; margin: .25rem 0 .5rem; }
.settings .rows li { display: flex; flex-wrap: wrap; align-items: baseline; gap: .25rem .75rem; padding: .4rem 0; border-bottom: 1px solid var(--rule); }
.settings .rows form { margin-left: auto; }
.settings .stack { max-width: 22rem; }
.codes { font-family: ui-monospace, "DejaVu Sans Mono", monospace; font-size: .9375rem; columns: 2;
         border-left: 3px solid var(--pine); padding: .25rem 0 .25rem 1rem; margin: 1rem 0; white-space: pre-line; }
details.fallback { margin-top: 1rem; font-size: .875rem; }
details.fallback summary { cursor: pointer; color: var(--pine); }
details.fallback .stack { margin-top: .5rem; }
.gate-card h2 { font-size: 1.05rem; margin: 1rem 0 .4rem; }
a.primary { display: inline-block; text-decoration: none; }
.field .label { color: var(--muted); }
.send-row { display: flex; flex-wrap: wrap; gap: .5rem 1.25rem; align-items: baseline; margin-top: .75rem; }
.compose .send-row a { font-size: .875rem; }
/* Skicka stays in view at the foot of the window: under a long text, or
   with a phone's keyboard up, it was below the fold. */
.compose .send-row {
    position: sticky; bottom: 0; z-index: 5;
    background: var(--paper); border-top: 1px solid var(--rule);
    padding: .6rem 0 calc(.6rem + env(safe-area-inset-bottom, 0px));
}

/* The org chart as a dialog (budkavle's .label-dialog, wider), one line
   at a time: Till or Kopia. */
.label-dialog { border: 1px solid var(--rule); border-radius: var(--r-lg); padding: 1rem 1.25rem;
                width: min(22rem, calc(100vw - 2rem)); background: var(--paper); color: var(--ink); }
.label-dialog::backdrop { background: rgb(var(--shadow) / .35); }
.label-dialog h2 { font-size: 1rem; margin: 0 0 .5rem; }
.dialog-buttons { display: flex; gap: .5rem; margin: 0; }
.org-dialog { width: min(34rem, calc(100vw - 2rem)); }
.org-dialog[open] { max-height: calc(100vh - 2rem); display: flex; flex-direction: column; }
.org-scroll { overflow-y: auto; margin: 0 -1.25rem .75rem; padding: 0 1.25rem; }
.org-dialog h3, .org-fallback h3 { margin: .9rem 0 .2rem; font-size: .8125rem; font-weight: 600; color: var(--muted); }
.org-dialog h3:first-child { margin-top: .25rem; }
.org-dialog ul { list-style: none; margin: 0; padding: 0; }
.org-dialog .contact { display: flex; gap: .6rem; align-items: baseline; padding: .4rem .25rem;
                       border-bottom: 1px solid var(--rule); cursor: pointer; }
.org-dialog li:last-child .contact { border-bottom: 0; }
.org-dialog .contact:hover { background: var(--hover); }
.org-dialog .contact:has(input:checked) { background: var(--picked); }
.org-dialog .contact:has(input:disabled) { color: var(--muted); cursor: default; }
.org-dialog .contact input { accent-color: var(--pine); flex: none; }
.org-dialog .elsewhere:not(:empty) { margin-left: .4rem; font-size: .8125rem; color: var(--muted); }
.field.recipients { grid-template-columns: 5rem minmax(0, 1fr); align-items: center; }
.pick-recipients { justify-self: start; padding: .15rem .55rem; margin: .25rem 0; font-size: .875rem; color: var(--pine); }
.pick-recipients .icon { margin-right: .3em; }
.org-fallback { font-size: .875rem; }

/* The assistants: what they are doing, under the letter. */
.assistant-status { margin: .75rem 0 0; color: var(--muted); font-style: italic; font-size: .9375rem; }
.assistant-status span { display: block; }

/* Attachment previews: an image or a PDF's first page as a picture, a text
   file's opening lines; under it the same name and size as a plain file.
   One that can't be previewed falls back to the plain link (kansli.js). */
.files .preview .file { display: flex; flex-direction: column; gap: .3rem; padding: .3rem; width: 15rem; }
.files .preview img, .files .preview pre {
    width: 100%; height: 10.5rem; margin: 0; border-radius: 2px; background: var(--thumb);
}
.files .preview img { object-fit: contain; display: block; }
.files .preview pre {
    overflow: hidden; padding: .4rem .5rem; color: var(--ink); white-space: pre-wrap;
    font-size: .6875rem; line-height: 1.35;
    -webkit-mask-image: linear-gradient(#000 70%, transparent); mask-image: linear-gradient(#000 70%, transparent);
}
.files .preview .file-name { padding: 0 .3rem .1rem; overflow-wrap: anywhere; }
@media (max-width: 40rem) { .files .preview .file { width: calc(50vw - 1.5rem); } }
/* An attachment shown in the text: a picture, opening the file. */
.body img { max-width: 100%; height: auto; border: 1px solid var(--rule); border-radius: 2px; }

/* Status, from the account menu: one line per assistant. */
.status-dialog { width: min(28rem, calc(100vw - 2rem)); }
.status-watcher { margin: 0 0 .5rem; font-size: .9375rem; }
.status-watcher.away { color: var(--wax); }
.status-list { list-style: none; margin: 0 0 .75rem; padding: 0; max-height: 60vh; overflow-y: auto; }
.status-list li { padding: .4rem 0; border-bottom: 1px solid var(--rule); }
.status-list li:last-child { border-bottom: 0; }
.status-list small { color: var(--muted); }
.status-what { display: block; font-size: .875rem; color: var(--muted); }
.status-list li.busy .status-what { color: var(--pine); font-style: italic; }

/* ── Labels (budkavle's, kept on the server) ────────────────────────── */

.labels-nav { display: flex; flex-direction: column; gap: .2rem; }
@media (min-width: 44.01rem) and (min-height: 32rem) {
    .labels-nav {
        flex: 1 1 auto; min-height: 0; overflow-y: auto; overscroll-behavior: contain;
        padding: 2px 0 2px 2px; margin: -2px 0 -2px -2px;
        scrollbar-width: thin; scrollbar-color: rgb(var(--on-pine-rgb) / .35) transparent;
    }
    .account { margin-top: 0; }
}
.label-list a { font-size: .875rem; padding-top: .2rem; padding-bottom: .2rem; }
.label-list a span:first-child { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.chips:empty { display: none; }
.chip {
    display: inline-block;
    margin-right: .3rem;
    padding: 0 .35rem;
    border-radius: var(--r);
    background: color-mix(in srgb, var(--label, var(--muted)) 18%, var(--paper));
    box-shadow: inset 2px 0 0 var(--label, transparent);
    color: var(--ink);
    font-size: .75rem;
    font-weight: 400;
    vertical-align: .1em;
}
p.chips { margin: -.25rem 0 .75rem; }
a.chip { text-decoration: none; }
a.chip:hover { background: var(--pine); color: var(--on-pine); }
.letter-labels .labels-open { font-size: .8125rem; color: var(--muted); vertical-align: .1em; }
.letter-labels .labels-open:hover { color: var(--pine); }
.dot { display: inline-block; width: .6rem; height: .6rem; border-radius: 50%;
       background: var(--label, var(--muted)); margin: 0 .1rem 0 .15rem; align-self: center; }
.label-choices { list-style: none; margin: 0 0 .75rem; padding: 0; max-height: 50vh; overflow-y: auto; }
.label-choices label { display: flex; gap: .5rem; padding: .2rem 0; cursor: pointer; }
.label-choices input { accent-color: var(--pine); }
.new-label { display: flex; gap: .5rem; margin-bottom: .75rem; }
.new-label input, .label-create input:not([type=hidden]), .label-edit input[name=name] {
    flex: 1; min-width: 0; padding: .3rem .5rem;
    border: 1px solid var(--rule); border-radius: var(--r); background: var(--surface);
}
.labels-admin { max-width: 40rem; }
.label-create { display: flex; gap: .5rem; margin: .75rem 0 1.25rem; }
.label-admin { list-style: none; margin: 0; padding: 0; }
.label-admin .label-row { padding: .4rem .25rem; border-bottom: 1px solid var(--rule); }
.label-edit { display: flex; flex-wrap: wrap; align-items: center; gap: .4rem .6rem; }
.label-edit select { padding: .25rem .3rem; border: 1px solid var(--rule); border-radius: var(--r); background: var(--surface); font: inherit; font-size: .875rem; }
.label-edit .delivery { text-decoration: none; }

/* ── Library (stage 4) ──────────────────────────────────────────────── */

.library, .library-file { max-width: 56rem; }
.library .pane-head { display: flex; align-items: baseline; justify-content: space-between; gap: 1rem; }
.trash-link { font-size: .875rem; color: var(--muted); text-decoration: none; }
.trash-link:hover { color: var(--pine); }
.crumbs { font-size: .875rem; color: var(--muted); margin: -.25rem 0 .75rem; overflow-wrap: anywhere; }
.crumbs a { color: var(--pine); text-decoration: none; }
.crumbs a:hover { text-decoration: underline; }
.library-tools { display: flex; flex-wrap: wrap; gap: .5rem 1.5rem; align-items: center; margin: 0 0 1rem; }
.library-upload, .library-mkdir { display: flex; flex-wrap: wrap; gap: .4rem; align-items: center; }
.library-upload input[type=file] { position: absolute; width: 1px; height: 1px; opacity: 0; }
.library-upload .add-file { cursor: pointer; color: var(--pine); font-size: .9375rem; }
.library-upload .add-file:has(input:focus-visible) { outline: 2px solid var(--pine); outline-offset: 2px; }
.library-mkdir input:not([type=hidden]), .library-mkdir select, .library-bulk select {
    min-width: 0; padding: .3rem .5rem; border: 1px solid var(--rule); border-radius: var(--r); background: var(--surface); font: inherit; font-size: .875rem;
}
.library-mkdir input[name=name] { width: 14rem; max-width: 100%; }
.library-list { list-style: none; margin: 0; padding: 0; border-top: 1px solid var(--rule); }
.library-list li { display: flex; align-items: center; gap: .5rem; border-bottom: 1px solid var(--rule); }
.library-list li:hover { background: var(--surface); }
.library-list .pick { padding: .5rem 0 .5rem .4rem; display: flex; }
.library-list .pick input { accent-color: var(--pine); }
.library-list a, .library-list.trashed li { flex: 1; min-width: 0; display: flex; align-items: center; gap: .6rem;
                                             padding: .35rem .4rem; color: var(--ink); text-decoration: none; }
.library-list .thumb { flex: none; width: 2.5rem; height: 2rem; display: flex; align-items: center; justify-content: center;
                       background: var(--thumb); border-radius: 2px; overflow: hidden; color: var(--muted); }
.library-list .dir .thumb { color: var(--pine); background: none; }
.library-list .thumb img { width: 100%; height: 100%; object-fit: cover; }
.library-list .thumb .icon { margin: 0; width: 1.2rem; height: 1.2rem; }
.library-list .name { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.library-list .dir .name { font-weight: 500; }
.library-list .name small { color: var(--muted); }
.library-list time, .library-list .delivery { flex: none; font-size: .8125rem; color: var(--muted); }
.library-list.trashed form { flex: none; }
.library-bulk { display: flex; flex-wrap: wrap; align-items: center; gap: .4rem 1rem; margin: .75rem 0 0; font-size: .875rem; }
.library-bulk .move-to { display: inline-flex; gap: .3rem; align-items: center; }
@media (max-width: 44rem) {
    .library-list time { display: none; }
    .library-mkdir input[name=name] { width: 100%; }
}
.library-file h1 { overflow-wrap: anywhere; }
.library-view { margin: 1rem 0; }
.library-view img { max-width: 100%; height: auto; border: 1px solid var(--rule); background: var(--surface); }
.library-view iframe { width: 100%; height: 80vh; border: 1px solid var(--rule); background: var(--surface); }
.library-view pre { white-space: pre-wrap; background: var(--surface); border: 1px solid var(--rule); padding: .75rem; font-size: .875rem; max-height: 80vh; overflow: auto; }
.library-manage { margin-top: 1.25rem; font-size: .875rem; }
.library-manage summary { cursor: pointer; color: var(--pine); }
.library-manage form { margin: .6rem 0 0; }
/* Compose: the file input and "Från biblioteket" side by side. */
.attach-row { display: flex; flex-wrap: wrap; align-items: center; gap: .25rem 1rem; }
.pick-library { font-size: .875rem; color: var(--pine); padding: .15rem .55rem; }
.library-picks { list-style: none; margin: 0; padding: 0; }
.library-picks li { padding: .25rem 0; border-bottom: 1px solid var(--rule); }
.library-picks button.link { text-align: left; }
/* An attachment's "Spara i biblioteket", under it. */
.files li { display: flex; flex-direction: column; gap: .15rem; }
.save-file { font-size: .75rem; color: var(--muted); text-decoration: none; padding-left: .2rem; }
.save-file:hover { color: var(--pine); text-decoration: underline; }

/* ── The AI page (public/ai.js): budkavle's AI dialog as a page of its
   own; the chat and gallery grow with the page instead of scrolling in a box. */
.ai-page { max-width: 56rem; }
.ai-head { display: flex; align-items: baseline; gap: .75rem; }
.ai-state { font-size: .8125rem; color: var(--muted); }
.ai-state::before { content: ""; display: inline-block; width: .5rem; height: .5rem; border-radius: 50%;
                    margin-right: .35rem; background: var(--rule); }
.ai-state[data-up="true"]::before { background: var(--pine); }
.ai-state[data-up="false"]::before { background: var(--wax); }
.ai-where { margin: 0 0 .25rem; }
.ai-where select { max-width: 100%; }
.ai-tabs { display: flex; gap: .25rem; border-bottom: 1px solid var(--rule); margin: .5rem 0 .75rem; }
.ai-tabs button { background: none; border: 0; border-bottom: 2px solid transparent; padding: .35rem .75rem;
                  color: var(--muted); font: inherit; cursor: pointer; margin-bottom: -1px; }
.ai-tabs button[aria-selected="true"] { color: var(--ink); border-bottom-color: var(--pine); }
/* Your words on the right, tinted; the AI's on the left, on white, as a letter would read. */
.ai-chat { list-style: none; margin: 0 0 .75rem; padding: 0; display: flex; flex-direction: column; gap: .6rem; }
.ai-chat:empty { display: none; }
.ai-chat li { padding: .45rem .75rem .55rem; border-radius: var(--r); max-width: 85%; }
.ai-chat .ai-user { align-self: flex-end; background: color-mix(in srgb, var(--pine) 10%, var(--light)); }
.ai-chat .ai-assistant { align-self: flex-start; background: var(--surface); border: 1px solid var(--rule); }
.ai-who { margin: 0 0 .15rem; font-size: .75rem; color: var(--muted); }
.ai-said { font-family: var(--letter); line-height: 1.5; overflow-wrap: anywhere; white-space: pre-wrap; }
.ai-said:has(> p, > ul, > ol, > pre, > table, > h1, > h2, > h3) { white-space: normal; }
.ai-said p, .ai-said ul, .ai-said ol, .ai-said pre { margin: 0 0 .5rem; }
.ai-said > :last-child { margin-bottom: 0; }
.ai-said ul, .ai-said ol { padding-left: 1.25rem; }
.ai-said pre { white-space: pre-wrap; font-size: .875rem; }
.ai-busy { display: inline-flex; align-items: center; gap: .5rem; font-family: var(--ui); font-size: .875rem;
           color: var(--muted); font-variant-numeric: tabular-nums; white-space: normal; }
.ai-secs:not(:empty)::before { content: "· "; }
.spinner { width: 1rem; height: 1rem; flex: none; box-sizing: border-box; border-radius: 50%;
           border: 2px solid var(--rule); border-top-color: var(--pine); animation: spin .8s linear infinite; }
@keyframes spin { to { transform: rotate(1turn); } }
@media (prefers-reduced-motion: reduce) { .spinner { animation-duration: 3s; } }
.ai-actions { display: flex; flex-wrap: wrap; gap: .4rem; margin: .5rem 0 0; font-size: .8125rem; }
.ai-actions .quiet { color: var(--pine); padding: .15rem .6rem; text-decoration: none; }
.ai-actions .quiet:hover { border-color: var(--pine); }
.ai-actions .quiet:disabled { color: var(--muted); border-color: var(--rule); }
.ai-actions .ai-remove { margin-left: auto; color: var(--muted); }
.ai-saved { overflow-wrap: anywhere; }
.ai-ask textarea { width: 100%; font: inherit; padding: .5rem; resize: vertical;
                   border: 1px solid var(--rule); border-radius: var(--r); background: var(--surface); color: var(--ink); }
.ai-ask textarea:focus { outline: none; border-color: var(--pine); }
.ai-row { display: flex; flex-wrap: wrap; align-items: center; gap: .5rem .75rem; margin-top: .5rem; font-size: .875rem; }
.ai-row select { font: inherit; padding: .2rem; border: 1px solid var(--rule); border-radius: var(--r); background: var(--surface); color: var(--ink); }
.ai-spacer { flex: 1; }
.ai-gallery { list-style: none; margin: .75rem 0 0; padding: 0;
              display: grid; grid-template-columns: repeat(auto-fill, minmax(14rem, 1fr)); gap: .75rem; align-items: start; }
.ai-gallery img { display: block; width: 100%; height: auto; border-radius: var(--r-lg); background: var(--rule); }
.ai-pending { display: grid; place-items: center; border-radius: var(--r-lg); background: var(--surface); border: 1px dashed var(--rule); }
.ai-pending.ai-square { aspect-ratio: 1; }
.ai-pending.ai-wide { aspect-ratio: 1344 / 768; }
.ai-pending.ai-tall { aspect-ratio: 768 / 1344; max-height: 40vh; }
.ai-pending .spinner { width: 1.75rem; height: 1.75rem; border-width: 3px; }
.ai-progress { margin: .6rem 0 0; }
.ai-progress:empty { display: none; }

/* ── The mailbox menu (budkavle's .msg-menu, as a list's Visa, Sortera
   and Lista; templates/list.html) */
.pane-tools { display: flex; align-items: center; gap: .5rem; }
.msg-menu { position: relative; }
.msg-menu summary {
    list-style: none;
    display: flex;
    align-items: center;
    min-height: 1.6em;
    padding: 0 .55rem;
    border-radius: var(--r);
    color: var(--muted);
    font-size: 1.1rem;
    line-height: 1.6;
    cursor: pointer;
}
.msg-menu summary::-webkit-details-marker { display: none; }
.msg-menu summary .icon { margin: 0; }
.msg-menu summary:hover, .msg-menu[open] summary { background: var(--rule); color: var(--ink); }
.msg-menu .menu { top: calc(100% + .2rem); bottom: auto; left: auto; right: 0; font-size: .875rem; }
.menu-head { margin: .4rem 0 .1rem; color: var(--muted); font-size: .75rem; }
.menu form.menu-choices { margin: 0; }
.menu .icon { margin-right: .4em; }

/* ── The library as webfc lays it out (templates/library.html,
   public/library.js): a toolbar of button groups, a table, a ⋯ menu per
   row; and webfc's modal layout for its dialogs. */
.lib-toolbar { display: flex; flex-wrap: wrap; gap: .4rem .75rem; align-items: center; margin: .25rem 0 .75rem; }
.tool-group { display: inline-flex; flex-wrap: wrap; gap: .3rem; align-items: center; }
.tool-group:empty { display: none; }
.lib-toolbar form { margin: 0; }
.tool {
    display: inline-flex; align-items: center; gap: .3rem;
    padding: .3rem .7rem; border: 1px solid var(--rule); border-radius: var(--r-lg);
    background: var(--surface); color: var(--ink); font-size: .875rem; text-decoration: none; cursor: pointer; line-height: 1.4;
}
.tool:hover { border-color: var(--pine); color: var(--pine); }
.tool:disabled { color: var(--muted); border-color: var(--rule); cursor: default; background: none; }
.tool .icon { margin: 0; width: 1em; height: 1em; color: var(--pine); }
.tool:disabled .icon { color: var(--muted); }
.tool.danger:not(:disabled) { color: var(--wax); }
.tool.danger:not(:disabled) .icon { color: var(--wax); }
.tool-menu summary.tool { list-style: none; font-size: .875rem; min-height: 0; padding: .3rem .7rem; color: var(--ink); }
.tool-menu summary.tool::-webkit-details-marker { display: none; }
.tool-menu .menu { left: 0; right: auto; }
.lib-toolbar .library-upload input[type=file] { position: absolute; width: 1px; height: 1px; opacity: 0; }
.lib-toolbar .library-upload .tool:has(input:focus-visible) { outline: 2px solid var(--pine); outline-offset: 2px; }
#lib-paste { border-color: var(--pine); color: var(--pine); }

.lib-table { width: 100%; border-collapse: collapse; font-size: .9375rem; }
.lib-table th { text-align: left; font-weight: 500; font-size: .8125rem; color: var(--muted); border-bottom: 1px solid var(--rule); padding: .3rem .4rem; white-space: nowrap; }
.lib-table th.num, .lib-table td.num { text-align: right; }
.lib-table .sort { background: none; border: 0; padding: 0; color: inherit; font: inherit; cursor: pointer; }
.lib-table .sort:hover { color: var(--ink); }
.lib-table th[aria-sort] .sort { color: var(--ink); }
.lib-table th[aria-sort=ascending] .sort::after { content: " ▲"; font-size: .7em; }
.lib-table th[aria-sort=descending] .sort::after { content: " ▼"; font-size: .7em; }
.lib-table td { border-bottom: 1px solid var(--rule); padding: .15rem .4rem; vertical-align: middle; }
.lib-table tbody tr:nth-child(even) { background: var(--zebra); }
.lib-table tbody tr:hover { background: var(--hover); }
.lib-table tbody tr.picked { background: var(--picked); }
.lib-table .pick-col { width: 1.75rem; padding-left: .4rem; }
.lib-table .pick-col input { accent-color: var(--pine); }
.lib-table .name-col a { display: flex; align-items: center; gap: .6rem; min-width: 0; color: var(--ink); text-decoration: none; padding: .3rem 0; }
.lib-table .name-col .name { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.lib-table .dir .name { font-weight: 500; }
.lib-table .thumb { flex: none; width: 2.5rem; height: 2rem; display: flex; align-items: center; justify-content: center;
                    background: var(--rule); border-radius: var(--r); overflow: hidden; color: var(--muted); }
.lib-table .dir .thumb { color: var(--pine); background: none; }
.lib-table .thumb img { width: 100%; height: 100%; object-fit: cover; }
.lib-table .thumb .icon { margin: 0; width: 1.2rem; height: 1.2rem; }
.lib-table .muted { color: var(--muted); font-size: .8125rem; white-space: nowrap; }
.lib-table .row-menu { width: 2rem; text-align: right; }
.lib-table .row-menu .menu { min-width: 14rem; }
.lib-table td.name-col { max-width: 0; width: 100%; }
@media (max-width: 40rem) {
    .lib-table .hide-narrow { display: none; }
}
/* A place something can be dropped, while it is dragged over. */
.drop-target, .lib-table tr.drop-target { outline: 2px dashed var(--pine); outline-offset: -2px; background: var(--picked) !important; }
.lib-drop.empty.drop-target { border-radius: var(--r-lg); }
.library-file .actions .msg-menu .menu { min-width: 13rem; }

/* webfc's modal: a title, a line, a field, the buttons on the right. */
dialog.modal { border: 0; border-radius: var(--r-lg); padding: 1.4rem 1.6rem; width: min(30rem, calc(100vw - 2rem));
               box-shadow: 0 10px 40px rgb(var(--shadow) / .25); color: var(--ink); }
dialog.modal::backdrop { background: rgb(var(--shadow) / .35); }
dialog.modal form { margin: 0; }
.modal-title { font-size: 1rem; font-weight: 600; margin: 0 0 .75rem; overflow-wrap: anywhere; }
.modal-message { font-size: .875rem; color: var(--muted); margin: 0 0 1rem; line-height: 1.5; white-space: pre-wrap; max-height: 12rem; overflow-y: auto; overflow-wrap: anywhere; }
.modal-input { display: block; width: 100%; padding: .5rem .6rem; font: inherit; border: 1px solid var(--rule); border-radius: var(--r); margin: 0 0 1.1rem; background: var(--surface); color: var(--ink); }
.modal-input:focus { outline: none; border-color: var(--pine); box-shadow: 0 0 0 3px rgb(var(--pine-rgb) / .15); }
.modal-buttons { display: flex; justify-content: flex-end; gap: .5rem; margin: 0; }
.primary.danger-fill { background: var(--wax); }
.primary.danger-fill:hover { background: var(--wax-deep); }

.library-text .text-editor textarea { width: 100%; min-height: 60vh; font: .9375rem/1.5 ui-monospace, "SF Mono", Menlo, monospace;
    padding: .75rem; border: 1px solid var(--rule); border-radius: var(--r-lg); background: var(--surface); color: var(--ink); resize: vertical; margin: .5rem 0 .75rem; }
.library-text .text-editor textarea:focus { outline: none; border-color: var(--pine); }

/* ── Sök: messages, then the library's files (templates/search.html) */
.search-head { font-size: .9375rem; font-weight: 600; margin: 1.25rem 0 .4rem; }
.count-note { color: var(--muted); font-weight: 400; font-size: .8125rem; font-variant-numeric: tabular-nums; }
.file-hits { list-style: none; margin: 0; padding: 0; border-top: 1px solid var(--rule); }
.file-hits li { border-bottom: 1px solid var(--rule); }
.file-hits li:hover { background: var(--hover); }
.file-hits a { display: flex; gap: .6rem; align-items: flex-start; padding: .45rem .5rem; color: var(--ink); text-decoration: none; }
.file-hits .thumb { flex: none; width: 2.5rem; height: 2rem; display: flex; align-items: center; justify-content: center;
                    background: var(--rule); border-radius: var(--r); overflow: hidden; color: var(--muted); }
.file-hits .thumb img { width: 100%; height: 100%; object-fit: cover; }
.file-hits .thumb .icon { margin: 0; width: 1.2rem; height: 1.2rem; }
.file-hits .hit-text { min-width: 0; }
.file-hits .name { font-weight: 500; overflow-wrap: anywhere; }
.file-hits .where { color: var(--muted); font-size: .8125rem; }
.file-hits .snippet { display: block; color: var(--muted); font-size: .875rem; overflow-wrap: anywhere; }
.file-hits mark { background: var(--mark); color: var(--ink); border-radius: 2px; padding: 0 .1em; }
.status-head { font-size: .8125rem; font-weight: 600; color: var(--muted); margin: .25rem 0 .2rem; }
.status-library .status-what { overflow-wrap: anywhere; }

/* ── Toolbars on a phone (Viktor, 2026-10-22): the letter's actions and the
   library's toolbar become a bar at the foot of the screen, in thumb's
   reach — an icon over a short label (`data-short`), one row, no wrapping.
   The library shows the actions on ticked files only while some are
   (`.picking`, public/library.js). Wider screens keep the row above. */
.back-top { display: none; }
/* The chevron points right; Upp points up. */
[data-drop-up] .icon { transform: rotate(-90deg); }
/* The letter's move buttons share a form; as items of the row they get its gaps. */
.actions form { display: contents; }
@media (max-width: 44rem) {
    .pane:has(.toolbar) { padding-bottom: calc(4.75rem + env(safe-area-inset-bottom)); }
    .toolbar {
        position: fixed; left: 0; right: 0; bottom: 0; z-index: 20;
        display: flex; flex-wrap: nowrap; justify-content: space-around; align-items: stretch; gap: 0;
        margin: 0; padding: .2rem .25rem calc(.2rem + env(safe-area-inset-bottom));
        background: var(--surface); border-top: 1px solid var(--rule); box-shadow: 0 -2px 12px rgb(var(--shadow) / .1);
        font-size: .6875rem;
    }
    .toolbar form, .toolbar .tool-group { display: contents; }
    .toolbar .back, .toolbar .wide-only { display: none; }
    .back-top { display: inline-block; margin: 0 0 .25rem; padding: .45rem 0; font-size: .875rem; }
    .toolbar [data-short], .toolbar details.tool-menu > summary {
        flex: 1 1 0; min-width: 3.4rem; min-height: 3rem;
        display: flex; flex-direction: column; align-items: center; justify-content: center; gap: .15rem;
        padding: .3rem .15rem; margin: 0; border: 0; border-radius: var(--r); background: none;
        color: var(--ink); font-size: .6875rem; line-height: 1.15; text-align: center; text-decoration: none; white-space: nowrap;
    }
    .toolbar details.tool-menu { flex: 1 1 0; display: flex; min-width: 3.4rem; }
    .toolbar details.tool-menu > summary { flex: 1; }
    .toolbar [data-short] .label { display: none; }
    .toolbar [data-short]::after { content: attr(data-short); }
    .toolbar [data-short] .icon { width: 1.35rem; height: 1.35rem; margin: 0; color: var(--pine); opacity: 1; }
    /* Older rules colour link-styled buttons; in the bar every label is ink. */
    .toolbar [data-short][data-short] { color: var(--ink); }
    .toolbar [data-short][data-short].danger { color: var(--wax); }

    .toolbar .danger, .toolbar .danger .icon { color: var(--wax); }
    .toolbar [data-short]:active, .toolbar [open] > summary { background: var(--paper); }
    .toolbar [data-short]:disabled { opacity: .45; }
    /* A menu in the bar opens upwards. */
    .toolbar .tool-menu .menu { top: auto; bottom: calc(100% + .4rem); left: auto; right: 0; }
    .lib-toolbar:not(.picking) [data-needs-pick] > *,
    .lib-toolbar.picking .tool-group:not([data-needs-pick]):not(.paste-group) > * { display: none; }
}

/* ── The top bar on a phone (Viktor, 2026-10-22): with Bibliotek and AI
   beside Sök it no longer fit one row and wrapped unevenly. Now one row of
   even, 36 px tap targets: the wordmark left, then Skriv, the page icons
   and your initial on the right; the current page is a light square. The
   folders scroll sideways under it, without a scrollbar. On the narrowest
   phones Skriv keeps only its icon. */
@media (max-width: 44rem) {
    .rail { gap: .45rem .3rem; padding: .5rem .75rem .55rem; }
    .wordmark { margin-right: auto; padding: 0; font-size: 1.1rem; line-height: 2.25rem; }
    .write { order: 0; margin: 0; display: inline-flex; align-items: center; gap: .3rem; min-height: 2.25rem; padding: 0 .7rem; }
    .write .icon { margin: 0; }
    .rail .search-link {
        display: inline-flex; align-items: center; justify-content: center;
        min-width: 2.25rem; min-height: 2.25rem; padding: 0; margin: 0; border-radius: var(--r-lg);
    }
    .rail .search-link.current { background: var(--on-rail); color: var(--pine); border-color: var(--on-rail); }
    .rail .search-link.current .icon { color: var(--pine); }
    .account summary { min-height: 2.25rem; }
    .folders { scrollbar-width: none; scroll-snap-type: x proximity; margin-top: .1rem; }
    .folders::-webkit-scrollbar { display: none; }
    .folders li { scroll-snap-align: start; flex: none; }
    .folders a { min-height: 2.1rem; align-items: center; white-space: nowrap; }
}
@media (max-width: 24rem) {
    .write { padding: 0; min-width: 2.25rem; justify-content: center; }
    .write-label { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); }
}

/* ── The list's bulk bar (budkavle's .bulk, templates/list.html): above
   the list on a wide screen, the bar at the foot on a phone. */
.bulk .bulk-label { display: inline-flex; gap: .3rem; align-items: center; }
.bulk .bulk-label select { font: inherit; padding: .2rem; border: 1px solid var(--rule); border-radius: var(--r); background: var(--surface); color: var(--ink); max-width: 10rem; }
.bulk .bulk-clear { border: 0; }
.list-menu .select-choices { display: block; }
.list-menu .select-choices[hidden] { display: none; }
@media (max-width: 44rem) {
    .bulk.toolbar .picked, .bulk.toolbar .bulk-label { display: none; }
    .bulk.toolbar .bulk-actions { display: contents; }
    .bulk.toolbar button { border: 0; }
}

/* ── Till and Kopia typed (templates/compose.html): chips and a field on
   one wrapping line, the suggestions under it. */
.chip-line { position: relative; display: flex; flex-wrap: wrap; align-items: center; gap: .3rem; min-height: 2.25rem; padding: .2rem 0; cursor: text; }
.chip-person { display: inline-flex; align-items: center; gap: .15rem; padding: .1rem .2rem .1rem .55rem; border-radius: 999px;
               background: color-mix(in srgb, var(--pine) 10%, var(--light)); border: 1px solid color-mix(in srgb, var(--pine) 25%, var(--light)); font-size: .875rem; }
.chip-person button { border: 0; background: none; color: var(--muted); font-size: 1rem; line-height: 1; padding: 0 .3rem; cursor: pointer; border-radius: 50%; }
.chip-person button:hover { color: var(--wax); }
.chip-input { flex: 1; min-width: 8rem; border: 0; background: none; padding: .3rem 0; font: inherit; outline: none; }
.chip-input[aria-invalid="true"] { color: var(--wax); text-decoration: underline wavy var(--wax); }
.suggest { position: absolute; left: 0; top: 100%; z-index: 15; list-style: none; margin: .1rem 0 0; padding: .25rem 0; min-width: min(22rem, 100%);
           background: var(--surface); border: 1px solid var(--rule); border-radius: var(--r-lg); box-shadow: 0 4px 16px rgb(var(--shadow) / .15); }
.suggest li { padding: .4rem .75rem; cursor: pointer; }
.suggest li[aria-selected="true"], .suggest li:hover { background: var(--hover); }
.suggest small { color: var(--muted); }
#recipient-error { margin: .25rem 0 0; }
.library .pane-head .pane-tools { display: flex; gap: .4rem; }
.lib-log-list { max-height: 60vh; overflow-y: auto; }
.org-search { width: 100%; margin: .25rem 0 .5rem; padding: .45rem .6rem; font: inherit; border: 1px solid var(--rule); border-radius: var(--r-lg); background: var(--surface); }
.org-search:focus { outline: none; border-color: var(--pine); }
.org-group[hidden], .org-dialog li[hidden] { display: none; }

/* ── The rail's menu on Utkast and Papperskorg (right-click, long press) */
.folder-menu { position: fixed; bottom: auto; right: auto; z-index: 40; min-width: 14rem; font-size: .875rem; }
.folder-menu form { margin: 0; border: 0; padding: 0; }
.folder-menu form[hidden] { display: none; }
.rail [data-folder-menu] { -webkit-touch-callout: none; user-select: none; }
.status-dialog { width: min(34rem, calc(100vw - 2rem)); }
.status-queue { list-style: none; margin: .15rem 0 0; padding: 0 0 0 .75rem; border-left: 2px solid var(--rule); font-size: .8125rem; color: var(--muted); }
.status-queue li { padding: .1rem 0; border: 0; }

/* ── The icon beside the wordmark: people building a house together. */
.wordmark { display: inline-flex; align-items: center; gap: .5rem; }
.wordmark .mark { width: 2rem; height: 2rem; flex: none; }
.wordmark-large .mark { display: block; width: 5rem; height: 5rem; margin: 0 0 .5rem; }
@media (max-width: 44rem) {
    .wordmark .mark { width: 1.85rem; height: 1.85rem; }
}

/* ── Folder icons: a folder with what it holds as a badge in its corner
   (Viktor, 2026-10-22; src/library.rs, FOLDER_KINDS). */
.lib-table .dir .thumb, .folder-glyph { position: relative; }
.lib-table .dir .thumb .icon { width: 1.6rem; height: 1.6rem; }
.lib-table .thumb .badge, .folder-glyph .badge {
    position: absolute; right: 0; bottom: -.1rem; width: 1.05rem; height: 1.05rem;
    display: flex; align-items: center; justify-content: center;
    border-radius: 50%; background: var(--pine); color: var(--on-pine); box-shadow: 0 0 0 2px var(--paper);
}
.lib-table .thumb .badge .icon, .folder-glyph .badge .icon { width: .7rem; height: .7rem; margin: 0; stroke-width: 2.4; }
.icon-choices { display: grid; grid-template-columns: repeat(auto-fill, minmax(6.5rem, 1fr)); gap: .4rem; margin: 0 0 1rem; }
.icon-choices label { display: flex; flex-direction: column; align-items: center; gap: .3rem; padding: .5rem .25rem; border: 1px solid var(--rule); border-radius: var(--r-lg); cursor: pointer; font-size: .8125rem; text-align: center; }
.icon-choices label:has(input:checked) { border-color: var(--pine); background: color-mix(in srgb, var(--pine) 8%, var(--paper)); }
.icon-choices input { position: absolute; opacity: 0; width: 1px; height: 1px; }
.icon-choices label:has(input:focus-visible) { outline: 2px solid var(--pine); outline-offset: 2px; }
.folder-glyph { display: inline-flex; color: var(--pine); }
.folder-glyph > .icon { width: 2rem; height: 2rem; margin: 0; }
.folder-glyph .badge { right: -.15rem; bottom: 0; width: 1.15rem; height: 1.15rem; }

/* ── 3D previews (public/model.js) ──────────────────────────────────── */
.model-view { position: relative; width: 100%; height: 18rem; border: 1px solid var(--rule); border-radius: var(--r);
              background: var(--surface); overflow: hidden; touch-action: none; }
.model-view.large { height: min(70vh, 40rem); }
/* Full screen: the Fullscreen API where there is one, the whole window anyway. */
.model-view.model-open { position: fixed; inset: 0; z-index: 60; width: auto; height: auto; border: 0; border-radius: 0; }
.model-view:fullscreen { height: 100vh; border: 0; border-radius: 0; }
html.model-shown { overflow: hidden; }
.model-loading { position: absolute; inset: 0; display: grid; place-items: center; margin: 0; color: var(--muted); font-size: .875rem; pointer-events: none; }
.model-panel { display: none; position: absolute; top: .75rem; right: .75rem; width: min(16rem, calc(100% - 1.5rem));
               max-height: calc(100% - 1.5rem); overflow-y: auto; padding: .6rem .75rem; font-size: .875rem;
               background: var(--surface); border: 1px solid var(--rule); border-radius: var(--r); }
.model-open .model-panel { display: block; }
.model-panel-head { display: flex; justify-content: space-between; align-items: center; margin-bottom: .4rem; }
.model-panel .quiet { padding: .1rem .5rem; font-size: .8125rem; }
.model-colour { display: flex; align-items: center; gap: .5rem; margin: .3rem 0; min-width: 0; }
.model-colour input { flex: none; width: 2rem; height: 1.6rem; padding: 0; border: 1px solid var(--rule); border-radius: 4px; background: none; cursor: pointer; }
.model-colour span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.model-panel > .quiet:last-child { margin-top: .4rem; }
.model-view canvas { display: block; width: 100%; height: 100%; cursor: grab; }
.model-view canvas:active { cursor: grabbing; }
.model-view.model-failed { display: grid; place-items: center; height: auto; padding: 1rem; color: var(--muted); }
.model-hint { margin: .3rem 0 .6rem; font-size: .8125rem; color: var(--muted); }
.model-hint .model-full { padding: .1rem .5rem; font-size: .8125rem; }
.files .preview.model { width: min(100%, 28rem); }

/* The rail's label menu (templates/app.html): the deletes apart, below. */
.label-menu .stack { margin: .5rem 0 1rem; }
.label-menu .label-menu-delete { display: flex; flex-wrap: wrap; gap: .5rem; margin: 1rem 0 0; padding-top: .75rem; border-top: 1px solid var(--rule); }
