/* OBSCURA OS: Keep.

   One window, built as Case is: the bar across the top with Keep's six
   screens, and the screen under it. Items is a working surface that does
   not scroll as a page: the filters on the left, the list, and the item on
   the right. The other screens are pages that scroll. On a phone the
   filters become a menu over the list, and an item opens in place of the
   list with a Back button; every control is at least 44px.

   Every colour, size, corner and duration is a theme.css token, so Keep
   follows the colourway, the dark mode and the motion setting the rest of
   the site does. Numbers that are read down a column (dates, counts,
   codes) are set in tabular figures. */

body.kp-app { margin: 0; height: 100vh; height: 100dvh; overflow: hidden; background: var(--paper); color: var(--ink); font: var(--text-sm)/var(--leading-ui) var(--font-sans); }
.kp *, .kp *::before, .kp *::after { box-sizing: border-box; }
/* At no weight, so a button's own class decides its colour and weight:
   at one class's weight this reset outranked .kp-btn-main, and the
   main button was ink on the accent, unreadable in the default colourway. */
:where(.kp) :where(button, input, select, textarea) { font: inherit; color: inherit; }
.kp-sprite { position: absolute; width: 0; height: 0; overflow: hidden; }
.kp-ico { width: 18px; height: 18px; flex: none; fill: none; stroke: currentColor; stroke-width: var(--icon-stroke); stroke-linecap: round; stroke-linejoin: round; }
.kp-sr { position: absolute !important; width: 1px; height: 1px; margin: -1px; padding: 0; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0; }
.kp-grow { flex: 1; }
.kp code, .kp kbd { font: var(--text-xs) var(--font-mono); padding: 1px var(--space-1); border-radius: var(--radius-sm); background: var(--paper-inset); }
.kp kbd { border: 1px solid var(--rule-strong); border-bottom-width: 2px; }
.kp-mono { font-family: var(--font-mono); font-variant-numeric: tabular-nums; }
.kp-num { text-align: right; font-variant-numeric: tabular-nums; white-space: nowrap; }
.kp-clock { font-variant-numeric: tabular-nums; font-weight: 600; color: var(--ink); }

.kp { height: 100vh; height: 100dvh; display: grid; grid-template-rows: auto auto minmax(0, 1fr); }

/* ---------------------------------------------------------------- top bar */

.kp-top { display: flex; align-items: center; gap: var(--space-2); min-width: 0; padding: 6px 10px; background: var(--paper-raised); border-bottom: 1px solid var(--rule); }
.kp-home { display: inline-flex; align-items: center; justify-content: center; flex: none; width: 36px; height: 36px; border-radius: var(--radius-md); }
.kp-home:hover { background: var(--paper-inset); }
.kp-home img { display: block; }
.kp-brand { margin: 0 var(--space-1) 0 0; font-size: var(--text-md); font-weight: 650; letter-spacing: -.01em; white-space: nowrap; max-width: 26ch; overflow: hidden; text-overflow: ellipsis; }
.kp-tabs { display: flex; gap: 2px; min-width: 0; padding: 2px; border: 1px solid var(--rule); border-radius: var(--radius-pill); background: var(--paper-inset); overflow-x: auto; scrollbar-width: none; }
.kp-tabs[hidden] { display: none; }
.kp-tabs::-webkit-scrollbar { display: none; }
.kp-tabs button { flex: none; min-height: 30px; padding: 0 var(--space-3); border: 0; border-radius: var(--radius-pill); background: transparent; color: var(--ink-soft); font-size: var(--text-xs); font-weight: 600; white-space: nowrap; cursor: pointer; transition: background-color var(--dur-2) var(--ease-standard), color var(--dur-2) var(--ease-standard); }
.kp-tabs button:hover { color: var(--ink); }
.kp-tabs button[aria-current="page"] { background: var(--paper-raised); color: var(--ink); box-shadow: 0 0 0 1px var(--rule), 0 1px 2px rgba(0, 0, 0, .08); }
.kp-state { margin: 0; max-width: 24ch; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-size: var(--text-xs); color: var(--ink-faint); }
.kp-state[data-save-state="failed"] { color: var(--danger); font-weight: 600; }
.kp-menuwrap { position: relative; }
/* A menu comes down the last few pixels from its button on the theme's
   own distance (os-menu-in, theme.css), a fade with motion switched down. */
.kp-menu { --os-fade: var(--dur-fade); position: absolute; z-index: 50; top: calc(100% + var(--space-1)); left: 0; min-width: 260px; max-width: min(340px, calc(100vw - 20px)); padding: 6px; border-radius: var(--radius-lg); background: var(--paper-raised); box-shadow: 0 0 0 1px var(--rule), 0 14px 36px rgba(16, 16, 24, .18); animation: os-menu-in var(--dur-3) var(--ease-standard) backwards; }
.kp-menu-right { left: auto; right: 0; }
.kp-menu[hidden] { display: none; }
.kp-menu button { display: flex; width: 100%; align-items: baseline; justify-content: space-between; gap: var(--space-3); min-height: 36px; padding: var(--space-2) 11px; border: 0; border-radius: var(--radius-sm); background: transparent; text-align: left; cursor: pointer; }
.kp-menu button:hover, .kp-menu button:focus-visible { background: var(--paper-inset); outline: none; }
.kp-menu button span { font-size: var(--text-2xs); color: var(--ink-faint); }
.kp-menu hr { margin: 6px var(--space-1); border: 0; border-top: 1px solid var(--rule); }


/* ---------------------------------------------------------------- controls */

.kp-btn { display: inline-flex; align-items: center; justify-content: center; gap: 6px; min-height: 36px; padding: 6px 14px; border: 1px solid var(--rule-strong); border-radius: var(--radius-md); background: var(--paper-raised); color: var(--ink); font-weight: 600; white-space: nowrap; cursor: pointer; text-decoration: none; transition: background-color var(--dur-2) var(--ease-standard), border-color var(--dur-2) var(--ease-standard); }
.kp-btn:hover:not(:disabled) { background: var(--paper-inset); }
.kp-btn:active:not(:disabled) { transform: translateY(1px); }
.kp-btn:disabled { opacity: .5; cursor: default; }
.kp-btn[hidden] { display: none; }
.kp-btn .kp-ico { width: 16px; height: 16px; }
.kp-btn-main { border-color: var(--accent); background: var(--accent); color: var(--on-accent); }
.kp-btn-main:hover:not(:disabled) { background: var(--accent-strong); }
.kp-btn-danger { border-color: var(--danger); background: var(--danger); color: var(--on-danger, var(--on-accent)); }
.kp-btn-danger:hover:not(:disabled) { background: var(--danger); filter: brightness(.92); }
.kp-btn-quiet { border-color: transparent; background: transparent; color: var(--ink-soft); }
.kp-btn-quiet:hover:not(:disabled) { color: var(--danger); }
.kp-btn[aria-pressed="true"] .kp-ico { fill: currentColor; color: var(--warn); }
.kp-icon-btn { display: inline-flex; align-items: center; justify-content: center; flex: none; width: 36px; height: 36px; padding: 0; border: 0; border-radius: var(--radius-md); background: transparent; color: var(--ink-soft); cursor: pointer; }
.kp-icon-btn:hover { background: var(--paper-inset); color: var(--ink); }
.kp-link { min-height: 32px; padding: 0; border: 0; background: none; color: var(--accent-strong); font-size: inherit; font-weight: 600; text-align: left; cursor: pointer; }
.kp-link:hover { text-decoration: underline; }
.kp-link-ink { color: var(--ink); font-weight: 600; }
.kp-link-quiet { color: var(--ink-faint); font-weight: 400; }
.kp-mini { flex: none; min-height: 28px; padding: 2px 9px; border: 1px solid var(--rule); border-radius: var(--radius-sm); background: var(--paper-raised); color: var(--ink-soft); font-size: var(--text-2xs); font-weight: 600; cursor: pointer; }
.kp-mini:hover { background: var(--paper-inset); color: var(--ink); }
.kp :is(button, a, input, select, textarea, summary, [tabindex]):focus-visible { outline: 2px solid var(--focus, var(--accent)); outline-offset: 1px; }
.kp-row { display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-2); margin: var(--space-3) 0 0; }
.kp-row-tight { margin-top: var(--space-1); gap: var(--space-1) var(--space-3); }

.kp-field { display: flex; flex-direction: column; gap: var(--space-1); min-width: 0; margin: 0 0 var(--space-3); font-size: var(--text-xs); color: var(--ink-soft); }
.kp-field[hidden] { display: none; }
.kp-field > span:first-child { font-weight: 600; }
.kp-field-inline { flex-direction: row; align-items: center; gap: var(--space-2); margin: 0; }
.kp input:not([type="checkbox"]):not([type="radio"]):not([type="file"]):not([type="range"]), .kp select, .kp textarea { width: 100%; min-height: 36px; padding: 6px var(--space-2); border: 1px solid var(--rule-strong); border-radius: var(--radius-md); background: var(--paper); color: var(--ink); font-size: var(--text-sm); }
.kp textarea { resize: vertical; line-height: 1.5; }
.kp input:focus, .kp select:focus, .kp textarea:focus { border-color: var(--accent); outline: 2px solid var(--accent-border); outline-offset: 0; }
.kp-field-inline select { width: auto; }
.kp input[type="range"] { width: 100%; accent-color: var(--accent); }
.kp-mono-in { font-family: var(--font-mono) !important; font-size: var(--text-xs) !important; letter-spacing: .02em; }
.kp-prose { font-family: var(--font-sans); }
.kp-check { display: inline-flex; align-items: center; gap: 6px; min-height: 36px; font-size: var(--text-xs); color: var(--ink-soft); cursor: pointer; }
.kp-check input { width: 18px; height: 18px; flex: none; accent-color: var(--accent); }
.kp-pwrow { display: flex; align-items: center; gap: var(--space-1); }
.kp-pwrow input { flex: 1; min-width: 0; }
.kp-grid2 { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 0 var(--space-3); }
.kp-grid3 { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 0 var(--space-3); }
.kp-span2 { grid-column: 1 / -1; }
.kp-fs { min-width: 0; margin: 0 0 var(--space-3); padding: 0; border: 0; }
.kp-fs legend { margin: 0 0 var(--space-2); padding: 0; font-size: var(--text-xs); font-weight: 650; color: var(--ink-soft); }
.kp-remind { font-style: normal; font-weight: 400; color: var(--ink-faint); }
.kp-hint { margin: var(--space-1) 0 var(--space-2); font-size: var(--text-xs); line-height: 1.5; color: var(--ink-faint); }
/* A button in a line of hint keeps its touch height without stretching the
   line it sits in: the floor is laid over the text above and below it. */
.kp-hint .kp-link { display: inline-flex; align-items: center; min-height: 44px; margin-block: -14px; vertical-align: baseline; }
.kp-hint-inline { font-size: var(--text-2xs); font-weight: 400; color: var(--ink-faint); }
.kp-bad { margin: 0; font-size: var(--text-xs); color: var(--danger); }
.kp-bad:empty { display: none; }
.kp-bad-text { color: var(--danger); font-weight: 600; }
.kp-note { margin: 0 0 var(--space-4); padding: var(--space-2) var(--space-3); border-left: 3px solid var(--accent); background: var(--accent-soft); font-size: var(--text-sm); }
/* Try an example (keep-app.js): the line under the gate's two cards, and
   the line above an example while it is open. */
.kp-gate-example { margin: var(--space-3) 0 0; }
.kp-example-note { margin: var(--space-2) var(--space-2) 0; }
@media (max-width: 480px) { .kp-brand-more { display: none; } }
.kp-empty { margin: var(--space-6) var(--space-4); color: var(--ink-faint); }
.kp-scroll { overflow-x: auto; }

.kp-meter { display: flex; align-items: flex-start; gap: var(--space-2); margin: calc(var(--space-2) * -1) 0 var(--space-3); }
.kp-meter-track { flex: 0 0 120px; height: 4px; margin-top: 6px; border-radius: var(--radius-pill); background: var(--paper-inset); overflow: hidden; }
/* The bar is drawn full and scaled to the fraction (keep-app.js sets
   --kp-meter, nought to one), so it eases to each new reading without
   laying the row out again. */
.kp-meter-bar { display: block; width: 100%; height: 100%; background: var(--danger); transform-origin: left; scale: var(--kp-meter, 0) 1; transition: scale var(--dur-3) var(--ease-standard), background-color var(--dur-2) var(--ease-standard); }
.kp-meter[data-score="2"] .kp-meter-bar { background: var(--warn); }
.kp-meter[data-score="3"] .kp-meter-bar, .kp-meter[data-score="4"] .kp-meter-bar { background: var(--good); }
.kp-meter-say { flex: 1; min-width: 0; font-size: var(--text-2xs); line-height: 1.45; color: var(--ink-faint); }

/* The clipboard's countdown, in the bar while something Keep copied is on
   it: pressing it clears the clipboard at once. The rule under it shortens
   as the seconds go, easing from one second's mark to the next rather
   than stepping; the bar itself lands when something is copied and goes
   when the clipboard is clear. */
.kp-clip { --os-fade: var(--dur-fade); position: relative; overflow: hidden; gap: 6px; font-weight: 500; color: var(--ink-soft); font-variant-numeric: tabular-nums; animation: os-pop var(--dur-3) var(--ease-spring) backwards; }
.kp-clip b { min-width: 2.6em; font-weight: 650; color: var(--ink); text-align: left; }
.kp-clip::after { content: ""; position: absolute; left: 0; bottom: 0; width: 100%; height: 2px; background: var(--accent); transform-origin: left; scale: var(--kp-clip, 1) 1; transition: scale var(--dur-4) var(--ease-standard); }

/* ---------------------------------------------------------------- screens */

.kp-main { position: relative; min-height: 0; overflow: hidden; }
.kp-boot { margin: var(--space-6); color: var(--ink-faint); }
.kp-boot[hidden], .kp-view[hidden] { display: none !important; }
/* A screen arrives on the theme's distance, and fades alone with motion
   switched down. */
.kp-page { --os-fade: var(--dur-fade); height: 100%; overflow-y: auto; padding: var(--space-5) max(var(--space-5), calc((100% - 1120px) / 2)) var(--space-7); animation: os-rise-soft var(--dur-4) var(--ease-standard) backwards; }
.kp-h { margin: 0 0 var(--space-2); font: 650 var(--text-2xl)/1.15 var(--font-headline); letter-spacing: -.01em; }
.kp-lead { max-width: var(--measure); margin: 0 0 var(--space-5); font-size: var(--text-md); line-height: var(--leading-prose); color: var(--ink-soft); }
/* A second line under the lead, closer to it than the lead is to what follows. */
.kp-lead + .kp-lead-also { margin-top: calc(var(--space-5) * -0.6); }
.kp-headrow { display: flex; flex-wrap: wrap; align-items: flex-start; justify-content: space-between; gap: var(--space-3); }
.kp-headrow .kp-btn { margin-top: var(--space-1); }
.kp-sec-h { display: flex; align-items: center; gap: var(--space-2); margin: var(--space-5) 0 var(--space-2); font-size: var(--text-2xs); font-weight: 650; letter-spacing: .06em; text-transform: uppercase; color: var(--ink-faint); }
.kp-cards { display: grid; grid-template-columns: repeat(auto-fit, minmax(260px, 1fr)); gap: var(--space-3); }
.kp-card, .kp-panel { padding: var(--space-4); border-radius: var(--radius-lg); background: var(--paper-raised); box-shadow: 0 0 0 1px var(--rule); }
.kp-card { display: flex; flex-direction: column; align-items: flex-start; gap: var(--space-2); }
.kp-card h3, .kp-panel h3 { margin: 0 0 var(--space-2); font-size: var(--text-md); font-weight: 650; }
.kp-card p, .kp-panel p { margin: 0 0 var(--space-2); color: var(--ink-soft); line-height: 1.5; }
.kp-card .kp-field { width: 100%; }
.kp-card > .kp-btn { margin-top: auto; }
.kp-panel { margin: 0 0 var(--space-3); }
.kp-cols { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--space-3); align-items: start; }
.kp-cols > .kp-panel { margin: 0; }

/* The gate */
.kp-gate, .kp-gate-wait { max-width: 1120px; }
.kp-unlock { max-width: 460px; }
.kp-unlock .kp-row { margin-top: var(--space-2); gap: var(--space-4); }
.kp-gate-more { margin-top: var(--space-4); }
.kp-gate-foot { max-width: var(--measure); margin-top: var(--space-5); }

/* ---------------------------------------------------------------- Items */

.kp-items { display: grid; grid-template-columns: 220px minmax(300px, 34%) minmax(0, 1fr); min-height: 0; height: 100%; }
.kp-filters { overflow-y: auto; min-height: 0; padding: var(--space-3) var(--space-2) var(--space-6); border-right: 1px solid var(--rule); background: var(--paper); }
.kp-side-h { margin: var(--space-4) 0 var(--space-1); padding: 0 var(--space-2); font-size: var(--text-2xs); font-weight: 650; letter-spacing: .06em; text-transform: uppercase; color: var(--ink-faint); }
.kp-filter { display: flex; width: 100%; align-items: center; gap: var(--space-2); min-height: 32px; padding: 4px var(--space-2); border: 0; border-radius: var(--radius-sm); background: transparent; color: var(--ink-soft); text-align: left; cursor: pointer; }
.kp-filter:hover { background: var(--paper-inset); color: var(--ink); }
.kp-filter[aria-current="true"] { background: var(--accent-soft); color: var(--ink); font-weight: 600; }
.kp-filter .kp-ico { width: 16px; height: 16px; color: var(--ink-faint); }
.kp-filter-name { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.kp-filter-n { font-size: var(--text-2xs); font-variant-numeric: tabular-nums; color: var(--ink-faint); font-weight: 400; }

.kp-listpane { display: flex; flex-direction: column; min-height: 0; border-right: 1px solid var(--rule); background: var(--paper-raised); }
.kp-search { position: relative; padding: var(--space-2) var(--space-3); border-bottom: 1px solid var(--rule); }
.kp-search-ico { position: absolute; left: calc(var(--space-3) + 9px); top: 50%; width: 16px; height: 16px; transform: translateY(-50%); color: var(--ink-faint); pointer-events: none; fill: none; stroke: currentColor; stroke-width: var(--icon-stroke); }
.kp-search input { padding-left: 32px !important; }
.kp-listbar { display: flex; align-items: center; gap: var(--space-2); padding: var(--space-1) var(--space-3); border-bottom: 1px solid var(--rule); }
.kp-filter-sel { display: none; }
.kp-count { flex: 1; margin: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-size: var(--text-xs); color: var(--ink-faint); }
.kp-list { flex: 1; overflow-y: auto; min-height: 0; margin: 0; padding: 0; list-style: none; }
.kp-item { display: grid; grid-template-columns: auto minmax(0, 1fr) auto; align-items: center; column-gap: var(--space-3); min-height: 58px; padding: 6px var(--space-3); border-bottom: 1px solid var(--rule); cursor: pointer; }
.kp-item:hover { background: var(--paper-inset); }
.kp-item[aria-selected="true"] { background: var(--accent-soft); }
.kp-item:focus-visible { outline: 2px solid var(--accent); outline-offset: -2px; }
.kp-row-ico { display: grid; place-items: center; width: 34px; height: 34px; overflow: hidden; border-radius: var(--radius-sm); background: var(--paper-inset); color: var(--ink-soft); }
.kp-row-ico .kp-ico { width: 17px; height: 17px; }
.kp-thumb { display: block; width: 100%; height: 100%; object-fit: cover; }
.kp-row-main { display: flex; flex-direction: column; gap: 1px; min-width: 0; }
.kp-row-title { display: flex; align-items: center; gap: 4px; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-weight: 600; }
.kp-fav-mark { width: 13px; height: 13px; fill: currentColor; color: var(--warn); }
.kp-row-sub { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-size: var(--text-xs); color: var(--ink-faint); }
.kp-row-when { font-size: var(--text-2xs); font-variant-numeric: tabular-nums; color: var(--ink-faint); white-space: nowrap; }
.kp-row-when.is-soon, .kp-rel.is-soon { color: var(--warn); font-weight: 600; }
.kp-row-when.is-gone, .kp-rel.is-gone { color: var(--danger); font-weight: 600; }
.kp-empty-row { padding: var(--space-5) var(--space-4); color: var(--ink-faint); line-height: 1.5; }
.kp-empty-row p { margin: 0 0 var(--space-3); }
.kp-empty-row .kp-btn { min-height: 44px; white-space: normal; text-align: left; }

.kp-detail { overflow-y: auto; min-height: 0; min-width: 0; background: var(--paper); outline: none; }
.kp-detail-in { max-width: 760px; padding: var(--space-4) var(--space-5) var(--space-7); }
.kp-detail-empty { padding: var(--space-6) var(--space-5); color: var(--ink-faint); }
.kp-detail-empty p { margin: 0 0 var(--space-2); }
.kp-detail-top { display: none; margin-bottom: var(--space-3); }
.kp-dhead { display: flex; align-items: flex-start; gap: var(--space-3); }
.kp-dhead-ico { display: grid; place-items: center; flex: none; width: 40px; height: 40px; border-radius: var(--radius-md); background: var(--paper-inset); color: var(--ink-soft); }
.kp-dhead-main { min-width: 0; }
.kp-dtitle { margin: 0; font-size: var(--text-xl); line-height: 1.25; overflow-wrap: anywhere; }
.kp-dmeta { margin: 2px 0 0; font-size: var(--text-xs); color: var(--ink-faint); }
.kp-tags { display: flex; flex-wrap: wrap; gap: var(--space-1); margin: var(--space-2) 0 0; }
.kp-tag { min-height: 24px; padding: 0 8px; border: 1px solid var(--rule); border-radius: var(--radius-sm); background: var(--paper-raised); color: var(--ink-soft); font-size: var(--text-2xs); cursor: pointer; }
.kp-tag:hover { border-color: var(--rule-strong); color: var(--ink); }
.kp-actions { display: flex; flex-wrap: wrap; gap: var(--space-2); margin: var(--space-3) 0 var(--space-4); padding-bottom: var(--space-3); border-bottom: 1px solid var(--rule); }

.kp-dl { margin: 0 0 var(--space-3); }
.kp-dl-row { display: grid; grid-template-columns: minmax(130px, 34%) minmax(0, 1fr); gap: var(--space-3); align-items: baseline; padding: 8px 0; border-bottom: 1px solid var(--rule); }
.kp-dl dt { font-size: var(--text-xs); color: var(--ink-faint); }
.kp-dl dd { display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-1) var(--space-2); min-width: 0; margin: 0; overflow-wrap: anywhere; }
.kp-val { min-width: 0; overflow-wrap: anywhere; }
.kp-copyable, .kp-secret { display: inline-flex; flex-wrap: wrap; align-items: center; gap: var(--space-1) var(--space-2); min-width: 0; }
.kp-secret-val { letter-spacing: .04em; overflow-wrap: anywhere; }
.kp-date { font-variant-numeric: tabular-nums; }
.kp-rel { font-size: var(--text-xs); color: var(--ink-faint); }
.kp-pre, .kp-notebody { white-space: pre-wrap; overflow-wrap: anywhere; line-height: 1.55; }
.kp-notebody { max-width: var(--measure); margin: 0 0 var(--space-3); }
.kp-url { color: var(--accent-strong); overflow-wrap: anywhere; }
.kp-strength { font-size: var(--text-2xs); font-weight: 600; color: var(--danger); }
.kp-strength[data-score="2"] { color: var(--warn); }
.kp-strength[data-score="3"], .kp-strength[data-score="4"] { color: var(--good); }
.kp-code-inline { display: inline-flex; align-items: center; gap: var(--space-2); }
.kp-code-inline .kp-code-num { font-size: var(--text-md); font-weight: 600; }
.kp-stamp { margin: var(--space-5) 0 0; font-size: var(--text-2xs); color: var(--ink-faint); }
.kp-history { margin: 0 0 var(--space-3); }
.kp-history summary, .kp-adv summary { min-height: 32px; padding: 6px 0; font-size: var(--text-xs); font-weight: 600; color: var(--ink-soft); cursor: pointer; }

.kp-bigcode { display: grid; grid-template-columns: minmax(0, 1fr) auto; grid-template-rows: auto auto; gap: var(--space-2) var(--space-4); align-items: center; margin: 0 0 var(--space-4); padding: var(--space-4); border-radius: var(--radius-lg); background: var(--paper-raised); box-shadow: 0 0 0 1px var(--rule); }
.kp-bigcode .kp-code-num { font-size: 2.25rem; font-weight: 600; letter-spacing: .04em; }
.kp-bigcode .kp-btn { grid-row: 1; grid-column: 2; }
.kp-bigcode .kp-code-left { grid-column: 1 / -1; }
.kp-code-left { display: block; height: 3px; border-radius: var(--radius-pill); background: var(--paper-inset); overflow: hidden; }
/* A counter-based code has no time running out. */
[data-kind="hotp"] .kp-code-left { visibility: hidden; }
/* The time left runs out by transform, a second's mark eased to the next
   (keep-app.js sets --kp-left, nought to one, once a second); at the
   turn of a period it fills again and the new code fades in over the old. */
.kp-code-bar { display: block; width: 100%; height: 100%; background: var(--accent); transform-origin: left; scale: var(--kp-left, 1) 1; transition: scale var(--dur-4) var(--ease-standard), background-color var(--dur-2) var(--ease-standard); }
.kp-code-num.is-fresh { --os-fade: var(--dur-fade); animation: os-fade-in var(--dur-3) var(--ease-standard) backwards; }
[data-low="true"] .kp-code-bar { background: var(--warn); }
[data-low="true"] .kp-code-num { color: var(--warn); }

.kp-files { display: grid; grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); gap: var(--space-2); margin: 0 0 var(--space-2); padding: 0; list-style: none; }
.kp-file { position: relative; }
.kp-file-open { display: flex; flex-direction: column; align-items: stretch; width: 100%; padding: 0 0 var(--space-2); border: 0; border-radius: var(--radius-md); background: var(--paper-raised); box-shadow: 0 0 0 1px var(--rule); text-align: left; cursor: pointer; overflow: hidden; }
.kp-file-open:hover { box-shadow: 0 0 0 1px var(--rule-strong); }
.kp-file-th { display: grid; place-items: center; height: 110px; margin-bottom: var(--space-2); background: var(--paper-inset); color: var(--ink-faint); overflow: hidden; }
.kp-file-th .kp-ico { width: 28px; height: 28px; }
.kp-file-th .kp-thumb { object-fit: cover; object-position: top; }
.kp-file-name { padding: 0 var(--space-2); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-size: var(--text-xs); font-weight: 600; }
.kp-file-meta { padding: 0 var(--space-2); font-size: var(--text-2xs); color: var(--ink-faint); }
.kp-file .kp-icon-btn { position: absolute; top: 4px; right: 4px; width: 32px; height: 32px; background: var(--paper-raised); box-shadow: 0 0 0 1px var(--rule); opacity: 0; transition: opacity var(--dur-2) var(--ease-standard), background-color var(--dur-2) var(--ease-standard), color var(--dur-2) var(--ease-standard); }
.kp-file:hover .kp-icon-btn, .kp-file .kp-icon-btn:focus-visible { opacity: 1; }
.kp.is-drop .kp-main { outline: 2px dashed var(--accent); outline-offset: -8px; }

/* ---------------------------------------------------------------- tables, codes, dates, health */

.kp-pagein { max-width: 1120px; }
.kp-table { width: 100%; border-collapse: collapse; font-size: var(--text-sm); }
.kp-table th { padding: 6px var(--space-2); border-bottom: 1px solid var(--rule-strong); font-size: var(--text-2xs); font-weight: 650; letter-spacing: .04em; text-align: left; text-transform: uppercase; color: var(--ink-faint); }
.kp-table td { padding: 7px var(--space-2); border-bottom: 1px solid var(--rule); vertical-align: middle; }
.kp-table th.kp-num, .kp-table td.kp-num { text-align: right; }
.kp-dates-t { table-layout: fixed; }
.kp-dates-t th:nth-child(1) { width: 9.5em; }
.kp-dates-t th:nth-child(2) { width: 38%; }
.kp-dates-t th:nth-child(4) { width: 9em; }
.kp-dates-t td { overflow: hidden; text-overflow: ellipsis; }
.kp-dates-sub { display: none; font-size: var(--text-xs); color: var(--ink-faint); }
.kp-keys td:first-child { width: 9em; white-space: nowrap; }
.kp-notify { max-width: 760px; }
.kp-notify .kp-hint { margin-bottom: 0; }

.kp-codes { margin: 0; padding: 0; list-style: none; border-top: 1px solid var(--rule); }
.kp-coderow { display: grid; grid-template-columns: minmax(0, 1fr) auto 3.5em auto; grid-template-rows: auto auto; align-items: center; gap: 4px var(--space-4); padding: var(--space-3) 0; border-bottom: 1px solid var(--rule); }
.kp-coderow-name { display: flex; flex-direction: column; min-width: 0; }
.kp-coderow-name b, .kp-coderow-name span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.kp-coderow-name span { font-size: var(--text-xs); color: var(--ink-faint); }
.kp-coderow .kp-code-num { font-size: var(--text-xl); font-weight: 600; letter-spacing: .04em; }
.kp-code-secs { font-size: var(--text-xs); color: var(--ink-faint); }
.kp-coderow .kp-code-left { grid-column: 1 / -1; grid-row: 2; }
.kp-coderow-acts { display: flex; align-items: center; gap: var(--space-1); }

.kp-hrow { display: grid; grid-template-columns: auto minmax(0, 1fr); gap: var(--space-3); padding: var(--space-3) 0; border-bottom: 1px solid var(--rule); }
.kp-hrow:first-of-type { border-top: 1px solid var(--rule); }
.kp-hmark { display: grid; place-items: center; width: 28px; height: 28px; border-radius: 50%; background: var(--paper-inset); color: var(--ink-faint); }
.kp-hmark .kp-ico { width: 16px; height: 16px; }
.kp-hrow[data-state="good"] .kp-hmark { background: var(--good-soft); color: var(--good); }
.kp-hrow[data-state="bad"] .kp-hmark { background: var(--danger-soft); color: var(--danger); }
.kp-hrow[data-state="todo"] .kp-hmark { background: var(--warn-soft); color: var(--warn); }
.kp-hmain h3 { margin: 3px 0 var(--space-1); font-size: var(--text-md); }
.kp-hmain p { max-width: var(--measure); margin: 0 0 var(--space-2); color: var(--ink-soft); line-height: 1.5; }
.kp-hlist { max-width: 760px; margin: 0 0 var(--space-2); padding: 0; list-style: none; columns: 2 240px; column-gap: var(--space-5); }
.kp-hlist li { break-inside: avoid; padding: 1px 0; }
/* The passwords to change: one row each, what is wrong under its name, the
   button that makes a new one on the right. */
.kp-fixlist { max-width: 860px; margin: var(--space-2) 0 var(--space-3); padding: 0; list-style: none; border-top: 1px solid var(--rule); }
.kp-fixrow { display: grid; grid-template-columns: minmax(0, 1fr) auto; align-items: center; gap: var(--space-2) var(--space-4); padding: var(--space-2) 0; border-bottom: 1px solid var(--rule); }
.kp-fixmain { min-width: 0; }
.kp-fixmain > .kp-link { min-height: 28px; overflow-wrap: anywhere; }
.kp-fixmain > .kp-hint-inline { margin-left: var(--space-2); overflow-wrap: anywhere; }
.kp-why { margin: 2px 0 0; padding: 0; list-style: none; font-size: var(--text-xs); line-height: 1.5; color: var(--ink-soft); }
.kp-why li.is-bad { color: var(--danger); font-weight: 600; }
.kp-howstrong { max-width: var(--measure); }
.kp-howstrong p { font-size: var(--text-xs); }
.kp-crack { flex-basis: 100%; }
.kp-fixnote { font-size: var(--text-xs); line-height: 1.5; }
.kp-row-sec { margin: 0 0 var(--space-4); }

/* ---------------------------------------------------------------- legacy, sync */

.kp-picklist { max-height: 300px; overflow-y: auto; border: 1px solid var(--rule); border-radius: var(--radius-md); background: var(--paper); }
.kp-pick { display: grid; grid-template-columns: auto minmax(0, 1fr) auto; align-items: center; gap: var(--space-2); min-height: 38px; padding: 4px var(--space-2); border-bottom: 1px solid var(--rule); cursor: pointer; }
.kp-pick:last-child { border-bottom: 0; }
.kp-pick input { width: 18px; height: 18px; accent-color: var(--accent); }
.kp-pick-name { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.kp-pick-sub { font-size: var(--text-2xs); color: var(--ink-faint); white-space: nowrap; }
/* Files handed in by another application, before they are filed. */
.kp-files-in { margin: 0 0 var(--space-3); padding: 0; list-style: none; font-size: var(--text-xs); }
.kp-files-in li { padding: 2px 0; overflow-wrap: anywhere; }
.kp-files-in span { color: var(--ink-faint); font-variant-numeric: tabular-nums; }
.kp-done { margin-top: var(--space-3); padding-top: var(--space-3); border-top: 1px solid var(--rule); }
.kp-folder p { margin: 0 0 var(--space-2); }
.kp-mergelist { margin: 0; padding-left: 1.1em; line-height: 1.55; }
.kp-merge { margin-top: var(--space-3); border-left: 3px solid var(--accent); }

/* ---------------------------------------------------------------- dialogs */

.kp-dialog { width: min(520px, calc(100vw - 24px)); max-height: calc(100dvh - 24px); padding: 0; border: 0; border-radius: var(--radius-lg); background: var(--paper-raised); color: var(--ink); box-shadow: 0 0 0 1px var(--rule), 0 24px 60px rgba(0, 0, 0, .3); }
.kp-dialog-wide { width: min(760px, calc(100vw - 24px)); }
.kp-dialog::backdrop, .kp-viewer::backdrop { background: rgba(10, 10, 16, .45); }
.kp-dlg-form { display: grid; grid-template-rows: auto minmax(0, 1fr); max-height: calc(100dvh - 24px); margin: 0; }
.kp-dlg-head { display: flex; align-items: center; gap: var(--space-2); padding: var(--space-3) var(--space-3) var(--space-2) var(--space-5); border-bottom: 1px solid var(--rule); }
.kp-dlg-title { flex: 1; min-width: 0; margin: 0; font-size: var(--text-lg); overflow-wrap: anywhere; }
.kp-dlg-body { overflow-y: auto; padding: var(--space-4) var(--space-5) var(--space-5); }
.kp-dlg-body > p { margin: 0 0 var(--space-3); color: var(--ink-soft); line-height: 1.5; }
.kp-dlg-foot { display: flex; flex-wrap: wrap; justify-content: flex-end; gap: var(--space-2); margin-top: var(--space-4); }
.kp-tpls { display: grid; grid-template-columns: repeat(auto-fill, minmax(200px, 1fr)); gap: var(--space-2); }
.kp-tpl { display: flex; flex-direction: column; align-items: flex-start; gap: 2px; min-height: 56px; padding: var(--space-2) var(--space-3); border: 1px solid var(--rule); border-radius: var(--radius-md); background: var(--paper); text-align: left; cursor: pointer; }
.kp-tpl:hover { border-color: var(--rule-strong); background: var(--paper-inset); }
.kp-tpl span { font-size: var(--text-2xs); color: var(--ink-faint); }
.kp-daterow { display: grid; grid-template-columns: minmax(0, 1fr) 11em 11em auto; gap: var(--space-2); margin-bottom: var(--space-2); }
.kp-seg { display: inline-flex; gap: 2px; margin-bottom: var(--space-3); padding: 2px; border: 1px solid var(--rule); border-radius: var(--radius-md); background: var(--paper-inset); }
.kp-seg button { min-height: 30px; padding: 0 var(--space-3); border: 0; border-radius: var(--radius-sm); background: transparent; color: var(--ink-soft); font-size: var(--text-xs); font-weight: 600; cursor: pointer; }
.kp-seg button[aria-selected="true"] { background: var(--paper-raised); color: var(--ink); box-shadow: 0 0 0 1px var(--rule); }
.kp-genout { display: block; min-height: 2.6em; padding: var(--space-3); border: 1px solid var(--rule-strong); border-radius: var(--radius-md); background: var(--paper); font-size: var(--text-md); overflow-wrap: anywhere; user-select: all; }
.kp-codecheck { min-height: 1.4em; font-size: var(--text-xs); color: var(--ink-soft); }
.kp-reckey { margin: 0 0 var(--space-2); padding: var(--space-3); border: 1px solid var(--rule-strong); border-radius: var(--radius-md); background: var(--paper); font-size: var(--text-md); font-weight: 600; letter-spacing: .03em; overflow-wrap: anywhere; user-select: all; }
/* A QR code: dark on a light ground in either theme, as a camera reads it,
   at a size a phone held at arm's length can take in. */
.kp-qr { display: flex; justify-content: center; margin: 0 0 var(--space-3); }
.kp-qr-svg { display: block; width: min(300px, 100%); height: auto; aspect-ratio: 1; border-radius: var(--radius-sm); box-shadow: 0 0 0 1px var(--rule); }
.kp-qr-left { margin: 0 0 var(--space-3); text-align: center; font-size: var(--text-sm); color: var(--ink-soft); }
.kp-qr-name { display: flex; flex-direction: column; align-items: center; gap: 2px; margin: 0 0 var(--space-3); overflow-wrap: anywhere; }
.kp-qr-name span { font-size: var(--text-xs); color: var(--ink-faint); }
.kp-steps { margin: 0 0 var(--space-2); padding-left: 1.3em; color: var(--ink-soft); line-height: 1.55; }
.kp-steps .kp-code-num { font-size: var(--text-md); color: var(--ink); }

.kp-qrcam, .kp-scanview { position: relative; margin: var(--space-2) 0; overflow: hidden; border-radius: var(--radius-md); background: black; }
.kp-qrcam video, .kp-scanview video { display: block; width: 100%; max-height: 56vh; object-fit: contain; }
.kp-crop { position: relative; width: 100%; margin: var(--space-2) 0; user-select: none; touch-action: none; }
.kp-crop-img { display: block; width: 100%; height: auto; border-radius: var(--radius-sm); }
.kp-crop-lines { position: absolute; inset: 0; width: 100%; height: 100%; pointer-events: none; }
.kp-crop-lines polygon { fill: color-mix(in srgb, var(--accent) 12%, transparent); stroke: var(--accent); stroke-width: var(--icon-stroke); }
.kp-crop-h { position: absolute; width: 44px; height: 44px; margin: -22px 0 0 -22px; padding: 0; border: 0; border-radius: 50%; background: transparent; cursor: grab; touch-action: none; }
.kp-crop-h::after { content: ""; position: absolute; inset: 13px; border: 2px solid var(--accent); border-radius: 50%; background: var(--paper-raised); }
.kp-pages { display: grid; grid-template-columns: repeat(auto-fill, minmax(120px, 1fr)); gap: var(--space-2); margin-bottom: var(--space-3); }
.kp-page { margin: 0; }
.kp-page img { display: block; width: 100%; aspect-ratio: 3 / 4; object-fit: cover; object-position: top; border-radius: var(--radius-sm); box-shadow: 0 0 0 1px var(--rule); }
.kp-page figcaption { font-size: var(--text-2xs); color: var(--ink-faint); }

/* The preview: the whole window, the document drawn on a neutral ground. */
.kp-viewer { width: 100vw; max-width: none; height: 100dvh; max-height: none; margin: 0; padding: 0; border: 0; background: var(--paper); color: var(--ink); }
.kp-pv { display: grid; grid-template-rows: auto auto minmax(0, 1fr); height: 100%; }
.kp-pv-head { display: flex; align-items: center; gap: var(--space-2); padding: 6px 10px; border-bottom: 1px solid var(--rule); background: var(--paper-raised); }
.kp-pv-name { display: flex; flex: 1; flex-direction: column; min-width: 0; }
.kp-pv-name b { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.kp-pv-name span { font-size: var(--text-2xs); color: var(--ink-faint); }
.kp-pv-warn { margin: 0; padding: 6px 14px; border-bottom: 1px solid var(--rule); background: var(--warn-soft); font-size: var(--text-xs); }
.kp-pv-warn[hidden] { display: none; }
.kp-pv-body { overflow: auto; padding: var(--space-3); background: var(--paper-inset); }
.kp-pv-page { margin: 0 auto var(--space-3); background: white; box-shadow: 0 0 0 1px var(--rule); }
.kp-pv-page canvas { display: block; width: 100%; height: 100%; }
.kp-pv-page.is-bad { background: var(--danger-soft); }
.kp-pv-img { display: block; max-width: 100%; margin: 0 auto; background: white; box-shadow: 0 0 0 1px var(--rule); }

/* ---------------------------------------------------------------- /keep-open

   The free reader for a package: a page of the site, under its bar, so
   the window is not the application's. */
.kp-reader { display: block; height: auto; padding: var(--space-5) 0 var(--space-7); }
.ko-start.is-over { box-shadow: 0 0 0 2px var(--accent); }
.ko-pickrow { margin-top: 0; }
.ko-file { margin-top: var(--space-3); }
.ko-head { display: flex; flex-wrap: wrap; align-items: flex-start; justify-content: space-between; gap: var(--space-3); }
.ko-show { outline: none; }
.ko-show .kp-panel h3 { margin-bottom: 2px; }
.ko-show .kp-dmeta { margin-bottom: var(--space-3); }
.ko-letter .kp-notebody { font-size: var(--text-md); }
.ko-code { font-weight: 600; }
.ko-about { max-width: var(--measure); color: var(--ink-soft); line-height: var(--leading-prose); }

/* The site's privacy badge (privacyproof.js) sits small in the bottom right
   corner, as in Case, over the item pane, rather than over the sidebar's
   counts. On a phone it keeps the site's own place and size. */
@media (min-width: 761px) {
  body.kp-app #ppBadge { left: auto; right: var(--space-2); bottom: var(--space-1); min-height: 24px; padding: 1px var(--space-2); font-size: var(--text-2xs); box-shadow: none; }
}

/* ---------------------------------------------------------------- fields, history, the bin */

/* A hidden value of several lines (a private key) keeps its lines once
   shown; a long value has its Copy under it. */
.kp-secret-long { flex-direction: column; align-items: flex-start; }
.kp-secret-long .kp-secret-val { white-space: pre-wrap; font-size: var(--text-xs); }
.kp-copyable-long { flex-direction: column; align-items: flex-start; }
/* Hidden text in a box of several lines, as a password field hides it. */
.kp-cf-hidden { -webkit-text-security: disc; }
.kp-pwrow-top { align-items: flex-start; }
.kp-pwrow-top textarea { flex: 1; min-width: 0; }

/* An item's own fields, and a kind's fields, in their editors: one row
   each, the label, the kind and the value side by side. */
.kp-cfrow { display: grid; grid-template-columns: minmax(0, 11em) 10em minmax(0, 1fr) auto; gap: var(--space-2); align-items: start; margin-bottom: var(--space-2); }
.kp-cfrow .kp-pwrow, .kp-cfrow textarea { min-width: 0; }
.kp-kfrow { display: grid; grid-template-columns: minmax(0, 1fr) 12em auto auto auto; gap: var(--space-2); align-items: center; margin-bottom: var(--space-2); }
.kp-kfrow .kp-kf-remind[hidden] { display: inline-flex; visibility: hidden; }
.kp-ico-up { transform: rotate(90deg); }
.kp-kinds { margin: 0 0 var(--space-2); padding: 0; list-style: none; }
.kp-kinds li { display: flex; align-items: center; justify-content: space-between; gap: var(--space-2); padding: 6px 0; border-bottom: 1px solid var(--rule); color: var(--ink-soft); font-size: var(--text-xs); }
.kp-kinds b { color: var(--ink); font-size: var(--text-sm); }
.kp-kind-acts { display: flex; flex: none; gap: var(--space-1); }

/* Saved searches and the bin in the sidebar. A saved search's remove
   button shows on hover and on focus. */
.kp-filter-wrap { position: relative; display: block; }
.kp-filter-wrap .kp-filter { padding-right: 34px; }
.kp-filter-x { position: absolute; top: 50%; right: 0; width: 30px; height: 30px; transform: translateY(-50%); opacity: 0; transition: opacity var(--dur-2) var(--ease-standard), background-color var(--dur-2) var(--ease-standard), color var(--dur-2) var(--ease-standard); }
.kp-filter-x .kp-ico { width: 14px; height: 14px; }
.kp-filter-wrap:hover .kp-filter-x, .kp-filter-x:focus-visible { opacity: 1; }
.kp-filter-wrap:hover .kp-filter-n, .kp-filter-wrap:focus-within .kp-filter-n { visibility: hidden; }
.kp-side-rule { margin: var(--space-4) var(--space-2) var(--space-2); border: 0; border-top: 1px solid var(--rule); }
.kp-listbar { flex-wrap: wrap; }
.kp-listbar .kp-mini { white-space: nowrap; }
.kp-listbar .kp-mini[hidden] { display: none; }
.kp-qhelp { max-height: 46%; overflow-y: auto; padding: var(--space-2) var(--space-3); border-bottom: 1px solid var(--rule); background: var(--paper); }
.kp-qhelp[hidden] { display: none; }
.kp-qhelp .kp-hint { margin-top: 0; }
.kp-tips { display: grid; grid-template-columns: repeat(auto-fill, minmax(230px, 1fr)); gap: var(--space-1) var(--space-3); margin: 0; padding: 0; list-style: none; }
.kp-tips li { display: flex; align-items: center; gap: var(--space-2); min-width: 0; font-size: var(--text-2xs); color: var(--ink-faint); }
.kp-tips .kp-mini, .kp-tip-code { flex: none; min-width: 8.5em; text-align: left; font-family: var(--font-mono); font-size: var(--text-2xs); }
.kp-tip-code { padding: 4px 9px !important; }
.kp-slotbar { display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-2) var(--space-4); margin: 0 0 var(--space-4); }
.kp-slotbar select { min-width: 12em; }
.kp-reprompt { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: var(--space-2); }
.kp-reprompt p { margin: 0; }
.kp-trashnote { margin: var(--space-3) 0 0; border-left-color: var(--warn); background: var(--warn-soft); }
.kp-versions td:nth-child(2) { color: var(--ink-soft); font-size: var(--text-xs); }
.kp-versions .kp-when { white-space: nowrap; font-variant-numeric: tabular-nums; }

/* Large type: one box a character, numbered, digits and symbols in colour,
   to read a password off the screen and type it elsewhere. */
.kp-lt { display: flex; flex-wrap: wrap; gap: 6px; margin: 0 0 var(--space-3); }
.kp-lt-c { display: flex; flex-direction: column; align-items: center; justify-content: center; min-width: 3.1rem; padding: var(--space-2) var(--space-1) 4px; border: 1px solid var(--rule); border-radius: var(--radius-sm); background: var(--paper-raised); }
.kp-lt-c b { font: 500 2.2rem/1.1 var(--font-mono); color: var(--ink); }
.kp-lt-c i { font-style: normal; font-size: var(--text-2xs); font-variant-numeric: tabular-nums; color: var(--ink-faint); }
.kp-lt-c[data-k="d"] b, .kp-lt-key[data-k="d"] { color: var(--accent-strong); }
.kp-lt-c[data-k="s"] b, .kp-lt-key[data-k="s"] { color: var(--warn); }
.kp-lt-key { font-weight: 600; }

@media (max-width: 760px) {
  .kp-cfrow { grid-template-columns: minmax(0, 1fr) auto; padding-bottom: var(--space-2); border-bottom: 1px solid var(--rule); }
  .kp-cfrow .kp-cf-label { grid-column: 1; }
  .kp-cfrow .kp-cf-kind { grid-column: 1; grid-row: 2; }
  .kp-cfrow > .kp-pwrow, .kp-cfrow > textarea { grid-column: 1 / -1; }
  .kp-cfrow [data-rmcustom] { grid-column: 2; grid-row: 1; }
  .kp-kfrow { grid-template-columns: minmax(0, 1fr) auto auto; padding-bottom: var(--space-2); border-bottom: 1px solid var(--rule); }
  .kp-kfrow .kp-kf-label { grid-column: 1 / -1; }
  .kp-kfrow .kp-kf-kind { grid-column: 1; }
  .kp-kfrow .kp-kf-remind { grid-column: 1; grid-row: 3; }
  .kp-kfrow .kp-kf-remind[hidden] { display: none; }
  .kp-lt-c { min-width: 2.6rem; }
  .kp-lt-c b { font-size: 1.8rem; }
  .kp-tips { grid-template-columns: minmax(0, 1fr); }
  .kp-filter-x { opacity: 1; }
  .kp-seg { display: flex; }
  .kp-seg button { flex: 1 1 auto; padding: 0 var(--space-2); }
}

/* ---------------------------------------------------------------- the landing page's own */

.ld-aside { max-width: var(--measure); margin: var(--space-3) 0 0; font-size: var(--text-sm); color: var(--ink-soft); }

/* ---------------------------------------------------------------- round two: signing in, the health score, the plan, travel */

/* Signing in, one step at a time. */
.kp-seq { margin: 0 0 var(--space-4); padding: var(--space-3) var(--space-4); border-radius: var(--radius-lg); background: var(--paper-inset); box-shadow: inset 0 0 0 1px var(--rule); }
.kp-seq-head { display: flex; align-items: center; gap: var(--space-2); margin-bottom: var(--space-2); }
.kp-seq-head h3 { flex: 1; margin: 0; font-size: var(--text-sm); }
.kp-seq-steps { margin: 0 0 var(--space-2); padding: 0; list-style: none; }
.kp-seq-steps li { display: grid; grid-template-columns: 2em minmax(0, 1fr) auto auto; align-items: center; gap: var(--space-2); padding: var(--space-1) 0; border-top: 1px solid var(--rule); }
.kp-seq-n { display: grid; place-items: center; width: 24px; height: 24px; border-radius: 50%; background: var(--paper-raised); box-shadow: 0 0 0 1px var(--rule); font-size: var(--text-2xs); font-family: var(--font-mono); color: var(--ink-soft); }
.kp-seq-steps li[data-state="now"] .kp-seq-n { background: var(--accent); color: var(--on-accent); box-shadow: none; }
.kp-seq-steps li[data-state="done"] .kp-seq-label { color: var(--ink-soft); }
.kp-seq-label { font-weight: 600; }

/* The health score. */
.kp-watch { display: grid; grid-template-columns: auto minmax(0, 1fr) minmax(0, 320px); gap: var(--space-4) var(--space-5); align-items: center; max-width: 1100px; }
.kp-wscore { text-align: center; min-width: 7em; }
.kp-wnum { display: flex; align-items: baseline; justify-content: center; gap: 4px; margin: 0; }
.kp-wnum b { font-size: 3rem; line-height: 1; font-weight: 650; font-variant-numeric: tabular-nums; }
.kp-wnum span { font-size: var(--text-xs); color: var(--ink-faint); }
.kp-wnum[data-band="good"] b { color: var(--good); }
.kp-wnum[data-band="fair"] b { color: var(--warn); }
.kp-wnum[data-band="poor"] b { color: var(--danger); }
.kp-wword { margin: var(--space-1) 0 0; font-size: var(--text-2xs); font-weight: 650; letter-spacing: .06em; text-transform: uppercase; color: var(--ink-soft); }
.kp-wparts { display: grid; gap: var(--space-2); margin: 0; }
.kp-wpart { display: grid; grid-template-columns: 9em minmax(0, 1fr); gap: var(--space-2); align-items: baseline; }
.kp-wpart dt { font-size: var(--text-xs); font-weight: 600; color: var(--ink-soft); }
.kp-wpart dd { margin: 0; font-size: var(--text-xs); color: var(--ink-faint); }
.kp-wpart dd b { color: var(--ink); }
.kp-wpart .kp-hint-inline { display: block; }
.kp-wbar { display: block; height: 6px; margin: 4px 0 2px; border-radius: var(--radius-pill); background: var(--paper-inset); overflow: hidden; }
.kp-wbar::before { content: ""; display: block; width: var(--kp-w, 0%); height: 100%; border-radius: var(--radius-pill); background: var(--accent); }
.kp-spark { margin: 0; }
.kp-spark svg { display: block; width: 100%; height: auto; }
.kp-spark-grid { stroke: var(--rule); stroke-width: 1.5; stroke-dasharray: 3 3; }
.kp-spark-line { fill: none; stroke: var(--accent); stroke-width: 1.5; stroke-linejoin: round; stroke-linecap: round; }
.kp-spark-dot { fill: var(--accent); stroke: var(--paper-raised); stroke-width: 1.5; }
.kp-spark-cap { display: flex; justify-content: space-between; font-size: var(--text-2xs); color: var(--ink-faint); font-variant-numeric: tabular-nums; }
.kp-wline .kp-adv { margin-top: var(--space-2); }
.kp-wgroup .kp-hint { margin: 0; }
.kp-fixacts { display: flex; flex-wrap: wrap; align-items: center; justify-content: flex-end; gap: var(--space-1) var(--space-2); }
.kp-why1 { margin: 2px 0 0; font-size: var(--text-xs); line-height: 1.5; color: var(--ink-soft); overflow-wrap: anywhere; }
.kp-fixrow[data-kind="breached"] .kp-why1 { color: var(--danger); font-weight: 600; }

/* The plan. */
.kp-planrow { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr) minmax(0, 1.4fr) auto; gap: var(--space-2); align-items: center; margin-bottom: var(--space-2); }
.kp-planrow-2 { grid-template-columns: minmax(0, 1fr) minmax(0, 2fr) auto; }
.kp-check-field { align-self: end; min-height: 36px; }

/* Moving an item by QR code, travel mode. */
.kp-qr-big .kp-qr-svg { width: min(360px, 100%); }
.kp-xfer-check { font-size: var(--text-xl); letter-spacing: .12em; color: var(--ink); }
.kp-travel-steps > li { margin-bottom: var(--space-3); }
.kp-travel-steps .kp-row { margin-top: var(--space-2); }
.kp-travel-steps .kp-check { display: flex; margin-top: var(--space-1); }
.kp-btn.is-done { border-color: var(--good); color: var(--good); }

/* The free reader's plan and limits. */
.ko-plan .kp-table td { vertical-align: top; }
.ko-limits { max-width: var(--measure); }

/* ---------------------------------------------------------------- narrower */

@media (max-width: 1180px) {
  .kp-items { grid-template-columns: minmax(280px, 38%) minmax(0, 1fr); }
  .kp-filters { display: none; }
  .kp-filter-sel { display: block; width: auto !important; max-width: 60%; min-height: 32px !important; padding: 2px var(--space-2) !important; font-size: var(--text-xs) !important; }
}

@media (max-width: 760px) {
  body.kp-app { height: auto; overflow: auto; }
  .kp { height: auto; min-height: 100dvh; }
  .kp-top { flex-wrap: wrap; row-gap: var(--space-1); }
  .kp-tabs { order: 5; flex: 1 1 100%; }
  .kp-state { display: none; }
  .kp-lockbtn span { display: none; }
  .kp-clip-say { display: none; }
  .kp-fixrow { grid-template-columns: minmax(0, 1fr); }
  .kp-fixrow > .kp-btn { justify-self: start; }
  .kp-main { overflow: visible; }
  .kp-page { height: auto; overflow: visible; padding: var(--space-4) var(--space-4) var(--space-7); }
  .kp-cols, .kp-grid2, .kp-grid3 { grid-template-columns: minmax(0, 1fr); }
  .kp-items { display: block; height: auto; }
  .kp-listpane { min-height: calc(100dvh - 120px); border-right: 0; }
  .kp-list { overflow: visible; }
  .kp-detail { display: none; overflow: visible; }
  .kp-items[data-detail="open"] .kp-listpane { display: none; }
  .kp-items[data-detail="open"] .kp-detail { display: block; }
  .kp-detail-in { padding: var(--space-3) var(--space-4) var(--space-7); }
  .kp-detail-top { display: block; }
  .kp-dl-row { grid-template-columns: minmax(0, 1fr); gap: 2px; }
  .kp-coderow { grid-template-columns: minmax(0, 1fr) auto; }
  .kp-coderow .kp-code-secs { display: none; }
  .kp-coderow-acts { grid-column: 1 / -1; }
  .kp-coderow .kp-code-left { grid-row: 3; }
  .kp-bigcode .kp-code-num { font-size: 1.9rem; }
  .kp-daterow { grid-template-columns: minmax(0, 1fr) auto; }
  .kp-daterow .kp-date-val, .kp-daterow .kp-date-lead { grid-column: 1; }
  .kp-watch { grid-template-columns: minmax(0, 1fr); }
  .kp-wscore { text-align: left; }
  .kp-wnum { justify-content: flex-start; }
  .kp-fixacts { justify-content: flex-start; }
  .kp-planrow, .kp-planrow-2 { grid-template-columns: minmax(0, 1fr) auto; padding-bottom: var(--space-2); border-bottom: 1px solid var(--rule); }
  .kp-planrow input { grid-column: 1; }
  .kp-planrow [data-rmrow] { grid-column: 2; grid-row: 1; }
  .kp-seq-steps li { grid-template-columns: 2em minmax(0, 1fr) auto; }
  .kp-seq-steps li .kp-mini { grid-column: 2; justify-self: start; }
  .kp-dates-t th:nth-child(1) { width: 6.5em; }
  .kp-dates-t th:nth-child(3), .kp-dates-t td:nth-child(3) { display: none; }
  .kp-dates-t th:nth-child(4) { width: 7em; }
  .kp-dates-sub { display: block; }
  .kp-file .kp-icon-btn { opacity: 1; width: 44px; height: 44px; }
  /* Six actions do not fit one row at 360 pixels: three to a row, each
     wide enough for its word, rather than squeezed until they overlap. */
  .kp-actions { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: var(--space-1); }
  .kp-actions .kp-btn { min-width: 0; padding: 6px 4px; gap: 4px; }
  .kp-dialog { width: 100vw; max-width: 100vw; max-height: 100dvh; height: 100dvh; margin: 0; border-radius: 0; }
  .kp-dlg-form { max-height: 100dvh; height: 100%; }
}

/* Quick access: a search box over any screen, as a launcher. */
.kp-quick { width: min(620px, calc(100vw - 24px)); max-height: min(560px, calc(100dvh - 24px)); margin: 12vh auto auto; padding: 0; border: 0; border-radius: var(--radius-lg); background: var(--paper-raised); color: var(--ink); box-shadow: 0 0 0 1px var(--rule), 0 24px 60px rgba(0, 0, 0, .3); }
.kp-quick::backdrop { background: rgba(10, 10, 16, .45); }
.kp-quick-in { display: flex; flex-direction: column; max-height: inherit; }
.kp-quick-bar { display: flex; align-items: center; gap: var(--space-2); padding: var(--space-2) var(--space-2) var(--space-2) var(--space-4); border-bottom: 1px solid var(--rule); }
.kp-quick-ico { flex: none; color: var(--ink-faint); }
.kp .kp-quick-bar input { flex: 1; min-width: 0; min-height: 44px; padding: 0; border: 0; border-radius: 0; background: none; box-shadow: none; color: var(--ink); font-size: var(--text-md); outline: none; }
.kp-quick-bar:focus-within { box-shadow: inset 0 -2px var(--focus); }
.kp-quick-head { margin: var(--space-2) var(--space-4) 0; font-family: var(--font-mono); font-size: var(--text-2xs); letter-spacing: .08em; text-transform: uppercase; color: var(--ink-faint); }
.kp-quick-head:empty { display: none; }
.kp-quick-list { flex: 1; min-height: 0; margin: 0; padding: var(--space-1) 0; list-style: none; overflow-y: auto; }
.kp-quick-row { display: grid; grid-template-columns: auto minmax(0, 1fr) auto; align-items: center; column-gap: var(--space-3); min-height: 48px; padding: 4px var(--space-4); cursor: pointer; }
@media (hover: hover) { .kp-quick-row:hover { background: var(--paper-inset); } }
.kp-quick-row[aria-selected="true"] { background: var(--accent-soft); box-shadow: inset 2px 0 var(--accent); }
.kp-quick-main { display: grid; min-width: 0; }
.kp-quick-title { display: flex; align-items: center; gap: 4px; font-weight: 600; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.kp-quick-sub { font-size: var(--text-xs); color: var(--ink-faint); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.kp-quick-does { font-family: var(--font-mono); font-size: var(--text-2xs); color: var(--ink-faint); white-space: nowrap; }
.kp-quick-row[aria-selected="false"] .kp-quick-does { visibility: hidden; }
.kp-quick-empty { padding: var(--space-4); color: var(--ink-faint); font-size: var(--text-sm); }
.kp-quick-say { margin: 0 var(--space-4); font-size: var(--text-xs); color: var(--ink-soft); }
.kp-quick-say:empty { display: none; }
.kp-quick-keys { display: flex; flex-wrap: wrap; gap: 4px var(--space-4); margin: 0; padding: var(--space-2) var(--space-4); border-top: 1px solid var(--rule); font-size: var(--text-2xs); color: var(--ink-faint); }
.kp-quick-keys kbd { font-family: var(--font-mono); font-size: var(--text-2xs); padding: 0 4px; border: 1px solid var(--rule); border-radius: var(--radius-sm); background: var(--paper); color: var(--ink-soft); }
/* Vaults in Settings, and the one an item is in. */
.kp-vaults { margin: 0 0 var(--space-3); padding: 0; list-style: none; }
.kp-vaults li { display: flex; align-items: center; gap: var(--space-2); min-height: 44px; border-bottom: 1px solid var(--rule); }
.kp-vault-name { flex: 1; min-width: 0; font-size: var(--text-sm); color: var(--ink-soft); font-variant-numeric: tabular-nums; }
.kp-vault-name b { color: var(--ink); }
.kp-grow { flex: 1; min-width: 0; }
.kp-vaultpick select { min-height: 36px; padding: 4px 8px; border: 1px solid var(--rule-strong); border-radius: var(--radius-sm); background: var(--paper-raised); color: var(--ink); }
.kp-share-in { width: 100%; font-family: var(--font-mono); font-size: var(--text-sm); }
@media (max-width: 760px) {
  .kp-quick { width: 100vw; max-width: 100vw; max-height: 100dvh; height: 100dvh; margin: 0; border-radius: 0; }
  .kp-quick-keys { display: none; }
  .kp-quick-row { min-height: 56px; }
  .kp-quick-does { display: none; }
  .kp-vaultpick { flex: 1 1 100%; }
  .kp-vaultpick select { width: 100%; min-height: 44px; }
}

/* A finger needs more than a pointer. */
@media (pointer: coarse) {
  .kp-home, .kp-tabs button, .kp-btn, .kp-link, .kp-mini, .kp-icon-btn, .kp-filter, .kp-tag, .kp-seg button, .kp-check, .kp-menu button,
  .kp-history summary, .kp-adv summary, .kp input:not([type="checkbox"]):not([type="radio"]):not([type="file"]):not([type="range"]), .kp select, .kp-filter-sel, .kp-pick { min-height: 44px !important; }
  .kp-home, .kp-icon-btn { width: 44px; }
  .kp-mini { min-width: 44px; }
  .kp-check input, .kp-pick input { width: 22px; height: 22px; }
  .kp-item { min-height: 64px; }
}

/* ------------------------------------------- motion inside the window
   (30 October 2026.) The screens arrived, and then nothing in the window
   moved: the Keep opened in one frame, a list redrawn for another filter
   appeared whole, the item chosen took its pane in a step, a copy was
   answered only by a notice at the foot of the window, and a long job
   showed in the tab's title and nowhere on the page. Each now happens as
   the rest of the site's things do (theme.css, MOTION): the three panes of
   Items deal in a step apart as the Keep opens or the screen is come back
   to (keep-app.js marks the section is-arriving for that one drawing); a
   list that is a new list, at the unlock or under another filter, deals
   its rows out a --stagger apart, eight steps then flat, while the list
   redrawn under a search being typed stays still; a row that was not there
   before rises into its place; the item chosen arrives in its pane, on a
   phone from the right edge, and the list comes back from the left, while
   the same item drawn again stays still; the chosen item and the chosen
   filter carry a line of the accent along their left edge, as quick
   access's row already did; a Copy button says Copied where it was pressed;
   every control answers the hand with a colour over --dur-2 and settles a
   pixel under the press, and not at all with motion switched down; and a
   job still going (encrypting files, reading a scan, an import) fills a
   hairline along the top of the window to the fraction done, or breathes
   while it cannot say. Every distance is one of theme.css's, nought with
   motion switched down, and everything that arrives asks for the fade it
   keeps then. */
.kp-items.is-arriving > * { --os-fade: var(--dur-fade); animation: os-rise-soft var(--dur-4) var(--ease-standard) backwards; }
.kp-items.is-arriving > :nth-child(2) { animation-delay: var(--os-step); }
.kp-items.is-arriving > :nth-child(3) { animation-delay: calc(var(--os-step) * 2); }
.kp-list.is-dealt .kp-item, .kp-item.is-new { --os-fade: var(--dur-fade); animation: os-rise-soft var(--dur-3) var(--ease-standard) backwards; animation-delay: calc(var(--stagger) * var(--deal, 0)); }
.kp-detail-in.is-arriving, .kp-detail-empty.is-arriving { --os-fade: var(--dur-fade); animation: os-rise-soft var(--dur-3) var(--ease-standard) backwards; }
.kp-item[aria-selected="true"], .kp-filter[aria-current="true"] { box-shadow: inset 2px 0 0 var(--accent); }
/* The sign-in steps unfolding under the actions, the search tips, and the
   question an item asks before it is shown. */
.kp-seq:not([hidden]), .kp-qhelp:not([hidden]), .kp-reprompt { --os-fade: var(--dur-fade); animation: os-rise-soft var(--dur-3) var(--ease-standard) backwards; }
/* Large type: the characters land one after another, eight steps then
   together (keep-app.js counts them in --deal). */
.kp-lt-c { --os-fade: var(--dur-fade); animation: os-pop var(--dur-3) var(--ease-spring) backwards; animation-delay: calc(var(--stagger) * var(--deal, 0)); }
/* Hover and press. A colour, a line or a shadow eases over --dur-2 on
   every control the sheet above did not already ease, and a pressed
   control settles a pixel, as .kp-btn did; with motion switched down the
   colour changes and nothing moves (theme.css names the site's own
   classes; Keep's are named here). */
.kp-item, .kp-filter, .kp-icon-btn, .kp-mini, .kp-tag, .kp-tpl, .kp-menu button, .kp-seg button, .kp-quick-row, .kp-home, .kp-pick, .kp-link, .kp-file-open { transition: background-color var(--dur-2) var(--ease-standard), color var(--dur-2) var(--ease-standard), border-color var(--dur-2) var(--ease-standard), box-shadow var(--dur-2) var(--ease-standard); }
.kp-icon-btn:not(.kp-filter-x):active, .kp-mini:active, .kp-tabs button:active, .kp-filter:active, .kp-tag:active, .kp-tpl:active, .kp-seg button:active { transform: translateY(1px); }
:root[data-motion="none"] .kp :is(.kp-btn, .kp-icon-btn, .kp-mini, .kp-tabs button, .kp-filter, .kp-tag, .kp-tpl, .kp-seg button):active { transform: none; }
/* Copy, pressed: the button says Copied where it stands, in the colour of
   a thing done, and settles (theme.css, os-confirm); it is as wide as its
   longer word from the start, so the row does not jog. */
.kp-mini[data-copy], .kp-mini[data-copyval], .kp-mini[data-copycode] { min-width: 4.8em; }
.kp-btn[data-copycode] { min-width: 5.4em; }
.kp-btn.is-copied, .kp-mini.is-copied { border-color: var(--good); color: var(--good); }
/* The status line in the bar, when its words change. */
.kp-state.is-fresh { --os-fade: var(--dur-fade); animation: os-fade-in var(--dur-2) var(--ease-standard) backwards; }
/* A job still going: a hairline in the accent along the top of the
   window, filled to the fraction done (keep-app.js sets --kp-job) or,
   while it cannot say, full and breathing; it fades when the job is done.
   With motion switched down the line simply stands there. */
.kp-main::before { content: ""; position: absolute; z-index: 5; top: 0; left: 0; right: 0; height: 2px; background: var(--accent); opacity: 0; transform-origin: left; scale: var(--kp-job, 0) 1; pointer-events: none; transition: opacity var(--dur-2) var(--ease-standard), scale var(--dur-2) var(--ease-standard); }
.kp[data-busy] .kp-main::before { opacity: 1; }
.kp[data-busy="wait"] .kp-main::before { animation: ob-breathe var(--dur-sweep) var(--ease-standard) infinite alternate; }
/* On a phone the item slides in from the right edge over the list, and
   the list comes back from the left when Back is pressed (keep-app.js
   marks it is-back for that one drawing); each by the theme's distance. */
@media (max-width: 760px) {
  .kp-items[data-detail="open"] .kp-detail-in.is-arriving { animation-name: kp-from-right; animation-duration: var(--dur-4); }
  .kp-listpane.is-back { --os-fade: var(--dur-fade); animation: kp-from-left var(--dur-4) var(--ease-standard) backwards; }
}
@keyframes kp-from-right { from { opacity: 0; transform: translate3d(var(--os-rise-lg), 0, 0); } }
@keyframes kp-from-left { from { opacity: 0; transform: translate3d(calc(var(--os-rise-lg) * -1), 0, 0); } }
