/* Keystone Data Pond UI kit.
   Link this one file, put class="kdp" on the root element, then build with the kdp- classes.
   Every value comes from a token in tokens/keystone-data-pond.css.
   A page that needs a value the tokens do not have is a change to the bible, not a local override.
   The rules for each component are in DESIGN.md. */

@import url("tokens/keystone-data-pond.css");

/* ---------- Base ---------- */

.kdp { font-family: var(--kdp-font-display); font-size: var(--kdp-text-body); line-height: 1.5; color: var(--kdp-ink); background: var(--kdp-bg); font-optical-sizing: auto; -webkit-font-smoothing: antialiased; text-wrap: pretty; }
/* The browser's 8 px body margin framed the app bar and made a page 16 px wider than a phone (DUCK-1622). */
body.kdp { margin: 0; }
.kdp *, .kdp *::before, .kdp *::after { box-sizing: border-box; }
/* The link rules wrap a in :where() to keep them as weak as one class.
   Stronger, they would beat every component that is also a link: an <a class="kdp-btn"> lost its text colour. */
.kdp :where(a) { color: var(--kdp-link); text-decoration-thickness: 1px; text-underline-offset: 3px; }
.kdp :where(a):hover { color: var(--kdp-pond-hover); }
.kdp :focus-visible { outline: var(--kdp-focus-ring); outline-offset: 2px; }
.kdp-on-deep { --kdp-focus: var(--kdp-shallows); background: var(--kdp-deep-water); color: var(--kdp-eggshell); }
.kdp-on-deep :where(a), .kdp-on-deep :where(a):hover { color: var(--kdp-shallows); }

/* ---------- Type ---------- */

.kdp-display { font-size: var(--kdp-text-display); font-weight: 800; line-height: 1; letter-spacing: -.035em; margin: 0; text-wrap: balance; }
.kdp-h1 { font-size: var(--kdp-text-h1); font-weight: 800; line-height: 1.05; letter-spacing: -.03em; margin: 0; text-wrap: balance; }
.kdp-h2 { font-size: var(--kdp-text-h2); font-weight: 800; line-height: 1.15; letter-spacing: -.02em; margin: 0; text-wrap: balance; }
.kdp-h3 { font-size: var(--kdp-text-h3); font-weight: 700; line-height: 1.25; letter-spacing: -.01em; margin: 0; }
.kdp-h4 { font-size: var(--kdp-text-h4); font-weight: 700; line-height: 1.3; margin: 0; }
.kdp-body { font-size: var(--kdp-text-body); line-height: 1.5; margin: 0; }
.kdp-small { font-size: var(--kdp-text-small); line-height: 1.45; margin: 0; }
.kdp-caption { font-size: var(--kdp-text-caption); line-height: 1.35; margin: 0; }
.kdp-lead { max-width: 52ch; font-size: var(--kdp-text-h4); line-height: 1.5; margin: 0; }
.kdp-eyebrow { font-family: var(--kdp-font-mono); font-size: var(--kdp-text-caption); font-weight: 600; letter-spacing: .12em; text-transform: uppercase; color: var(--kdp-pond); margin: 0; }
/* Pond on Deep Water is below the text minimum, so the eyebrow turns Shallows there.
   The allowed pairs: DESIGN.md section 3.4. */
.kdp-on-deep .kdp-eyebrow { color: var(--kdp-shallows); }
.kdp-muted { color: var(--kdp-ink-2); }
.kdp-mono { font-family: var(--kdp-font-mono); }
.kdp-num { font-family: var(--kdp-font-mono); font-variant-numeric: tabular-nums; }
.kdp-code-inline { font-family: var(--kdp-font-mono); font-size: .875em; background: var(--kdp-eggshell-2); border-radius: var(--kdp-radius-sm); padding: 1px 6px; }
.kdp-kbd { font-family: var(--kdp-font-mono); font-size: 12px; font-weight: 600; border: 1px solid var(--kdp-line-strong); border-bottom-width: 2px; border-radius: var(--kdp-radius-sm); padding: 1px 6px; background: var(--kdp-card); }

/* ---------- Layout ---------- */

.kdp-shell { min-height: 100vh; display: grid; grid-template-rows: var(--kdp-appbar-height) 1fr; }
.kdp-page { width: 100%; max-width: var(--kdp-content-max); margin: 0 auto; padding: 0 var(--kdp-gutter) var(--kdp-space-8); }
.kdp-pagehead { display: flex; flex-wrap: wrap; align-items: flex-end; justify-content: space-between; gap: var(--kdp-space-4) var(--kdp-space-5); padding: var(--kdp-space-6) 0 var(--kdp-space-5); }
.kdp-pagehead__text { display: grid; gap: var(--kdp-space-2); max-width: 64ch; }
.kdp-pagehead__actions { display: flex; flex-wrap: wrap; gap: var(--kdp-space-3); }
/* A stack and a field have one column of minmax(0, 1fr), never the implicit auto column.
   An auto column is as wide as its widest item, so a long kdp-id or kdp-code ran past the card on a phone, and the ID's ellipsis and the code's scroll never started. */
.kdp-stack { display: grid; grid-template-columns: minmax(0, 1fr); gap: var(--kdp-space-4); }
/* A tight stack holds the parts of one value, such as a provider over its ID in a table cell. */
.kdp-stack--tight { gap: var(--kdp-space-2); }
.kdp-row { display: flex; flex-wrap: wrap; align-items: center; gap: var(--kdp-space-3); }
.kdp-row--between { justify-content: space-between; }
.kdp-row--end { justify-content: flex-end; }

/* ---------- App bar ---------- */

.kdp-appbar { --kdp-focus: var(--kdp-shallows); position: sticky; top: 0; z-index: var(--kdp-z-sticky); display: flex; align-items: center; gap: var(--kdp-space-6); height: var(--kdp-appbar-height); padding: 0 var(--kdp-gutter); background: var(--kdp-deep-water); color: var(--kdp-eggshell); }
.kdp-appbar__logo { display: block; flex: none; }
.kdp-appbar__logo img { display: block; height: 36px; width: auto; }
.kdp-appbar__nav { display: flex; align-items: stretch; gap: var(--kdp-space-5); height: 100%; }
.kdp-appbar__nav a { display: flex; align-items: center; color: var(--kdp-eggshell); text-decoration: none; font-size: var(--kdp-text-small); font-weight: 600; border-bottom: 3px solid transparent; border-top: 3px solid transparent; }
.kdp-appbar__nav a:hover { color: var(--kdp-rubber-duck); }
.kdp-appbar__nav a[aria-current="page"] { color: var(--kdp-rubber-duck); border-bottom-color: var(--kdp-rubber-duck); }
.kdp-appbar__end { margin-left: auto; display: flex; align-items: center; gap: var(--kdp-space-4); }
.kdp-appbar__context { font-family: var(--kdp-font-mono); font-size: var(--kdp-text-caption); font-weight: 600; letter-spacing: .12em; text-transform: uppercase; color: var(--kdp-shallows); white-space: nowrap; }
.kdp-appbar__user { font-size: var(--kdp-text-small); font-weight: 600; color: var(--kdp-eggshell); white-space: nowrap; }
/* The hover rule repeats Shallows because the base link hover is Pond Hover, which fails on Deep Water. */
.kdp-appbar__link, .kdp-appbar__link:hover { font-size: var(--kdp-text-small); font-weight: 600; color: var(--kdp-shallows); white-space: nowrap; }
/* "Sign out" is a form's button, because it is a POST, so this rule gives the button the look of the link. */
button.kdp-appbar__link { padding: 0; border: 0; background: none; font-family: inherit; line-height: inherit; text-decoration: underline; text-decoration-thickness: 1px; text-underline-offset: 3px; cursor: pointer; }
/* An app bar button opens the kdp-menu after it: the app selector and "Your account" are the two.
   A row of links there made the bar wider than a phone (DESIGN.md section 5, "App bar and page head"). */
.kdp-appbar__button { display: inline-flex; align-items: center; gap: var(--kdp-space-2); min-height: 40px; padding: 0 var(--kdp-space-3); border: 0; border-radius: var(--kdp-radius-pill); background: none; color: var(--kdp-eggshell); font: 600 var(--kdp-text-small)/1 var(--kdp-font-display); white-space: nowrap; cursor: pointer; }
.kdp-appbar__button:hover, .kdp-appbar__button:has(+ .kdp-menu:popover-open) { background: rgba(156, 203, 255, .14); }

/* ---------- Menu: a list of actions in a popover ---------- */

/* The menu is a native popover, so it needs no script; it is fixed below the app bar, at its right end.
   It sets Pond as its focus colour, because inside the app bar it would take the bar's Shallows ring, which fails on Card. */
.kdp-menu { --kdp-focus: var(--kdp-pond); position: fixed; inset: var(--kdp-appbar-height) var(--kdp-gutter) auto auto; min-width: var(--kdp-menu-min); margin: 0; padding: var(--kdp-space-2); border: 1px solid var(--kdp-line); border-radius: var(--kdp-radius-md); background: var(--kdp-raised); color: var(--kdp-ink); box-shadow: var(--kdp-shadow-1); }
.kdp-menu:popover-open { animation: kdp-rise var(--kdp-dur-2) var(--kdp-ease); }
.kdp-menu ul { list-style: none; margin: 0; padding: 0; display: grid; gap: 2px; }
.kdp-menu form { margin: 0; }
.kdp-menu__item { display: flex; align-items: center; width: 100%; min-height: 40px; padding: 0 var(--kdp-space-3); border: 0; border-radius: var(--kdp-radius-sm); background: none; color: var(--kdp-ink); font: 600 var(--kdp-text-small)/1.2 var(--kdp-font-display); text-align: left; text-decoration: none; cursor: pointer; }
.kdp-menu__item:hover { background: var(--kdp-eggshell-2); color: var(--kdp-ink); }
.kdp-menu__item[aria-current="page"] { background: var(--kdp-pond-tint); }
/* A split starts a group of its own after a line, as "Sign out" is. */
.kdp-menu__split { margin-top: var(--kdp-space-1); padding-top: var(--kdp-space-1); border-top: 1px solid var(--kdp-line); }

/* ---------- Hero: the top of a landing page ---------- */

.kdp-hero { display: grid; grid-template-columns: minmax(0, 1.25fr) minmax(0, 1fr); gap: var(--kdp-space-7); align-items: center; padding: var(--kdp-space-8) 0 var(--kdp-space-7); }
.kdp-hero__text { display: grid; gap: var(--kdp-space-4); justify-items: start; }
.kdp-hero__art { display: flex; justify-content: center; }
.kdp-hero__art img { width: 100%; max-width: 420px; height: auto; }

/* ---------- Side nav ---------- */

.kdp-shell__body { display: grid; grid-template-columns: var(--kdp-sidenav-width) minmax(0, 1fr); }
.kdp-shell__body > .kdp-page { margin: 0; }
/* The side nav carries the popover attribute for the small-screen menu.
   The browser gives a popover its own position, inset, size, margin, border and colour, so this rule sets every one of them;
   leave one out and the side nav moves or vanishes on wide screens. */
.kdp-sidenav { position: sticky; inset: var(--kdp-appbar-height) auto auto; align-self: start; display: flex; flex-direction: column; gap: var(--kdp-space-3); width: auto; height: calc(100vh - var(--kdp-appbar-height)); margin: 0; overflow-y: auto; padding: var(--kdp-space-5) var(--kdp-space-3); border: 0; border-right: 1px solid var(--kdp-line); background: var(--kdp-bg); color: var(--kdp-ink); }
.kdp-sidenav ul { list-style: none; margin: 0; padding: 0; display: grid; gap: 2px; }
.kdp-sidenav a { display: flex; align-items: center; gap: var(--kdp-space-2); min-height: 40px; padding: 0 var(--kdp-space-3); border-radius: var(--kdp-radius-md); color: var(--kdp-ink); font-size: var(--kdp-text-small); font-weight: 600; text-decoration: none; transition: background-color var(--kdp-dur-1) var(--kdp-ease); }
.kdp-sidenav a:hover { background: var(--kdp-eggshell-2); color: var(--kdp-ink); }
/* "true" is a page below the link's own, such as one window of an extract: the link is still where you are. */
.kdp-sidenav a[aria-current] { background: var(--kdp-pond-tint); font-weight: 600; }
.kdp-sidenav .kdp-count { margin-left: auto; font-family: var(--kdp-font-mono); font-size: var(--kdp-text-caption); font-weight: 400; color: var(--kdp-ink-2); }
.kdp-sidenav__label { padding: 0 var(--kdp-space-3); }
/* A group: a section with pages. Its heading is not a link, and its pages are always listed, with no chevron.
   A page lines up with the section names, after the icon's column: the 20 px icon and its gap. */
.kdp-sidenav__group { display: grid; gap: 2px; margin: var(--kdp-space-2) 0; }
.kdp-sidenav__heading { display: flex; align-items: center; gap: var(--kdp-space-2); min-height: 40px; margin: 0; padding: 0 var(--kdp-space-3); font-size: var(--kdp-text-small); font-weight: 600; }
.kdp-sidenav__pages a { padding-left: calc(var(--kdp-space-3) + 20px + var(--kdp-space-2)); font-weight: 400; }
.kdp-sidenav__pages a[aria-current] { font-weight: 600; }
.kdp-sidenav__foot { margin: auto 0 0; padding: 0 var(--kdp-space-3); font-size: var(--kdp-text-caption); color: var(--kdp-ink-2); }

/* ---------- Buttons ---------- */

.kdp-btn { display: inline-flex; align-items: center; justify-content: center; gap: var(--kdp-space-2); min-height: 40px; padding: 0 18px; border-radius: var(--kdp-radius-pill); border: 2px solid transparent; font: 600 15px/1 var(--kdp-font-display); text-decoration: none; white-space: nowrap; cursor: pointer; transition: background-color var(--kdp-dur-1) var(--kdp-ease), border-color var(--kdp-dur-1) var(--kdp-ease), color var(--kdp-dur-1) var(--kdp-ease), transform var(--kdp-dur-1) var(--kdp-ease); }
.kdp-btn:active { transform: translateY(1px); }
.kdp-btn--primary { background: var(--kdp-pond); color: var(--kdp-eggshell); }
.kdp-btn--primary:hover { background: var(--kdp-pond-hover); color: var(--kdp-eggshell); }
.kdp-btn--primary:active { background: var(--kdp-pond-press); }
.kdp-btn--secondary { background: transparent; color: var(--kdp-ink); border-color: var(--kdp-line-strong); }
.kdp-btn--secondary:hover { background: var(--kdp-eggshell-2); color: var(--kdp-ink); border-color: var(--kdp-ink); }
.kdp-btn--ghost { background: transparent; color: var(--kdp-pond); }
.kdp-btn--ghost:hover { background: var(--kdp-pond-tint); color: var(--kdp-pond-hover); }
.kdp-btn--danger { background: var(--kdp-fox); color: var(--kdp-deep-water); }
.kdp-btn--danger:hover { background: var(--kdp-fox-hover); color: var(--kdp-deep-water); }
.kdp-btn--duck { background: var(--kdp-rubber-duck); color: var(--kdp-deep-water); }
.kdp-btn--duck:hover { background: var(--kdp-duck-tint); color: var(--kdp-deep-water); border-color: var(--kdp-rubber-duck); }
.kdp-btn--sm { min-height: 32px; padding: 0 14px; font-size: 14px; }
.kdp-btn--icon { width: 40px; padding: 0; }
.kdp-btn--icon.kdp-btn--sm { width: 32px; }
.kdp-btn[disabled], .kdp-btn[aria-disabled="true"] { opacity: .45; cursor: not-allowed; transform: none; }
.kdp-btn[aria-busy="true"] { cursor: progress; }
.kdp-btn[aria-busy="true"]::after { content: ""; width: 14px; height: 14px; border-radius: 50%; border: 2px solid currentColor; border-right-color: transparent; animation: kdp-spin .8s linear infinite; }
.kdp-on-deep .kdp-btn--secondary { color: var(--kdp-eggshell); border-color: var(--kdp-shallows); }
.kdp-on-deep .kdp-btn--secondary:hover { background: rgba(156, 203, 255, .14); color: var(--kdp-eggshell); }

/* ---------- Form fields ---------- */

.kdp-field { display: grid; grid-template-columns: minmax(0, 1fr); gap: 6px; }
/* A form is one column, no wider than --kdp-form-max, so a line of input stays readable (DESIGN.md section 6.4). */
.kdp-form { max-width: var(--kdp-form-max); }
/* A fieldset groups the choices of one question; the browser's own border, margin and padding would draw a box the bible does not have. */
.kdp-fieldset { min-width: 0; margin: 0; padding: 0; border: 0; }
.kdp-field--inline { min-width: var(--kdp-control-min); }
.kdp-label { font-size: var(--kdp-text-small); font-weight: 600; }
.kdp-label .kdp-optional { font-weight: 400; color: var(--kdp-ink-2); }
.kdp-hint { font-size: var(--kdp-text-small); color: var(--kdp-ink-2); margin: 0; }
.kdp-input, .kdp-select, .kdp-textarea { width: 100%; min-height: 40px; padding: 8px 12px; border: 1.5px solid var(--kdp-line-strong); border-radius: var(--kdp-radius-md); background: var(--kdp-card); color: var(--kdp-ink); font: 400 16px/1.4 var(--kdp-font-display); transition: border-color var(--kdp-dur-1) var(--kdp-ease); }
.kdp-input::placeholder, .kdp-textarea::placeholder { color: var(--kdp-ink-3); }
.kdp-input:hover, .kdp-select:hover, .kdp-textarea:hover { border-color: var(--kdp-ink-2); }
.kdp-input:focus-visible, .kdp-select:focus-visible, .kdp-textarea:focus-visible { border-color: var(--kdp-pond); }
.kdp-input[disabled], .kdp-select[disabled], .kdp-textarea[disabled] { background: var(--kdp-eggshell-2); color: var(--kdp-ink-2); cursor: not-allowed; }
.kdp-input--mono { font-family: var(--kdp-font-mono); font-size: 14px; }
.kdp-select { appearance: none; padding-right: 40px; background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Cpath d='M4 6l4 4 4-4' fill='none' stroke='%230C1C3D' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E"); background-repeat: no-repeat; background-position: right 12px center; background-size: 16px; }
.kdp-textarea { min-height: 96px; resize: vertical; }
.kdp-field--error .kdp-input, .kdp-field--error .kdp-select, .kdp-field--error .kdp-textarea { border-color: var(--kdp-fox-ink); }
.kdp-error { display: flex; align-items: baseline; gap: var(--kdp-space-2); margin: 0; font-size: var(--kdp-text-small); font-weight: 600; color: var(--kdp-fox-ink); }
.kdp-error::before { content: ""; flex: none; width: 8px; height: 8px; border-radius: 50%; background: var(--kdp-fox); transform: translateY(-1px); }
.kdp-check { display: inline-flex; align-items: center; gap: 10px; font-size: var(--kdp-text-body); cursor: pointer; }
.kdp-check input { width: 18px; height: 18px; margin: 0; accent-color: var(--kdp-pond); }
.kdp-switch { appearance: none; flex: none; width: 40px; height: 24px; margin: 0; border-radius: var(--kdp-radius-pill); background: var(--kdp-line-strong); position: relative; cursor: pointer; transition: background-color var(--kdp-dur-2) var(--kdp-ease); }
.kdp-switch::before { content: ""; position: absolute; top: 3px; left: 3px; width: 18px; height: 18px; border-radius: 50%; background: var(--kdp-card); transition: transform var(--kdp-dur-2) var(--kdp-ease); }
.kdp-switch:checked { background: var(--kdp-pond); }
.kdp-switch:checked::before { transform: translateX(16px); }

/* ---------- Status chips ---------- */

.kdp-chip { display: inline-flex; align-items: center; gap: var(--kdp-space-2); min-height: 28px; padding: 0 12px; border-radius: var(--kdp-radius-pill); background: var(--kdp-eggshell-2); color: var(--kdp-deep-water); font: 600 13px/1 var(--kdp-font-display); white-space: nowrap; }
.kdp-chip::before { content: ""; flex: none; width: 8px; height: 8px; border-radius: 50%; background: var(--kdp-ink-2); }
.kdp-chip--success { background: var(--kdp-lily-tint); }
.kdp-chip--success::before { background: var(--kdp-lily-ink); }
.kdp-chip--warning { background: var(--kdp-bill-tint); }
.kdp-chip--warning::before { background: var(--kdp-bill); }
.kdp-chip--danger { background: var(--kdp-fox-tint); }
.kdp-chip--danger::before { background: var(--kdp-fox); }
.kdp-chip--info { background: var(--kdp-pond-tint); }
.kdp-chip--info::before { background: var(--kdp-pond); }
.kdp-chip--running { background: var(--kdp-pond-tint); }
.kdp-chip--running::before { background: var(--kdp-pond); animation: kdp-pulse 1.8s var(--kdp-ease-bob) infinite; }
.kdp-chip--solid.kdp-chip--success { background: var(--kdp-lily-pad); }
.kdp-chip--solid.kdp-chip--warning { background: var(--kdp-bill); }
.kdp-chip--solid.kdp-chip--danger { background: var(--kdp-fox); }
.kdp-chip--solid.kdp-chip--info { background: var(--kdp-shallows); }
.kdp-chip--solid::before { background: var(--kdp-deep-water); }

/* ---------- Banners and toasts ---------- */

.kdp-banner { display: flex; align-items: flex-start; gap: var(--kdp-space-3); padding: 14px 16px; border-radius: var(--kdp-radius-md); background: var(--kdp-pond-tint); color: var(--kdp-ink); }
.kdp-banner::before { content: ""; flex: none; width: 10px; height: 10px; margin-top: 7px; border-radius: 50%; background: var(--kdp-pond); }
.kdp-banner__body { flex: 1; display: grid; gap: 2px; }
.kdp-banner__title { font-weight: 700; margin: 0; }
/* The list of a form's errors in its danger banner, each a link to its field (DESIGN.md section 6.4). */
.kdp-banner__list { margin: 0; padding-left: var(--kdp-space-5); font-size: var(--kdp-text-small); }
.kdp-banner--success { background: var(--kdp-lily-tint); }
.kdp-banner--success::before { background: var(--kdp-lily-ink); }
.kdp-banner--warning { background: var(--kdp-bill-tint); }
.kdp-banner--warning::before { background: var(--kdp-bill); }
.kdp-banner--danger { background: var(--kdp-fox-tint); }
.kdp-banner--danger::before { background: var(--kdp-fox); }
.kdp-toast-region { position: fixed; right: var(--kdp-space-5); bottom: var(--kdp-space-5); z-index: var(--kdp-z-toast); display: grid; gap: var(--kdp-space-3); }
.kdp-toast { --kdp-focus: var(--kdp-shallows); display: flex; align-items: center; gap: var(--kdp-space-4); min-width: 320px; max-width: 480px; padding: 14px 16px 14px 20px; border-radius: var(--kdp-radius-md); background: var(--kdp-deep-water); color: var(--kdp-eggshell); box-shadow: var(--kdp-shadow-2); font-size: var(--kdp-text-small); animation: kdp-rise var(--kdp-dur-3) var(--kdp-ease); }
.kdp-toast__text { flex: 1; }
.kdp-toast__action { background: none; border: 0; padding: 4px 8px; border-radius: var(--kdp-radius-sm); color: var(--kdp-shallows); font: 700 14px/1 var(--kdp-font-display); cursor: pointer; }
.kdp-toast__action:hover { background: rgba(156, 203, 255, .14); }

/* ---------- Cards ---------- */

.kdp-card { background: var(--kdp-card); border: 1px solid var(--kdp-line); border-radius: var(--kdp-radius-lg); padding: var(--kdp-space-5); }
.kdp-card--surface { background: var(--kdp-eggshell-2); border-color: transparent; }
.kdp-card--link { display: block; color: inherit; text-decoration: none; transition: border-color var(--kdp-dur-1) var(--kdp-ease); }
.kdp-card--link:hover { border-color: var(--kdp-pond); color: inherit; }
.kdp-stat { display: grid; gap: var(--kdp-space-1); }
.kdp-stat__value { font-family: var(--kdp-font-mono); font-variant-numeric: tabular-nums; font-size: var(--kdp-text-h2); font-weight: 600; letter-spacing: -.02em; line-height: 1.1; }
.kdp-stat__label { font-size: var(--kdp-text-small); color: var(--kdp-ink-2); }

/* ---------- Tabs ---------- */

.kdp-tabs { display: flex; gap: var(--kdp-space-1); border-bottom: 1px solid var(--kdp-line); overflow-x: auto; }
/* A tab can be a link, because a tab is a view and every view has a URL (DESIGN.md section 6.7), so it has no underline. */
.kdp-tab { flex: none; padding: 12px 16px; margin-bottom: -1px; border: 0; border-bottom: 3px solid transparent; background: none; color: var(--kdp-ink-2); font: 600 15px/1 var(--kdp-font-display); text-decoration: none; cursor: pointer; }
.kdp-tab:hover { color: var(--kdp-ink); }
.kdp-tab[aria-selected="true"] { color: var(--kdp-ink); border-bottom-color: var(--kdp-pond); }
.kdp-tab .kdp-count { margin-left: 6px; font-family: var(--kdp-font-mono); font-size: 12px; color: var(--kdp-ink-2); }

/* ---------- Tables ---------- */

.kdp-table-wrap { overflow-x: auto; background: var(--kdp-card); border: 1px solid var(--kdp-line); border-radius: var(--kdp-radius-lg); }
.kdp-table { width: 100%; border-collapse: separate; border-spacing: 0; font-size: var(--kdp-text-small); }
.kdp-table th { position: sticky; top: 0; z-index: 1; text-align: left; padding: 12px 16px; background: var(--kdp-card); border-bottom: 2px solid var(--kdp-deep-water); font: 600 12px/1.2 var(--kdp-font-mono); letter-spacing: .08em; text-transform: uppercase; color: var(--kdp-ink-2); white-space: nowrap; }
.kdp-table td { padding: 12px 16px; border-bottom: 1px solid var(--kdp-line); vertical-align: middle; }
.kdp-table tbody tr:last-child td { border-bottom: 0; }
.kdp-table tbody tr:hover td { background: var(--kdp-eggshell); }
.kdp-table tbody tr[aria-selected="true"] td { background: var(--kdp-pond-tint); }
.kdp-table .kdp-num, .kdp-table th.kdp-num { text-align: right; }
.kdp-table--dense th, .kdp-table--dense td { padding: 8px 12px; }
.kdp-sort { all: unset; cursor: pointer; display: inline-flex; gap: 6px; align-items: center; }
.kdp-sort[aria-sort="ascending"]::after { content: "\2191"; color: var(--kdp-pond); }
.kdp-sort[aria-sort="descending"]::after { content: "\2193"; color: var(--kdp-pond); }
.kdp-table-foot { display: flex; align-items: center; justify-content: space-between; gap: var(--kdp-space-4); padding: 12px 16px; border-top: 1px solid var(--kdp-line); font-size: var(--kdp-text-small); color: var(--kdp-ink-2); }

/* ---------- Tiles: a list of things, with no rules ---------- */

/* The tiles share the list's grid through subgrid, so the facts line up as columns: a title, at most three facts, then the actions.
   The rules and the markup: DESIGN.md section 5, "Tiles". */
.kdp-tiles { container: kdp-tiles / inline-size; list-style: none; margin: 0; padding: 0; display: grid; grid-template-columns: minmax(0, 1.25fr) repeat(3, minmax(0, 1fr)) auto; column-gap: var(--kdp-space-5); row-gap: var(--kdp-space-1); }
.kdp-tiles__head, .kdp-tile { grid-column: 1 / -1; display: grid; grid-template-columns: subgrid; align-items: center; }
.kdp-tiles__head { padding: 0 var(--kdp-space-4) var(--kdp-space-1); font-size: var(--kdp-text-caption); font-weight: 600; color: var(--kdp-ink-2); }
.kdp-tile { position: relative; min-height: 64px; padding: var(--kdp-space-3) var(--kdp-space-4); border-radius: var(--kdp-radius-md); background: var(--kdp-surface); }
.kdp-tile__title { grid-column: 1; display: grid; gap: 2px; min-width: 0; }
.kdp-tile__name { margin: 0; font-size: var(--kdp-text-body); font-weight: 700; line-height: 1.3; overflow-wrap: break-word; }
.kdp-tile__name :where(a) { color: var(--kdp-ink); text-decoration: none; }
.kdp-tile__sub { margin: 0; font-size: var(--kdp-text-small); color: var(--kdp-ink-2); overflow-wrap: break-word; }
.kdp-tile__actions { grid-column: -2; display: flex; align-items: center; justify-content: flex-end; gap: var(--kdp-space-2); }
.kdp-fact { display: grid; gap: 2px; min-width: 0; font-size: var(--kdp-text-small); }
.kdp-fact--wide { grid-column: span 2; }
.kdp-fact__label { font-size: var(--kdp-text-caption); font-weight: 600; color: var(--kdp-ink-2); }
/* On a wide list the head row shows each label once, so a fact's own label is for screen readers only.
   This is kdp-sr-only, repeated, because the narrow rule below must undo it. */
.kdp-tiles .kdp-fact__label { position: absolute; width: 1px; height: 1px; margin: -1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }
.kdp-tile__note { grid-column: span 2; margin: 0; font-size: var(--kdp-text-small); color: var(--kdp-ink-2); }
.kdp-tile__warn { display: inline-flex; align-items: baseline; gap: var(--kdp-space-2); color: var(--kdp-bill-ink); font-weight: 600; }
.kdp-tile__warn::before { content: ""; flex: none; width: 8px; height: 8px; border-radius: 50%; background: var(--kdp-bill); transform: translateY(-1px); }
/* An ID's ground is Eggshell 2, the tile's own, so in a tile it is Card. */
.kdp-tile .kdp-id { background: var(--kdp-card); }
/* Pairs: one fact that holds several entry points, each with its role. */
.kdp-pairs { display: grid; grid-template-columns: auto minmax(0, 1fr); gap: 2px var(--kdp-space-3); margin: 0; }
.kdp-pairs dt { font-family: var(--kdp-font-mono); }
.kdp-pairs dd { margin: 0; }
/* A link tile: the name's link covers the whole tile, and the tile's own controls sit above it.
   The focus ring moves from the link's text to the tile, so it goes round the whole target; it is never removed (DESIGN.md section 6.7). */
.kdp-tile--link .kdp-tile__name a::after { content: ""; position: absolute; inset: 0; border-radius: inherit; }
.kdp-tile--link .kdp-tile__name a:focus-visible { outline: none; }
.kdp-tile--link:has(.kdp-tile__name a:focus-visible) { outline: var(--kdp-focus-ring); outline-offset: 2px; }
/* A status strip's marks open their own windows, so they sit above the link too. */
.kdp-tile--link .kdp-tile__actions > :not(.kdp-tile__chevron), .kdp-tile--link .kdp-id, .kdp-tile--link .kdp-strip { position: relative; z-index: 1; }
.kdp-tile--link:hover .kdp-tile__name a { text-decoration: underline; text-decoration-thickness: 1px; text-underline-offset: 3px; }
.kdp-tile__chevron { color: var(--kdp-ink-2); transition: transform var(--kdp-dur-1) var(--kdp-ease); }
.kdp-tile--link:hover .kdp-tile__chevron { transform: translateX(3px); color: var(--kdp-ink); }
.kdp-tiles-foot { display: flex; flex-wrap: wrap; justify-content: space-between; gap: var(--kdp-space-2) var(--kdp-space-4); padding: var(--kdp-space-3) var(--kdp-space-4) 0; font-size: var(--kdp-text-small); color: var(--kdp-ink-2); }

/* 800px is --kdp-tiles-stack: a container query cannot read a custom property either.
   Change both together.
   It is the list's width, not the screen's, because the side nav takes 240 px of the screen. */
@container kdp-tiles (width < 800px) {
  .kdp-tiles__head { display: none; }
  .kdp-tile { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); gap: var(--kdp-space-3) var(--kdp-space-4); padding: var(--kdp-space-4); }
  .kdp-tile__title, .kdp-tile__note, .kdp-fact--wide, .kdp-tile__actions { grid-column: 1 / -1; }
  .kdp-tile__actions { justify-content: flex-start; }
  .kdp-tile__actions:empty { display: none; }
  .kdp-tiles .kdp-fact__label { position: static; width: auto; height: auto; margin: 0; overflow: visible; clip: auto; white-space: normal; }
  .kdp-tile--link .kdp-tile__title { padding-right: var(--kdp-space-6); }
  .kdp-tile__chevron { position: absolute; top: var(--kdp-space-4); right: var(--kdp-space-4); }
}

/* ---------- Status strip: one mark for each window, oldest first ---------- */

/* A mark's colour is its status, and its kdp-sr-only text and title say the word, because a colour alone is not a status (DESIGN.md section 9).
   The rules and the markup: DESIGN.md section 5, "Status strip". */
.kdp-strip { display: grid; grid-auto-flow: column; grid-auto-columns: minmax(12px, 1fr); gap: var(--kdp-space-1); height: 40px; margin: 0; padding: 0; list-style: none; }
.kdp-strip > li { display: grid; }
.kdp-strip__mark { display: block; border-radius: var(--kdp-radius-sm); background: var(--kdp-line); }
.kdp-strip__mark--success { background: var(--kdp-success); }
.kdp-strip__mark--warning { background: var(--kdp-warning); }
.kdp-strip__mark--danger { background: var(--kdp-danger); }
.kdp-strip__mark--running { background: var(--kdp-running); }
a.kdp-strip__mark:hover { outline: 2px solid var(--kdp-deep-water); outline-offset: 1px; }
/* The window in view is the screen's one highlight. */
.kdp-strip__mark[aria-current] { outline: 3px solid var(--kdp-highlight); outline-offset: 2px; }
.kdp-strip__axis { display: flex; justify-content: space-between; gap: var(--kdp-space-3); margin-top: var(--kdp-space-1); font-family: var(--kdp-font-mono); font-variant-numeric: tabular-nums; font-size: var(--kdp-text-caption); color: var(--kdp-ink-2); }

/* ---------- Charts: an <svg class="kdp-chart"> that the vendored D3 draws ---------- */

/* The rules: DESIGN.md section 6.8. A chart draws only with these classes, never with a style attribute, which the CSP blocks. */
.kdp-chart { display: block; width: 100%; overflow: visible; }
.kdp-chart text { font-family: var(--kdp-font-mono); font-variant-numeric: tabular-nums; font-size: var(--kdp-text-caption); fill: var(--kdp-ink-2); }
.kdp-chart .kdp-chart__strong { fill: var(--kdp-ink); font-weight: 600; }
.kdp-chart__axis path, .kdp-chart__axis line, .kdp-chart__grid line { stroke: var(--kdp-line); }
.kdp-chart__grid path { display: none; }
.kdp-chart__s1 { fill: var(--kdp-series-1); }
.kdp-chart__s2 { fill: var(--kdp-series-2); }
.kdp-chart__s3 { fill: var(--kdp-series-3); }
.kdp-chart__s4 { fill: var(--kdp-series-4); }
/* A reference value drawn across a bar, such as the total that the bar is checked against. */
.kdp-chart__mark { stroke: var(--kdp-series-4); stroke-width: 2; }
/* A legend names each series, for a chart whose marks cannot be labelled directly. */
.kdp-legend { display: flex; flex-wrap: wrap; gap: var(--kdp-space-4); margin: 0; padding: 0; list-style: none; font-size: var(--kdp-text-small); color: var(--kdp-ink-2); }
.kdp-legend > li { display: inline-flex; align-items: center; gap: var(--kdp-space-2); }
.kdp-legend__swatch { flex: none; width: 12px; height: 12px; border-radius: 2px; background: var(--kdp-series-1); }
.kdp-legend__swatch--s2 { background: var(--kdp-series-2); }
.kdp-legend__swatch--s3 { background: var(--kdp-series-3); }
.kdp-legend__swatch--s4 { background: var(--kdp-series-4); }
.kdp-legend__swatch--mark { height: 2px; border-radius: 0; background: var(--kdp-series-4); }

/* ---------- IDs and code ---------- */

.kdp-id { display: inline-flex; align-items: center; gap: 2px; max-width: 100%; padding: 2px 2px 2px 8px; border-radius: var(--kdp-radius-sm); background: var(--kdp-eggshell-2); font: 400 13px/1.6 var(--kdp-font-mono); }
.kdp-id__value { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.kdp-id__copy { flex: none; border: 0; background: none; padding: 2px 6px; border-radius: 4px; color: var(--kdp-pond); font: 600 12px/1.4 var(--kdp-font-display); cursor: pointer; }
.kdp-id__copy:hover { background: var(--kdp-pond-tint); }
.kdp-code { margin: 0; padding: 16px 20px; border-radius: var(--kdp-radius-md); background: var(--kdp-deep-water); color: var(--kdp-eggshell); font: 400 14px/1.6 var(--kdp-font-mono); overflow-x: auto; white-space: pre; }
.kdp-code .k { color: var(--kdp-shallows); }
.kdp-code .s { color: var(--kdp-rubber-duck); }
.kdp-code .c { color: #9AA5B8; }

/* ---------- Dialog ---------- */

.kdp-dialog { width: min(520px, calc(100vw - 32px)); padding: var(--kdp-space-6); border: 0; border-radius: var(--kdp-radius-lg); background: var(--kdp-card); color: var(--kdp-ink); box-shadow: var(--kdp-shadow-2); }
.kdp-dialog::backdrop { background: rgba(12, 28, 61, .55); }
.kdp-dialog__title { margin: 0 0 var(--kdp-space-3); font-size: var(--kdp-text-h3); font-weight: 700; line-height: 1.25; }
.kdp-dialog__body { display: grid; gap: var(--kdp-space-4); }
.kdp-dialog__actions { display: flex; flex-wrap: wrap; justify-content: flex-end; gap: var(--kdp-space-3); margin-top: var(--kdp-space-6); }

/* ---------- Empty and loading ---------- */

.kdp-empty { display: grid; justify-items: center; gap: var(--kdp-space-3); padding: var(--kdp-space-8) var(--kdp-space-5); text-align: center; }
.kdp-empty__art { width: 160px; height: auto; margin-bottom: var(--kdp-space-3); }
.kdp-empty .kdp-hint { max-width: 44ch; }
.kdp-paddling { display: inline-flex; align-items: center; gap: var(--kdp-space-3); color: var(--kdp-ink-2); font-weight: 600; }
.kdp-paddling img { width: 56px; height: auto; display: block; }
.kdp-skeleton { display: block; height: 14px; border-radius: var(--kdp-radius-sm); background: linear-gradient(90deg, var(--kdp-eggshell-2) 0%, var(--kdp-line) 50%, var(--kdp-eggshell-2) 100%); background-size: 200% 100%; animation: kdp-shimmer 1.4s linear infinite; }

/* ---------- Icons: Lucide 1.55.0, inline SVG, coloured by currentColor ---------- */

.kdp-icon { flex: none; width: 20px; height: 20px; stroke: currentColor; stroke-width: 2; fill: none; vertical-align: -4px; }
.kdp-icon--sm { width: 16px; height: 16px; vertical-align: -3px; }
.kdp-btn--sm .kdp-icon { width: 16px; height: 16px; }

/* ---------- Visually hidden, for screen-reader-only text ---------- */

.kdp-sr-only { position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0; }

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

/* The menu button for the side nav shows on small screens only.
   These rules come after the buttons so that they beat kdp-btn--ghost, whose Pond text fails on Deep Water. */
.kdp-appbar__menu { display: none; }
.kdp-appbar__menu, .kdp-appbar__menu:hover { color: var(--kdp-eggshell); }
.kdp-appbar__menu:hover { background: rgba(156, 203, 255, .14); }

/* 640px is --kdp-bp-sm: a custom property cannot be used in a media query.
   Change both together. */
@media (width < 640px) {
  /* An 8 px gap, the app icon in place of the lockup, and icon-only buttons fit the bar to a 360 px screen; a wider gap, the lockup or a label overflows it. */
  .kdp-appbar { gap: var(--kdp-space-2); }
  .kdp-appbar__menu { display: inline-flex; }
  .kdp-appbar__context, .kdp-appbar__user { display: none; }
  .kdp-appbar__button { width: 40px; padding: 0; justify-content: center; }
  .kdp-appbar__button-label, .kdp-appbar__button .kdp-icon--sm { display: none; }
  .kdp-hero { grid-template-columns: 1fr; padding-top: var(--kdp-space-6); }
  .kdp-hero__art { display: none; }
  .kdp-shell__body { grid-template-columns: minmax(0, 1fr); }
  .kdp-sidenav { position: fixed; inset: var(--kdp-appbar-height) auto 0 0; align-self: stretch; width: var(--kdp-sidenav-width); max-width: 100%; height: auto; box-shadow: var(--kdp-shadow-1); }
  .kdp-sidenav:not(:popover-open) { display: none; }
  .kdp-sidenav:popover-open { animation: kdp-slide-in var(--kdp-dur-2) var(--kdp-ease); }
}

/* ---------- Motion ---------- */

@keyframes kdp-spin { to { transform: rotate(360deg); } }
@keyframes kdp-pulse { 0%, 100% { transform: scale(1); opacity: 1; } 50% { transform: scale(.6); opacity: .55; } }
@keyframes kdp-shimmer { from { background-position: 100% 0; } to { background-position: -100% 0; } }
@keyframes kdp-rise { from { transform: translateY(8px); opacity: 0; } to { transform: none; opacity: 1; } }
@keyframes kdp-slide-in { from { transform: translateX(-16px); opacity: 0; } to { transform: none; opacity: 1; } }

@media (prefers-reduced-motion: reduce) {
  .kdp *, .kdp *::before, .kdp *::after { animation-duration: .01ms !important; animation-iteration-count: 1 !important; transition-duration: .01ms !important; }
}
