/* studio-ui.css v1.11.0 — shared look for the studio's internal tools.
   Owner: Platform Engineer. Standard: Roles/Platform Engineer/UI.md.
   Grown from Sprite Manager's gallery and the Art Director app (2026-09-17).

   Use: link this file, then set one accent for your app:
     :root { --ui-accent: #3a9d5d; }   (a dark-theme value can go in the same blocks as below)
   Every class starts with `ui-` so it never collides with an app's own CSS.
   Light and dark both work: OS preference by default, or data-theme="light|dark" on <html>.
   1.0.3: --ui-logo-size (default 44px, was a fixed 32px); chips wrap instead of overflowing.
   1.8.0: --ui-orange, the step between warn and bad (light #ea580c, dark #f97316; Art Director d164263,
   measured ΔE ≥ 34 from warn, bad and the accents). For lights and fills only: 3.56:1 on white fails text.
   1.7.0: .ui-brand, the Role's mascot head joined to its wordmark, top left of the header, in place
   of .ui-logo plus a visible h1 (Art Director, 2026-09-27). The h1 stays, in .ui-visually-hidden.
   1.2.0: a full dark palette can be set once: put --ui-dark-<token> (e.g. --ui-dark-bg) on :root
   beside the light values, and both dark blocks (OS preference and data-theme="dark") use it.
   No more copying the dark block twice (asked for by Sprite Manager).
   1.1.2: a sticky card head stays inside a branded card's stripe; a held drop's status is
   .is-incomplete, not .is-error (both found by Sprite Manager's migration).
   1.1.1: [hidden] always hides, even on a class that sets display (Art Director's pane notice
   showed for everyone because .flex beat the attribute).
   1.1.0: brand theming beyond one accent (--ui-brand-tint, --ui-display-font, .ui-card.is-branded);
   confirm-on-button, pane notice, whole-card drop target, reject dialog (see studio-ui.js).
   Every addition defaults to the 1.0.3 look. */

/* The hidden attribute must win over any class that sets display (1.1.1). */
[hidden] { display: none !important; }

:root {
  --ui-bg: #eef1f5;
  --ui-surface: #ffffff;
  --ui-raised: #f5f7fa;
  --ui-sunken: #e6eaf0;
  --ui-border: #d3d9e2;
  --ui-text: #1b2230;
  --ui-dim: #5b6576;
  --ui-accent: #3552c9;
  --ui-accent-text: #ffffff;
  --ui-ok: #2c7a4b;
  --ui-warn: #9a5b0f;
  --ui-bad: #b3352f;
  --ui-orange: #ea580c;   /* 1.8.0: lights and fills only, never text on white (3.56:1) */
  --ui-ok-soft: #e0f2e7;
  --ui-warn-soft: #fbefdc;
  --ui-bad-soft: #fbe5e3;
  --ui-checker-a: #d9dee6;
  --ui-checker-b: #eef1f5;
  --ui-shadow: 0 6px 24px rgba(20, 28, 45, 0.18);
  --ui-radius: 10px;
  --ui-radius-sm: 6px;
  --ui-logo-size: 44px; /* brand icons carry a safe margin; 44px makes the art read at title height */
  --ui-brand-height: 56px; /* the banner's small sub-label (MANAGER, DIRECTOR) is unreadable at 44 */
  --ui-font: "Segoe UI", system-ui, -apple-system, Roboto, sans-serif;
  --ui-mono: ui-monospace, "Cascadia Mono", Consolas, monospace;
  /* Brand theming, all optional (1.1.0). --ui-brand-tint is deliberately unset: when an app sets it
     (on :root, beside its accent), bg, surface and border take this much of its hue. */
  --ui-brand-tint-amount: 6%;
  color-scheme: light;
}
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    --ui-bg: var(--ui-dark-bg, #14161b);
    --ui-surface: var(--ui-dark-surface, #1d2027);
    --ui-raised: var(--ui-dark-raised, #242831);
    --ui-sunken: var(--ui-dark-sunken, #111317);
    --ui-border: var(--ui-dark-border, #363b47);
    --ui-text: var(--ui-dark-text, #e8eaf0);
    --ui-dim: var(--ui-dark-dim, #9ba2b1);
    --ui-accent: var(--ui-dark-accent, #8198ff);
    --ui-accent-text: var(--ui-dark-accent-text, #0f1220);
    --ui-ok: var(--ui-dark-ok, #6fcf97);
    --ui-warn: var(--ui-dark-warn, #f2b85b);
    --ui-bad: var(--ui-dark-bad, #ff7a73);
    --ui-orange: var(--ui-dark-orange, #f97316);
    --ui-ok-soft: var(--ui-dark-ok-soft, #173024);
    --ui-warn-soft: var(--ui-dark-warn-soft, #36291a);
    --ui-bad-soft: var(--ui-dark-bad-soft, #3a1f1f);
    --ui-checker-a: var(--ui-dark-checker-a, #2c3039);
    --ui-checker-b: var(--ui-dark-checker-b, #1d2027);
    --ui-shadow: var(--ui-dark-shadow, 0 8px 28px rgba(0, 0, 0, 0.5));
    color-scheme: dark;
  }
}
:root[data-theme="dark"] {
  --ui-bg: var(--ui-dark-bg, #14161b);
  --ui-surface: var(--ui-dark-surface, #1d2027);
  --ui-raised: var(--ui-dark-raised, #242831);
  --ui-sunken: var(--ui-dark-sunken, #111317);
  --ui-border: var(--ui-dark-border, #363b47);
  --ui-text: var(--ui-dark-text, #e8eaf0);
  --ui-dim: var(--ui-dark-dim, #9ba2b1);
  --ui-accent: var(--ui-dark-accent, #8198ff);
  --ui-accent-text: var(--ui-dark-accent-text, #0f1220);
  --ui-ok: var(--ui-dark-ok, #6fcf97);
  --ui-warn: var(--ui-dark-warn, #f2b85b);
  --ui-bad: var(--ui-dark-bad, #ff7a73);
  --ui-orange: var(--ui-dark-orange, #f97316);
  --ui-ok-soft: var(--ui-dark-ok-soft, #173024);
  --ui-warn-soft: var(--ui-dark-warn-soft, #36291a);
  --ui-bad-soft: var(--ui-dark-bad-soft, #3a1f1f);
  --ui-checker-a: var(--ui-dark-checker-a, #2c3039);
  --ui-checker-b: var(--ui-dark-checker-b, #1d2027);
  --ui-shadow: var(--ui-dark-shadow, 0 8px 28px rgba(0, 0, 0, 0.5));
  color-scheme: dark;
}

/* ---- page ---- */
.ui-page { margin: 0; background: var(--ui-bg); color: var(--ui-text); font: 14px/1.5 var(--ui-font);
  padding-inline: 16px; padding-block: 20px 64px; }
.ui-page *, .ui-page *::before, .ui-page *::after { box-sizing: border-box; }
.ui-main { max-width: 1100px; margin: 0 auto; display: flex; flex-direction: column; gap: 16px; }
.ui-header { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
.ui-header h1 { font-size: 22px; font-weight: 600; margin: 0; font-family: var(--ui-display-font, var(--ui-font)); }
/* 1.10.0: notifications behind a bell (notifications() in studio-ui.js). Nothing pops up over the page;
   the count is the only signal, and opening the pane marks everything read. */
.ui-notif { position: relative; margin-left: auto; }
.ui-notif-btn { position: relative; display: inline-flex; align-items: center; gap: 6px; }
.ui-notif-icon { display: block; flex: none; }
.ui-notif-count { min-width: 18px; padding: 0 5px; border-radius: 999px; font-size: 11px; font-weight: 700;
  line-height: 18px; text-align: center; color: var(--ui-surface); background: var(--ui-bad); }  /* 1.10.1: surface, not #fff: 6.43:1 in dark (Art Director) */
.ui-notif-count[hidden] { display: none; }
.ui-notif-panel { position: absolute; top: calc(100% + 6px); right: 0; z-index: 900;
  width: min(380px, calc(100vw - 32px)); max-height: min(70vh, 520px); overflow: auto; box-shadow: var(--ui-shadow); }
.ui-notif-panel[hidden] { display: none; }
.ui-notif-list { margin: 8px 0 0; padding: 0; list-style: none; }
.ui-notif-list li { margin: 0; padding: 8px 0 8px 11px; border-top: 1px solid var(--ui-border);
  border-left: 3px solid transparent; overflow-wrap: anywhere; }
.ui-notif-list li.is-unread { border-left-color: var(--ui-accent); }
.ui-notif-list li[data-kind="bad"] { color: var(--ui-bad); }
.ui-notif-empty { margin: 8px 0 0; }
.ui-notif-empty[hidden] { display: none; }
.ui-logo { width: var(--ui-logo-size); height: var(--ui-logo-size); flex: none; }
.ui-brand { display: block; height: var(--ui-brand-height); width: auto; max-width: 100%; flex: none; }
/* Kept for screen readers and the page outline, not shown: the banner already says it. */
.ui-visually-hidden { position: absolute !important; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0 0 0 0); clip-path: inset(50%); white-space: nowrap; border: 0; }
.ui-version { font: 11px var(--ui-mono); color: var(--ui-dim); }
.ui-lede { color: var(--ui-dim); margin: 2px 0 0; max-width: 70ch; }
.ui-section-title { font-size: 12px; font-weight: 600; text-transform: uppercase; letter-spacing: .08em;
  color: var(--ui-dim); margin: 20px 0 4px; }
.ui-spacer { margin-left: auto; }
.ui-row { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
.ui-grid { display: grid; gap: 14px; grid-template-columns: repeat(auto-fill, minmax(240px, 1fr)); }
.ui-hint { font-size: 12px; color: var(--ui-dim); }
.ui-mono { font-family: var(--ui-mono); }
/* Links read in the app's own accent, as the Art Director's style guides expect — not the browser's
   default blue. A link styled as a button keeps the button's colours. (Job Scout found it, 2026-09-18.)
   The accent marks actions and inline references, not headings: a title that is itself a link (a card
   or feed title) takes .ui-link-quiet and stays in the text colour, so the card's one accent action
   still stands out. Use the class; don't out-specify the rule, which may change. (Art Director.) */
.ui-page a:not(.ui-btn):not(.ui-link-quiet) { color: var(--ui-accent); }
.ui-page a.ui-link-quiet { color: inherit; text-decoration: none; }
.ui-page a.ui-link-quiet:hover { text-decoration: underline; }

/* ---- cards ---- */
.ui-card { background: var(--ui-surface); border: 1px solid var(--ui-border); border-radius: var(--ui-radius);
  padding: 14px 16px; }
.ui-card.is-accent { border-color: var(--ui-accent); }
/* A card that belongs to a brand wears its colour as a stripe, as the Art Director app's briefs do.
   --ui-card-accent lets one page show several brands; padding keeps content where it was. */
.ui-card.is-branded { border-left: 4px solid var(--ui-card-accent, var(--ui-accent)); padding-left: 13px; }
/* The sticky head's negative margin assumed 16px of padding; on a branded card it would cover the
   stripe (1.1.2). */
.ui-card.is-branded > .ui-card-head.is-sticky { margin-left: -13px; padding-left: 13px; border-top-left-radius: 0; }
.ui-card.is-collapsed .ui-card-body { display: none; }
.ui-card-head { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
.ui-card-head.is-sticky { position: sticky; top: env(safe-area-inset-top, 0px); z-index: 3;
  background: var(--ui-surface); margin: -14px -16px 10px; padding: 12px 16px 8px;
  border-radius: var(--ui-radius) var(--ui-radius) 0 0; border-bottom: 1px solid var(--ui-border); }
.ui-card-title { font-weight: 600; font-size: 15px; }
.ui-card-body { margin-top: 10px; display: flex; flex-direction: column; gap: 10px; }
.ui-step { font-size: 11px; color: var(--ui-dim); text-transform: uppercase; letter-spacing: .08em; margin: 6px 0 0; }

/* ---- chips (status and labels) ---- */
.ui-chip { display: inline-flex; align-items: center; gap: 4px; font-size: 12px; line-height: 1.6;
  padding: 0 9px; border-radius: 999px; border: 1px solid var(--ui-border); color: var(--ui-dim);
  background: transparent; white-space: normal; overflow-wrap: anywhere; max-width: 100%; }
.ui-chip.is-accent { color: var(--ui-accent); border-color: var(--ui-accent); }
.ui-chip.is-ok { color: var(--ui-ok); border-color: currentColor; background: var(--ui-ok-soft); }
.ui-chip.is-warn { color: var(--ui-warn); border-color: currentColor; background: var(--ui-warn-soft); }
.ui-chip.is-bad { color: var(--ui-bad); border-color: currentColor; background: var(--ui-bad-soft); }
button.ui-chip { cursor: pointer; font: inherit; font-size: 12px; }
button.ui-chip[aria-pressed="true"] { color: var(--ui-accent); border-color: var(--ui-accent); }

/* ---- buttons ---- */
.ui-btn { font: inherit; color: var(--ui-text); background: var(--ui-raised); border: 1px solid var(--ui-border);
  border-radius: 8px; padding: 6px 14px; cursor: pointer; }
.ui-btn:hover { border-color: var(--ui-dim); }
.ui-btn:disabled { opacity: .5; cursor: default; }
.ui-btn.is-primary { background: var(--ui-accent); border-color: var(--ui-accent); color: var(--ui-accent-text); font-weight: 600; }
.ui-btn.is-ok { color: var(--ui-ok); border-color: var(--ui-ok); background: var(--ui-ok-soft); font-weight: 600; }
.ui-btn.is-bad { color: var(--ui-bad); border-color: var(--ui-bad); background: var(--ui-bad-soft); }
.ui-btn.is-ghost { background: transparent; }
.ui-btn.is-small { font-size: 12px; padding: 3px 9px; }
/* The result shown on the button that was clicked (StudioUI.flash; UI.md "Confirm where the click happened"). */
.ui-btn.is-flash-ok { color: var(--ui-ok); border-color: var(--ui-ok); }
.ui-btn.is-flash-bad { color: var(--ui-bad); border-color: var(--ui-bad); }
/* 1.10.2: on a filled button the flash text sat on the accent, at 1.15:1 and 1.00:1 (YouTube Caption Bot).
   The soft ok/bad ground gives 4.51 / 5.02 light, 7.44 / 5.93 dark (Art Director, OK 2026-10-09). */
.ui-btn.is-primary.is-flash-ok { background: var(--ui-ok-soft); }
.ui-btn.is-primary.is-flash-bad { background: var(--ui-bad-soft); }
/* An <a class="ui-btn"> ("Open listing ↗") would otherwise keep the anchor's underline and inline box. */
a.ui-btn { display: inline-block; text-decoration: none; }
.ui-page :focus-visible { outline: 2px solid var(--ui-accent); outline-offset: 2px; }

/* ---- tabs ---- */
.ui-tabs { display: flex; flex-wrap: wrap; gap: 6px; }
.ui-tab { font: inherit; font-size: 14px; cursor: pointer; border: 1px solid var(--ui-border);
  background: var(--ui-surface); color: var(--ui-text); border-radius: 999px; padding: 4px 14px; }
.ui-tab[aria-selected="true"] { background: var(--ui-text); color: var(--ui-bg); border-color: var(--ui-text); }

/* ---- form fields ---- */
.ui-label { display: block; font-size: 12px; color: var(--ui-dim); margin: 0 0 3px; }
.ui-input, .ui-select, .ui-textarea { font: inherit; color: var(--ui-text); background: var(--ui-sunken);
  border: 1px solid var(--ui-border); border-radius: var(--ui-radius-sm); padding: 6px 8px; max-width: 100%; }
.ui-textarea { width: 100%; min-height: 84px; resize: vertical; }

/* ---- prompt / code block ---- */
.ui-prompt { white-space: pre-wrap; background: var(--ui-sunken); border: 1px solid var(--ui-border);
  border-radius: var(--ui-radius); padding: 10px 12px; margin: 0; font: 12.5px/1.6 var(--ui-mono);
  max-height: 280px; overflow: auto; }

/* ---- images ---- */
.ui-checker { background-color: var(--ui-checker-b);
  background-image: linear-gradient(45deg, var(--ui-checker-a) 25%, transparent 25%),
    linear-gradient(-45deg, var(--ui-checker-a) 25%, transparent 25%),
    linear-gradient(45deg, transparent 75%, var(--ui-checker-a) 75%),
    linear-gradient(-45deg, transparent 75%, var(--ui-checker-a) 75%);
  background-size: 16px 16px; background-position: 0 0, 0 8px, 8px -8px, -8px 0; }
.ui-thumb { display: block; max-width: 100%; object-fit: contain; border: 1px solid var(--ui-border); border-radius: var(--ui-radius-sm); }
.ui-thumb.is-pass { border: 3px solid var(--ui-ok); }
.ui-thumb.is-fail { border: 3px solid var(--ui-bad); }
.ui-thumb.is-now { border: 3px solid var(--ui-warn); }
.ui-new { outline: 3px solid var(--ui-accent); outline-offset: 3px; animation: ui-arrived 1.2s ease-out 3; }
@keyframes ui-arrived { 50% { outline-color: transparent; } }

/* ---- drop zone (drag-and-drop upload) ---- */
.ui-drop { border: 2px dashed var(--ui-border); border-radius: var(--ui-radius); padding: 12px 14px;
  display: flex; gap: 10px; align-items: center; flex-wrap: wrap; }
.ui-drop.is-armed { border-color: var(--ui-accent); background: var(--ui-raised); }
.ui-drop.is-busy { opacity: .6; pointer-events: none; }
.ui-drop-status { margin-left: auto; font-weight: 600; }
.ui-drop-status.is-error { color: var(--ui-bad); }
.ui-drop-status.is-incomplete { color: var(--ui-warn); }
.ui-drop.is-target { border-style: solid; border-color: var(--ui-accent); }  /* where a paste goes */
.ui-drop.is-incomplete { border-color: var(--ui-warn); }                      /* files kept, a detail missing */
/* A whole card as the drop target (StudioUI.dropZone with opts.card): the overlay says where the
   files will go, so a drop never lands somewhere unexpected (Art Director app, 2026-09-18). */
.ui-drop-card { position: relative; }
.ui-drop-card.is-dropping { outline: 3px dashed var(--ui-accent); outline-offset: 4px; }
.ui-drop-card.is-dropping::after { content: attr(data-drop-label); position: absolute; inset: 0; z-index: 4;
  display: grid; place-items: center; background: var(--ui-raised); border-radius: inherit;
  font-weight: 700; font-size: 1.2rem; color: var(--ui-text); pointer-events: none;
  white-space: pre-line; text-align: center; padding: 12px; }
.ui-drop-card.is-dropping.is-incomplete-drop { outline-color: var(--ui-warn); }
.ui-drop-card.is-dropping.is-incomplete-drop::after { color: var(--ui-warn); }

/* ---- empty / notice ---- */
.ui-empty { background: var(--ui-surface); border: 1px dashed var(--ui-border); border-radius: var(--ui-radius);
  padding: 24px; text-align: center; color: var(--ui-dim); }
.ui-notice { border-radius: var(--ui-radius-sm); padding: 8px 10px; background: var(--ui-warn-soft); color: var(--ui-text);
  border: 1px solid var(--ui-warn); }
.ui-notice.is-bad { background: var(--ui-bad-soft); border-color: var(--ui-bad); }
.ui-notice.is-ok { background: var(--ui-ok-soft); border-color: var(--ui-ok); }
.ui-pane-notice, .ui-notice.is-dismissible { display: flex; align-items: center; gap: 8px; }
.ui-notice.is-dismissible + .ui-notice.is-dismissible, .ui-notice.is-dismissible + .ui-pane-notice { margin-top: 8px; }
.ui-pane-notice a { font-weight: 600; overflow-wrap: anywhere; }
.ui-pane-notice .ui-btn, .ui-notice.is-dismissible .ui-btn { margin-left: auto; }

/* ---- owner's note on a reviewed item (1.4.0) ----
   The Owner's comment on an upload is read BEFORE the item is measured or
   judged (Owner via the Art Director, 2026-09-20). So the note sits above the
   image and above any readouts — never below, never behind a click, never in a
   folded panel. Acceptance test: if a review surface can be completed without
   the note having been seen, it is wrong.

   Two variants, because the reader and the decision differ (Owner's
   correction, 2026-09-20) — deliberately not one component with a mode flag:
     .is-deciding  an instruction to whoever is about to accept or reject on
                   the Owner's behalf (a still sprite, decided on first upload)
     .is-judging   the Owner's own note to themselves while judging by eye
                   (animation frames), in a narrow per-option column
   Render nothing when there is no note: an empty note is a piece of furniture
   that teaches the eye to skip the place the note will appear.
   Designed and proven in Sprite Manager's gallery on both placements; applied
   here by the PM because that project cannot write to lib/. */
.ui-owner-note { display: block; margin: 0 0 8px; padding: 6px 10px;
  border-left: 3px solid var(--ui-accent); border-radius: 0 var(--ui-radius-sm) var(--ui-radius-sm) 0;
  background: var(--ui-raised); color: var(--ui-text); font-size: 13px; line-height: 1.45;
  overflow-wrap: anywhere; }
.ui-owner-note > .ui-owner-note-label { display: block; font-size: 11px; font-weight: 700;
  letter-spacing: .04em; text-transform: uppercase; color: var(--ui-dim); margin-bottom: 2px; }
.ui-owner-note > .ui-owner-note-text { display: block; font-style: italic; }
/* Deciding: full card width, and heavier, because it is the instruction the
   decision will be measured against. */
.ui-owner-note.is-deciding { border-left-width: 4px; padding: 8px 12px; font-size: 14px; }
/* Judging: sits in a ~200px close-up column beside the readouts, so it must
   stay legible when narrow and must not read as one more status line. */
.ui-owner-note.is-judging { font-size: 12px; padding: 5px 8px; }
.ui-owner-note.is-judging > .ui-owner-note-label { font-size: 10px; }

/* ---- disclosure ---- */
details.ui-details > summary { cursor: pointer; color: var(--ui-dim); padding: 6px 0; }

/* ---- dialog ---- */
dialog.ui-dialog { background: var(--ui-surface); color: var(--ui-text); border: 1px solid var(--ui-border);
  border-radius: 12px; padding: 18px 20px; width: min(560px, 92vw); box-shadow: var(--ui-shadow); }
dialog.ui-dialog::backdrop { background: rgba(0, 0, 0, .55); }
dialog.ui-dialog h3 { margin: 0 0 6px; font-size: 17px; font-family: var(--ui-display-font, var(--ui-font)); }
.ui-dialog-actions { display: flex; justify-content: flex-end; gap: 8px; margin-top: 12px; }
/* Reject-with-reasons (StudioUI.rejectDialog): picked reasons read as "bad", not as a filter. */
.ui-reasons { display: flex; flex-wrap: wrap; gap: 8px; margin: 12px 0; }
.ui-reasons button.ui-chip[aria-pressed="true"] { color: var(--ui-bad); border-color: var(--ui-bad); background: var(--ui-bad-soft); }
.ui-reject-need { color: var(--ui-bad); margin: 6px 0 0; }

/* ---- toast (see studio-ui.js) ---- */
.ui-toast { position: fixed; left: 50%; bottom: calc(20px + env(safe-area-inset-bottom, 0px));
  transform: translateX(-50%) translateY(20px); background: var(--ui-text); color: var(--ui-bg);
  padding: 8px 16px; border-radius: 8px; font-size: 13px; opacity: 0; pointer-events: none;
  transition: opacity .15s, transform .15s; z-index: 1000; box-shadow: var(--ui-shadow); }
.ui-toast.is-shown { opacity: 1; transform: translateX(-50%) translateY(0); }
.ui-toast.is-bad { background: var(--ui-bad); color: #fff; }

/* ---- display face: one per app, for its main title (UI.md "Type") ---- */
.ui-display { font-family: var(--ui-display-font, var(--ui-font)); }

/* ---- debug overlay (root AGENTS.md: debug overlays) ---- */
.ui-debug-toggle.is-active { border-color: var(--ui-warn); color: var(--ui-warn); }
.ui-coord { display: none; position: absolute; top: 4px; left: 4px; z-index: 2; pointer-events: none;
  background: rgba(0, 0, 0, .75); color: #7f7; font: 11px var(--ui-mono); padding: 2px 6px; border-radius: 3px; }
body.ui-debug .ui-coord { display: block; }
/* element ids, drawn by StudioUI.labelElements (1.5.0) */
#ui-debug-layer { position: absolute; top: 0; left: 0; width: 0; height: 0; z-index: 9999; pointer-events: none; }
.ui-debug-badge { position: absolute; transform: translate(-2px, -2px); pointer-events: none;
  background: rgba(0, 0, 0, .8); color: #7f7; font: 10px/1 var(--ui-mono); padding: 2px 4px; border-radius: 3px;
  white-space: nowrap; }

@media (max-width: 560px) {
  .ui-header h1 { font-size: 19px; }
  .ui-card { padding: 12px; }
  .ui-card-head.is-sticky { margin: -12px -12px 10px; padding-inline: 12px; }
  .ui-card.is-branded { padding-left: 9px; }
  .ui-card.is-branded > .ui-card-head.is-sticky { margin-left: -9px; padding-left: 9px; }
  .ui-drop-card.is-dropping::after { font-size: 1rem; padding: 6px; }
}
@media (prefers-reduced-motion: reduce) {
  .ui-new { animation: none; }
  .ui-toast { transition: none; }
}

/* ---- brand tint (1.1.0) ----
   Mixing a colour with itself returns it unchanged, so while --ui-brand-tint is unset these rules
   paint exactly the 1.0.3 colours. Behind @supports because a var() inside an unsupported
   color-mix() would blank the background instead of falling back. */
@supports (color: color-mix(in srgb, red, blue)) {
  :root {
    --ui-bg-tinted: color-mix(in srgb, var(--ui-bg), var(--ui-brand-tint, var(--ui-bg)) var(--ui-brand-tint-amount));
    --ui-surface-tinted: color-mix(in srgb, var(--ui-surface), var(--ui-brand-tint, var(--ui-surface)) var(--ui-brand-tint-amount));
    --ui-border-tinted: color-mix(in srgb, var(--ui-border), var(--ui-brand-tint, var(--ui-border)) calc(var(--ui-brand-tint-amount) * 3));
  }
  .ui-page { background: var(--ui-bg-tinted); }
  .ui-card, .ui-card-head.is-sticky, .ui-tab, .ui-empty, dialog.ui-dialog {
    background: var(--ui-surface-tinted); border-color: var(--ui-border-tinted); }
  .ui-drop { border-color: var(--ui-border-tinted); }
  .ui-drop-card.is-dropping::after { background: color-mix(in srgb, var(--ui-raised) 88%, transparent); }
}
