/* GENERATED from carbon/src/accentUi.css — do not edit here.
 * The au- vocabulary for Mark Docs specimen rendering: the token block
 * plus every au-* rule. Collision-immune by design (no other system
 * ships au-* names); substrate colours come from the HOST page's own
 * --bs-* / --mk-* variables, so specimens wear the docs' light/dark
 * automatically. Regenerate: node scripts/sync-au-css.mjs (in carbon).
 * Synced 2026-08-29 */

:root {
  /* THE ACCENT IS MARK'S, LIVE — consumed from the vendored token
     contract (markTokens.generated.css); fallbacks are the 08-26 seeded
     values, so the look survives a missing sync. When Mark's blue
     moves, `node scripts/sync-mark-tokens.mjs` moves this. */
  --aui-accent: var(--mk-primary-l, #2f6feb);
  --aui-accent-rgb: var(--mk-primary-l-rgb, 47, 111, 235);
  --aui-accent-soft: rgba(var(--mk-primary-l-rgb, 47, 111, 235), 0.08);
  --aui-ring: 0 0 0 0.25rem rgba(var(--mk-primary-l-rgb, 47, 111, 235), 0.18);
  /* SOLID FILLS USE THE ACCENT MUTED TOWARD INK. Mark's blue is drawn for
     a tint, a hairline or a word of text; at full strength across a whole
     button it shouts in a room this quiet. Derived rather than
     hand-picked, so it stays the same blue — just spoken lower — and it
     follows if the accent ever moves. Muting toward ink also RAISES the
     contrast against white (4.6:1 → 5.5:1). */
  --aui-accent-solid: color-mix(in srgb, var(--aui-accent) 85%, var(--bs-body-color));
  /* One radius for the whole app (stock Bootstrap's step; Mark's menu
     default agrees). One control density: the admin wrote btn-sm on 350
     of ~426 buttons — the small size IS the app size. */
  --aui-radius: 0.375rem;
  --aui-control-pad-y: 0.3125rem;
  --aui-control-pad-x: 0.625rem;
  --aui-control-font-size: 0.875rem;
  /* Checks sit well ABOVE Bootstrap's 1em/16px box — a click target,
     not type (settled 21px, Ray 2026-08-29: switch first, then "apply
     the same to the checkbox and radio too"). */
  --mk-check-size: 1.3125rem;
  /* Text fields sit a step ABOVE stock Bootstrap (Ray, 2026-08-28,
     reinstated in the docs context: "make it a little larger again"):
     1rem type — content, not chrome — and padding landing the box at
     40px against Bootstrap's 38. */
  --aui-input-font-size: 1rem;
  --aui-input-pad-y: 0.5rem;
  --aui-input-pad-x: 0.75rem;
  /* THE MARK DOCS SIZE (Ray, 2026-08-28): one nav text size across the
     doc surfaces — measured off the deployed rail at accentmark.ai/docs
     (mark-design docs.css: .nav-link .9rem). The styleguide's left rail
     and its "On this page" both speak it. */
  --mk-docs-nav-size: 0.9rem;
  /* Elevation drawn in ink (Mark's technique): flips with the mode for
     free because the ink does. */
  --aui-shadow:
    0 0.125rem 0.375rem rgba(var(--bs-body-color-rgb), 0.18);
  /* The colours beside the accent. Red destroys; green reports a good
     state (published, live) and never fills a button; amber warns. */
  --aui-go: #198754;
  --aui-go-rgb: 25, 135, 84;
  --aui-danger: #dc3545;
  --aui-danger-rgb: 220, 53, 69;
  --aui-warn: #b26a00;
  --aui-warn-rgb: 178, 106, 0;
}

/* ==================================================== the au vocabulary
 *
 * ACCENT UI'S OWN CLASSES — PROTOTYPE (preview at /cms/ui). `au-` sits
 * beside Mark's `mk-` and speaks the same BEM grammar: `__` element,
 * `--` modifier, single-dash stays Bootstrap's. Two properties the
 * Bootstrap claims above can never have:
 *
 * 1. COLLISION-IMMUNE. No site theme ships an .au-* rule, so nothing
 *    here doubles a class, fights an !important utility, or waits on
 *    the canvas-isolation decision. No .tiptap exclusions either —
 *    site content never wears these names.
 * 2. A CLOSED VOCABULARY. The bare class IS the locked-in default; a
 *    modifier is a documented exception. Call sites stop making design
 *    decisions — there is nothing to choose.
 *
 * Rule order is load-bearing at equal specificity: bare → states →
 * modifiers, so a modifier (e.g. --primary) overrides the open tint and
 * solid variants keep their ground while open.
 */

/* ------------------------------------------------------------- au-btn */

/* Bare = the workhorse neutral (Bootstrap's btn-outline-secondary role):
   ink outline, correct on any ground. */
.au-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.375rem;
  padding: var(--aui-control-pad-y) var(--aui-control-pad-x);
  font-size: var(--aui-control-font-size);
  font-weight: 400;
  line-height: 1.5;
  white-space: nowrap;
  color: var(--au-btn-ink);
  background-color: transparent;
  border: 1px solid color-mix(in srgb, var(--au-btn-ink) 28%, transparent);
  border-radius: var(--aui-radius);
  cursor: pointer;
  user-select: none;
  text-decoration: none;
  /* The two axes, as local variables the modifiers set: --au-btn-ink is
     the MEANING colour, --au-btn-fill is what `--fill` paints with.
     Defaults are ink, so a bare button is the neutral outline. */
  --au-btn-ink: var(--bs-body-color);
  --au-btn-fill: var(--bs-body-color);
  transition:
    transform 0.15s ease,
    box-shadow 0.2s ease,
    background-color 0.2s ease,
    border-color 0.2s ease,
    color 0.2s ease;
}

.au-btn:hover {
  background-color: color-mix(in srgb, var(--au-btn-ink) 6%, transparent);
  border-color: color-mix(in srgb, var(--au-btn-ink) 50%, transparent);
}

.au-btn:focus-visible {
  outline: 0;
  box-shadow: var(--aui-ring);
}

.au-btn:active {
  transform: translateY(1px);
}

.au-btn:disabled {
  opacity: 0.55;
  pointer-events: none;
}

/* Open = a state; colour says so. Filled buttons keep their ground — a
   tint there reads as a demotion. */
.au-btn[aria-expanded='true']:not(.au-btn--fill) {
  background-color: var(--aui-accent-soft);
  border-color: rgba(var(--aui-accent-rgb), 0.45);
  color: var(--aui-accent);
}

/* ------------------------------------------------- the colour axis */

/* These set MEANING only, never treatment: each one just renames the
   button's ink. Outline is the default, so a coloured button is a
   coloured OUTLINE until `--fill` says otherwise. */

/* The highest-priority action — publish, save, create, approve. */
.au-btn--primary {
  --au-btn-ink: var(--aui-accent);
  --au-btn-fill: var(--aui-accent-solid);
}

/* Destructive. Red ink on an outline by default: a Delete sitting in a
   list row is available, not the path. Fill it only where destruction IS
   the path — the confirming button of a delete dialog. */
.au-btn--danger {
  --au-btn-ink: var(--aui-danger);
  --au-btn-fill: var(--aui-danger);
}

/* --------------------------------------------------- the fill axis */

/* OUTLINE IS THE DEFAULT AND FILL IS THE SIGNAL (Ray, 2026-08-27). The
   two axes are orthogonal: colour says what an action MEANS, fill says
   how loudly the surface is asking for it. `--fill` alone is ink — a
   commit with no consequence worth colouring, a wizard's Next.
   This replaced a one-axis enum where --primary happened to be filled
   and --danger happened to be outlined; one modifier doing two jobs is
   how a vocabulary starts lying. */
.au-btn--fill {
  color: #fff;
  background-color: var(--au-btn-fill);
  border-color: var(--au-btn-fill);
}

.au-btn--fill:hover {
  color: #fff;
  background-color: color-mix(in srgb, var(--au-btn-fill) 88%, #000);
  border-color: color-mix(in srgb, var(--au-btn-fill) 88%, #000);
}

.au-btn--fill:active {
  background-color: color-mix(in srgb, var(--au-btn-fill) 80%, #000);
}

/* Navigation wearing a button's box. Border stays (transparent) so a
   toolbar mixing variants stays one height. */
.au-btn--link {
  color: var(--aui-accent);
  background-color: transparent;
  border-color: transparent;
}

.au-btn--link:hover {
  background-color: rgba(var(--bs-body-color-rgb), 0.05);
  border-color: transparent;
}

/* ------------------------------------------------------ mk-app-header */

/* The app's slim top bar — the app-side twin of Mark's mk-site-header.
   One height, hairline foot, never part of the scroll. */
.mk-app-header {
  display: flex;
  align-items: center;
  gap: 1rem;
  flex-shrink: 0;
  height: 2.75rem;
  padding: 0 1rem;
  background-color: var(--bs-body-bg);
  border-bottom: 1px solid rgba(var(--bs-body-color-rgb), 0.12);
}

/* The wordmark — a brand, not a control, so it may carry weight. */
.mk-app-header__brand {
  display: inline-flex;
  align-items: baseline;
  gap: 0.375rem;
  font-size: var(--aui-control-font-size);
  font-weight: 600;
  color: var(--bs-body-color);
  text-decoration: none;
}

/* ------------------------------------------------------------ mk-menu */

.mk-menu {
  min-width: 10rem;
  padding: 0.25rem 0;
  font-size: var(--aui-control-font-size);
  color: var(--bs-body-color);
  background-color: var(--bs-body-bg);
  border: 1px solid rgba(var(--bs-body-color-rgb), 0.12);
  border-radius: var(--aui-radius);
  box-shadow: var(--aui-shadow);
}

.mk-menu__item {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  width: 100%;
  padding: 0.25rem var(--aui-control-pad-x);
  border: 0;
  background-color: transparent;
  color: inherit;
  font-size: inherit;
  text-align: left;
  text-decoration: none;
  cursor: pointer;
}

.mk-menu__item:hover {
  background-color: var(--aui-accent-soft);
}

/* Selected = tint plus accent ink; the aria the DOM already carries is
   the styling hook, with a modifier alias for non-aria rows. */
.mk-menu__item[aria-checked='true'],
.mk-menu__item[aria-selected='true'],
.mk-menu__item--selected {
  background-color: var(--aui-accent-soft);
  color: var(--aui-accent);
}

.mk-menu__item:focus-visible {
  outline: 0;
  box-shadow: var(--aui-ring);
}

.mk-menu__header {
  padding: 0.25rem var(--aui-control-pad-x);
  font-size: 0.66rem;
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--bs-secondary-color);
}

/* The menu as a popup under a trigger (the composed select). Placement
   is the wrapper's job (.mk-select-menu); past ~16rem it scrolls. */
.mk-menu--popup {
  position: absolute;
  top: 100%;
  left: 0;
  right: 0;
  z-index: 1060;
  margin-top: 0.25rem;
  max-height: 16rem;
  overflow-y: auto;
}

/* The check says which — drawn by the aria the row already carries. The
   slot renders on every row so unchecked labels stay aligned. */
.mk-menu__check {
  flex-shrink: 0;
  visibility: hidden;
}

.mk-menu__item[aria-checked='true'] .mk-menu__check,
.mk-menu__item[aria-selected='true'] .mk-menu__check,
.mk-menu__item--selected .mk-menu__check {
  visibility: visible;
}

/* ------------------------------------------------------- au field row */

/* Weight stays whatever the markup says — the skin does not hand out
   boldness. */
.mk-label {
  display: block;
  /* With the field, not the chrome (Ray, 2026-08-28, settled at 1rem):
     the label speaks at the same size as the field it names. */
  font-size: 1rem;
  margin-bottom: 0.25rem;
}

.mk-input,
.mk-select {
  display: block;
  width: 100%;
  padding: var(--aui-input-pad-y) var(--aui-input-pad-x);
  font-size: var(--aui-input-font-size);
  line-height: 1.5;
  color: var(--bs-body-color);
  background-color: var(--bs-body-bg);
  border: 1px solid rgba(var(--bs-body-color-rgb), 0.2);
  border-radius: var(--aui-radius);
}

/* FIELD FOCUS SPEAKS THE ACCENT BY DEFAULT (Ray, 2026-08-29: "blue by
   default and we'll do gray mode later" — flipping the 08-28 monochrome
   default). The ink voice survives as the `ink` palette — see the
   palettes block below the checks. */
.mk-input:focus,
.mk-select:focus {
  outline: 0;
  border-color: rgba(var(--aui-accent-rgb), 0.45);
  box-shadow: var(--aui-ring);
}

/* ONE FACE for "pick from a list", whichever list drops out of it: the
   class sits on a native <select> or on the <button> that triggers an
   mk-menu popup. The extra rules are for the button case — left-set
   text, ellipsis — and are no-ops on the native element. */
.mk-select {
  appearance: none;
  padding-right: 2.25rem;
  text-align: left;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  cursor: pointer;
  background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3e%3cpath fill='none' stroke='%23343a40' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='m2 5 6 6 6-6'/%3e%3c/svg%3e");
  background-repeat: no-repeat;
  background-position: right 0.75rem center;
  background-size: 16px 12px;
}

/* A data-URI cannot read custom properties, so the chevron's ink is
   swapped by hand where the mode flips — Bootstrap's own form-select
   does the same. */
[data-bs-theme='dark'] .mk-select {
  background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3e%3cpath fill='none' stroke='%23e8e8e8' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='m2 5 6 6 6-6'/%3e%3c/svg%3e");
}

/* The composed select — CmsSelectMenu's answer to the OS dropdown,
   spoken in the vocabulary: the same .mk-select face on a <button>,
   an .mk-menu--popup underneath. The wrapper is the anchor. */
.mk-select-menu {
  position: relative;
}

/* Invisible dismisser behind the popup: clicking anywhere else closes.
   The pair sits above the flyout (1050), so a select inside a drawer
   still opens on top. */
.mk-select-menu__backdrop {
  position: fixed;
  inset: 0;
  z-index: 1059;
  border: 0;
  background: transparent;
  cursor: default;
}

.mk-hint {
  margin-top: 0.25rem;
  font-size: 0.8125rem;
  color: var(--bs-secondary-color);
}

/* A SHORT FIELD SIZES TO ITS DATA (Ray, 2026-08-28: integer at 3, price
   at 5 — "to contain"). The width names the expected length in
   characters, declared at the call site because that is a fact about
   the field's CONTENT, not a design choice. The tail term leaves room
   for a number input's spinner. */
.mk-input--fit {
  display: inline-block;
  width: calc(var(--mk-chars, 6) * 1ch + 2 * var(--aui-control-pad-x) + 2px + 1.25rem);
}

/* ONE SPINNER FOR THE WHOLE SYSTEM (Ray, 2026-08-28: "make the up/down
   arrows look the same"). The native webkit spin-buttons are OS-drawn —
   unstylable and auto-hiding — so number faces hide them and every
   stepping field wears the same .mk-stepper pair below. */
.mk-input[type='number'] {
  appearance: textfield;
  -moz-appearance: textfield;
}

.mk-input[type='number']::-webkit-inner-spin-button,
.mk-input[type='number']::-webkit-outer-spin-button {
  -webkit-appearance: none;
  margin: 0;
}

/* The stepper: a field with its own ▴▾ pair, seated in the tail the
   --fit width already reserves. The buttons are companions to the
   place-step behavior — they swallow mousedown (see auBehaviors), so
   the field keeps its caret and a click steps the place you chose. */
.mk-stepper {
  position: relative;
  display: inline-block;
}

.mk-stepper > .mk-input {
  padding-right: 1.5rem;
}

/* Hidden until asked for, like the native spinner it replaces: hover
   or focus reveals the pair; while hidden it takes no clicks. */
.mk-stepper__arrows {
  position: absolute;
  top: 1px;
  right: 1px;
  bottom: 1px;
  width: 1.25rem;
  display: flex;
  flex-direction: column;
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.15s ease;
}

.mk-stepper:hover .mk-stepper__arrows,
.mk-stepper:focus-within .mk-stepper__arrows {
  opacity: 1;
  pointer-events: auto;
}

.mk-stepper__btn {
  flex: 1;
  display: flex;
  align-items: center;
  justify-content: center;
  border: 0;
  padding: 0;
  background: transparent;
  color: var(--bs-secondary-color);
  font-size: 1.3125rem;
  line-height: 1;
  cursor: pointer;
  border-radius: 0.2rem;
}

.mk-stepper__btn:hover {
  color: var(--bs-body-color);
  background: rgba(var(--bs-body-color-rgb), 0.06);
}

/* ----------------------------------------------------------- mk-check */

.mk-check {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  margin: 0;
  font-size: var(--aui-control-font-size);
  cursor: pointer;
}

.mk-check__input {
  appearance: none;
  flex-shrink: 0;
  width: var(--mk-check-size);
  height: var(--mk-check-size);
  margin: 0;
  background-color: var(--bs-body-bg);
  background-repeat: no-repeat;
  background-position: center;
  background-size: contain;
  border: 1px solid rgba(var(--bs-body-color-rgb), 0.35);
  border-radius: 0.25em;
  cursor: pointer;
}

.mk-check__input:focus-visible {
  outline: 0;
  box-shadow: var(--aui-ring);
}

/* CHECKED SPEAKS THE ACCENT BY DEFAULT (Ray, 2026-08-29 — flipping the
   08-28 checked-is-ink default; the monochrome voice survives as the
   `ink` palette below). White glyphs on the accent fill, both modes. */
.mk-check__input:checked {
  background-color: var(--aui-accent);
  border-color: var(--aui-accent);
  background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 20 20'%3e%3cpath fill='none' stroke='%23fff' stroke-linecap='round' stroke-linejoin='round' stroke-width='3' d='m6 10 3 3 6-6'/%3e%3c/svg%3e");
}

.mk-check__input[type='radio'] {
  border-radius: 50%;
}

.mk-check__input[type='radio']:checked {
  background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'%3e%3ccircle r='2' fill='%23fff'/%3e%3c/svg%3e");
}

/* The switch: same input wearing the modifier — the affordance carried
   entirely by presentation. */
.mk-check--switch .mk-check__input {
  width: calc(var(--mk-check-size) * 2);
  border-radius: 2em;
  background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'%3e%3ccircle r='3' fill='rgba%280,0,0,0.25%29'/%3e%3c/svg%3e");
  background-position: left center;
  background-size: contain;
  transition: background-position 0.15s ease-in-out;
}

/* The unchecked knob is drawn in ink too — swapped by hand for the same
   data-URI reason as the select chevron. :not(:checked) keeps this from
   outweighing the checked knob below. */
[data-bs-theme='dark'] .mk-check--switch .mk-check__input:not(:checked) {
  background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'%3e%3ccircle r='3' fill='rgba%28255,255,255,0.35%29'/%3e%3c/svg%3e");
}

.mk-check--switch .mk-check__input:checked {
  background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'%3e%3ccircle r='3' fill='%23fff'/%3e%3c/svg%3e");
  background-position: right center;
}

/* Dark twins for the INK palette's checked glyphs: under `ink`, the
   dark-mode fill is near-white, so the drawn mark flips to the ground
   colour. Scoped to the palette — the blue default keeps white glyphs
   in both modes. Specificity mirrors the light rules, so radio and
   switch still beat the plain check. */
[data-au-palette='ink'][data-bs-theme='dark'] .mk-check__input:checked {
  background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 20 20'%3e%3cpath fill='none' stroke='%230a0c11' stroke-linecap='round' stroke-linejoin='round' stroke-width='3' d='m6 10 3 3 6-6'/%3e%3c/svg%3e");
}

[data-au-palette='ink'][data-bs-theme='dark'] .mk-check__input[type='radio']:checked {
  background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'%3e%3ccircle r='2' fill='%230a0c11'/%3e%3c/svg%3e");
}

[data-au-palette='ink'][data-bs-theme='dark'] .mk-check--switch .mk-check__input:checked {
  background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'%3e%3ccircle r='3' fill='%230a0c11'/%3e%3c/svg%3e");
}

/* A multiple select is a LIST BOX, not a closed face: no chevron, no
   reserved right inset, natural height. Unlike the dropdown the closed
   face refuses to own, a list box's OPTIONS are ours to style — so the
   box breathes and the rows sit at control metrics (Ray, 2026-08-28:
   outline good; more padding, more space between options). */
.mk-select[multiple] {
  background-image: none;
  padding: 0.375rem;
  height: auto;
}

.mk-select[multiple] option {
  padding: 0.3125rem 0.625rem;
  border-radius: 0.25rem;
}

/* Chosen options hold the CONTROL VOICE whether or not the box has
   focus — the browser's grey "inactive selection" paint never shows
   (Ray, 2026-08-28). The gradient is the trick: browsers override an
   option's background-COLOR with system paint but respect a
   background-IMAGE. Accent by default; the ink palette re-voices it in
   the palettes block below. */
.mk-select[multiple] option:checked {
  background: var(--aui-accent)
    linear-gradient(0deg, var(--aui-accent) 0%, var(--aui-accent) 100%);
  color: #fff;
}

/* ---------------------------------------------------------- mk-preview */

/* Markup disclosure under every specimen — Mark Design's code-preview
   brought over: a ghost bar, the panel beneath, and the source read
   from the LIVE example so the markup cannot drift. Weight stays stock
   where Mark bolds; the panel is .mk-code, so it flips with the mode. */
.mk-preview__bar {
  display: flex;
  gap: 0.25rem;
  margin-top: 0.5rem;
}

.mk-preview__btn {
  display: inline-flex;
  align-items: center;
  gap: 0.35rem;
  border: 0;
  background: transparent;
  color: var(--bs-secondary-color);
  font-size: 0.8rem;
  padding: 0.28rem 0.55rem;
  border-radius: 0.25rem;
  cursor: pointer;
}

.mk-preview__btn:hover {
  color: var(--bs-body-color);
  background: rgba(var(--bs-body-color-rgb), 0.06);
}

.mk-preview__btn:focus-visible {
  outline: 0;
  box-shadow: var(--aui-ring);
}

/* --------------------------------------------------------- mk-docs/toc */

/* The docs shape, SEEDED from Mark Design's docs.css (content + 180px
   rail, hairline-left links, sticky rail) — same shape, this file's
   idiom. The rail sticks within the styleguide's scrolling <main>, so
   top is small; below xl the grid collapses and the rail hides. Active
   speaks accent ink + accent hairline, weight stays stock — this file
   does not hand out boldness. */
.mk-docs {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: 2rem;
}

@media (min-width: 1200px) {
  .mk-docs--toc {
    grid-template-columns: minmax(0, 1fr) 180px;
  }
}

.mk-toc {
  position: sticky;
  top: 0.5rem;
  align-self: start;
  max-height: calc(100vh - 6rem);
  overflow-y: auto;
}

.mk-toc__nav {
  display: flex;
  flex-direction: column;
}

/* The left rail's rows at the Mark Docs size. */
.mk-docs-rail .nav-link {
  font-size: var(--mk-docs-nav-size);
}

.mk-toc__link {
  padding: 0.18rem 0 0.18rem 0.8rem;
  font-size: var(--mk-docs-nav-size);
  color: var(--bs-secondary-color);
  border-left: 2px solid rgba(var(--bs-body-color-rgb), 0.12);
  text-decoration: none;
}

.mk-toc__link:hover {
  color: var(--bs-body-color);
}

.mk-toc__link--active {
  color: var(--aui-accent);
  border-left-color: var(--aui-accent);
}

/* Anchored markers land clear of the scrollport's padded top. */
.mk-docs [id] {
  scroll-margin-top: 0.75rem;
}

/* The seat for a SET of checks or radios. The bare class gives each
   control ITS system default: checkboxes stack; RADIOS LAY INLINE
   (Ray, 2026-08-28 — "inline is the default method" for radio; a radio
   set is short by doctrine, ≤ ~5 options, so it earns one line). The
   modifiers force either arrangement — documented exceptions, e.g.
   --stacked for a radio set with long labels. :where() keeps the radio
   default at bare specificity, so the modifiers win by ORDER — which is
   load-bearing here: base, then radio/inline, then stacked last. */
.mk-check-group {
  display: flex;
  flex-direction: column;
  gap: 0.25rem;
}

.mk-check-group:where(:has(.mk-check__input[type='radio'])),
.mk-check-group--inline {
  flex-direction: row;
  flex-wrap: wrap;
  gap: 0.375rem 1rem;
}

.mk-check-group--stacked {
  flex-direction: column;
  flex-wrap: nowrap;
  gap: 0.25rem;
}

/* ------------------------------------------------------------ palettes */

/* THE CONTROL VOICE IS A USER CHOICE (Ray, 2026-08-28; default flipped
   2026-08-29: "make it blue by default and we'll do gray mode later").
   The written default above is the ACCENT; `ink` is the monochrome
   voice — black on white, white on black — kept for the later gray
   mode. A palette re-voices the CONTROL STATES ONLY (field focus,
   checked fills); selection tint, primary buttons and the
   focus-visible ring keep the accent in every palette. The ink dark
   glyph twins live in the checks block, scoped to this palette. */
[data-au-palette='ink'] .mk-input:focus,
[data-au-palette='ink'] .mk-select:focus {
  border-color: rgba(var(--bs-body-color-rgb), 0.6);
  box-shadow: 0 0 0 0.25rem rgba(var(--bs-body-color-rgb), 0.08);
}

[data-au-palette='ink'] .mk-check__input:checked {
  background-color: var(--bs-body-color);
  border-color: var(--bs-body-color);
}

[data-au-palette='ink'] .mk-select[multiple] option:checked {
  background: var(--bs-body-color)
    linear-gradient(0deg, var(--bs-body-color) 0%, var(--bs-body-color) 100%);
  color: var(--bs-body-bg);
}

/* --------------------------------------------------------- date & time */

/* Native date/time inputs, held to the app's metrics. The picker itself
   is the browser's — the same complaint the CmsSelectMenu answers for
   <select>, and the same escape hatch applies if the OS calendar ever
   reads as foreign enough to be worth owning. */
.mk-input[type='date'],
.mk-input[type='time'],
.mk-input[type='datetime-local'] {
  min-height: 2.625rem;
}

.mk-input::-webkit-calendar-picker-indicator {
  opacity: 0.45;
  cursor: pointer;
}

.mk-input::-webkit-calendar-picker-indicator:hover {
  opacity: 0.85;
}

/* --------------------------------------------------------- validation */

/* One invalid treatment, driven by the aria the field already carries —
   no `is-invalid` class to remember, and screen readers and sighted
   readers are told by the same attribute. */
.mk-input[aria-invalid='true'],
.mk-select[aria-invalid='true'] {
  border-color: rgba(var(--aui-danger-rgb), 0.6);
}

.mk-input[aria-invalid='true']:focus,
.mk-select[aria-invalid='true']:focus {
  border-color: var(--aui-danger);
  box-shadow: 0 0 0 0.25rem rgba(var(--aui-danger-rgb), 0.18);
}

.mk-error {
  margin-top: 0.25rem;
  font-size: 0.8125rem;
  color: var(--aui-danger);
}

/* ------------------------------------------------------------ mk-alert */

/* Inline feedback about the surface you are on. Carry role="alert" when
   it interrupts (a failure), role="status" when it merely reports (a
   save) — the role is the difference between announced and polite, and
   it is the markup's job, not the skin's. */
.mk-alert {
  display: flex;
  flex-direction: column;
  gap: 0.125rem;
  padding: 0.625rem 0.875rem;
  font-size: var(--aui-control-font-size);
  color: var(--bs-body-color);
  background-color: rgba(var(--bs-body-color-rgb), 0.03);
  border: 1px solid rgba(var(--bs-body-color-rgb), 0.15);
  border-radius: var(--aui-radius);
}

/* A title is a heading, not a control — it may carry weight. Colour goes
   HERE and not on the body copy: the tint plus a coloured title is enough
   to classify the message, and body text stays as legible as any other. */
.mk-alert__title {
  font-weight: 600;
}

.mk-alert--success {
  background-color: rgba(var(--aui-go-rgb), 0.07);
  border-color: rgba(var(--aui-go-rgb), 0.3);
}

.mk-alert--success .mk-alert__title {
  color: var(--aui-go);
}

.mk-alert--danger {
  background-color: rgba(var(--aui-danger-rgb), 0.06);
  border-color: rgba(var(--aui-danger-rgb), 0.3);
}

.mk-alert--danger .mk-alert__title {
  color: var(--aui-danger);
}

.mk-alert--warning {
  background-color: rgba(var(--aui-warn-rgb), 0.08);
  border-color: rgba(var(--aui-warn-rgb), 0.3);
}

.mk-alert--warning .mk-alert__title {
  color: var(--aui-warn);
}

.mk-alert--info {
  background-color: var(--aui-accent-soft);
  border-color: rgba(var(--aui-accent-rgb), 0.3);
}

.mk-alert--info .mk-alert__title {
  color: var(--aui-accent);
}

/* ----------------------------------------------------------- mk-status */

/* Lifecycle, said in a dot and a word. A CMS shows this on every row it
   lists, so it is a label rather than a badge — no slab, no shouting;
   the dot carries the colour and the word carries the meaning. */
.mk-status {
  display: inline-flex;
  align-items: center;
  gap: 0.375rem;
  font-size: 0.8125rem;
  white-space: nowrap;
  color: var(--bs-secondary-color);
}

.mk-status::before {
  content: '';
  width: 0.5em;
  height: 0.5em;
  border-radius: 50%;
  background-color: currentcolor;
  flex-shrink: 0;
}

.mk-status--live {
  color: var(--aui-go);
}

.mk-status--scheduled {
  color: var(--aui-accent);
}

.mk-status--trashed {
  color: var(--aui-danger);
}

/* In a workflow and waiting on someone — neither live nor merely a draft. */
.mk-status--review {
  color: var(--aui-warn);
}

/* ----------------------------------------------------------- mk-dialog */

/* The native <dialog>: the platform already owns the modal — focus trap,
   inert background, Escape, the top layer — so the skin only dresses it.
   Open with showModal(); a hand-built div is how those four get lost. */
.mk-dialog {
  width: 100%;
  max-width: min(32rem, calc(100vw - 2rem));
  padding: 0;
  color: var(--bs-body-color);
  background-color: var(--bs-body-bg);
  border: 1px solid rgba(var(--bs-body-color-rgb), 0.12);
  border-radius: var(--aui-radius);
  box-shadow: 0 1rem 2rem rgba(0, 0, 0, 0.18);
}

.mk-dialog::backdrop {
  background-color: rgba(0, 0, 0, 0.35);
}

/* ----------------------------------------------------------- mk-flyout */

/* The side panel: a second surface beside the first, for editing without
   losing your place. <aside> plus aria-label — and a real <dialog> when
   it must be modal, since a drawer that traps focus IS a modal. */
.mk-flyout {
  position: fixed;
  inset-block: 0;
  inset-inline-end: 0;
  z-index: 1050;
  display: flex;
  flex-direction: column;
  width: min(22rem, 100vw);
  background-color: var(--bs-body-bg);
  border-left: 1px solid rgba(var(--bs-body-color-rgb), 0.12);
  box-shadow: -0.5rem 0 1.5rem rgba(0, 0, 0, 0.12);
}

.mk-flyout__backdrop {
  position: fixed;
  inset: 0;
  z-index: 1040;
  padding: 0;
  background-color: rgba(0, 0, 0, 0.25);
  border: 0;
  cursor: default;
}

/* Head, body and foot are shared by both overlays — one panel grammar, so
   a drawer and a dialog cannot drift apart. */
.mk-dialog__head,
.mk-flyout__head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  padding: 0.625rem 1rem;
  border-bottom: 1px solid rgba(var(--bs-body-color-rgb), 0.12);
}

.mk-dialog__title,
.mk-flyout__title {
  margin: 0;
  font-size: 1rem;
  font-weight: 600;
}

.mk-dialog__body,
.mk-flyout__body {
  padding: 1rem;
  overflow: auto;
}

.mk-flyout__body {
  flex-grow: 1;
}

.mk-dialog__foot,
.mk-flyout__foot {
  display: flex;
  align-items: center;
  justify-content: flex-end;
  gap: 0.5rem;
  padding: 0.625rem 1rem;
  border-top: 1px solid rgba(var(--bs-body-color-rgb), 0.12);
}

/* ------------------------------------------------------------ mk-table */

/* The list a CMS lives in. A real <table> with <th scope>: rows are data,
   and the moment they are divs the reader loses column association and
   the browser loses its own table semantics. */
.mk-table-wrap {
  overflow-x: auto;
  border: 1px solid rgba(var(--bs-body-color-rgb), 0.12);
  border-radius: var(--aui-radius);
}

.mk-table {
  width: 100%;
  border-collapse: collapse;
  font-size: var(--aui-control-font-size);
}

.mk-table th,
.mk-table td {
  padding: 0.4375rem 0.75rem;
  text-align: left;
  vertical-align: middle;
  border-bottom: 1px solid rgba(var(--bs-body-color-rgb), 0.09);
}

.mk-table thead th {
  font-size: 0.8125rem;
  font-weight: 600;
  color: var(--bs-secondary-color);
  white-space: nowrap;
  background-color: rgba(var(--bs-body-color-rgb), 0.02);
}

.mk-table tbody tr:last-child td {
  border-bottom: 0;
}

.mk-table tbody tr:hover {
  background-color: rgba(var(--bs-body-color-rgb), 0.03);
}

/* Selection is a state, so it takes the accent — and it is announced by
   the same attribute that draws it. */
.mk-table tbody tr[aria-selected='true'] {
  background-color: var(--aui-accent-soft);
}

/* A sortable header is a BUTTON inside the th: the th carries aria-sort
   (which is what assistive tech reads), the button carries the click. */
.mk-table__sort {
  display: inline-flex;
  align-items: center;
  gap: 0.25rem;
  padding: 0;
  font: inherit;
  color: inherit;
  background: none;
  border: 0;
  cursor: pointer;
}

.mk-table__sort:hover {
  color: var(--bs-body-color);
}

.mk-table__sort:focus-visible {
  outline: 0;
  box-shadow: var(--aui-ring);
  border-radius: 0.125rem;
}

.mk-table th[aria-sort] .mk-table__sort {
  color: var(--aui-accent);
}

.mk-table th[aria-sort='ascending'] .mk-table__sort::after {
  content: '↑';
}

.mk-table th[aria-sort='descending'] .mk-table__sort::after {
  content: '↓';
}

/* Right-align the actions column so a row's verbs sit under each other. */
.mk-table__actions {
  display: flex;
  justify-content: flex-end;
  gap: 0.375rem;
  white-space: nowrap;
}

/* An empty list still has to say something — a blank table reads as a
   failure to load. */
.au-empty {
  padding: 2rem 1rem;
  text-align: center;
  color: var(--bs-secondary-color);
  font-size: var(--aui-control-font-size);
}

/* ------------------------------------------------------------- mk-tabs */

.mk-tabs {
  display: flex;
  gap: 0.25rem;
  border-bottom: 1px solid rgba(var(--bs-body-color-rgb), 0.12);
}

.mk-tabs__tab {
  padding: 0.4375rem 0.75rem;
  margin-bottom: -1px;
  font-size: var(--aui-control-font-size);
  color: var(--bs-secondary-color);
  background: none;
  border: 0;
  border-bottom: 2px solid transparent;
  cursor: pointer;
}

.mk-tabs__tab:hover {
  color: var(--bs-body-color);
}

.mk-tabs__tab:focus-visible {
  outline: 0;
  box-shadow: var(--aui-ring);
  border-radius: var(--aui-radius) var(--aui-radius) 0 0;
}

.mk-tabs__tab[aria-selected='true'] {
  color: var(--aui-accent);
  border-bottom-color: var(--aui-accent);
}

/* ------------------------------------------------------------- mk-code */

/* Markup samples in the styleguide. */
.mk-code {
  margin: 0;
  padding: 0.625rem 0.75rem;
  font-size: 0.8125rem;
  color: var(--bs-body-color);
  background-color: rgba(var(--bs-body-color-rgb), 0.04);
  border: 1px solid rgba(var(--bs-body-color-rgb), 0.1);
  border-radius: var(--aui-radius);
  overflow-x: auto;
}
