/* Product-screen scaffolding for the navigable prototype.
 *
 * Structure only, like every stylesheet outside skins/: no literal colour,
 * no [data-skin], no var() fallback. Everything visual is a contract token.
 */

/* -------------------------------------------------------- the phone column */

.rk-screen {
  display: flex;
  flex-direction: column;
  gap: var(--space-4);
  width: 100%;
  max-width: 430px;
  min-height: 100dvh;
  margin-inline: auto;
  padding: var(--space-4) var(--space-4) var(--space-7);
}

/* ------------------------------------------------------- the page's light */

/* One light source behind everything, drifting. It is a sibling of the content
   at z-index -1 rather than a background on .rk-app because a background cannot
   move without repainting; a transformed layer can, on the compositor.
   The layer is not required to cover the viewport at every moment of the drift,
   and sizing it so would cost real compositor memory on a wide screen. It is
   required to *contain* its lights: --bg-page-lights keeps every ellipse inside
   the layer (the contract says so), so the layer's own edge is always at alpha
   zero and a corner of it swinging into view shows nothing at all. What the size
   buys is scale -- the lights and their travel are percentages of this box, so
   170% is how large a light is and how far it goes. `pointer-events: none`
   because a layer over the whole screen must still catch nothing.

   The skin decides whether there is a light at all: with --bg-page-lights at
   `none` the layer paints nothing, and with --bg-lights-drift at `none` there is
   no animation for the compositor to promote a layer for, so a flatly-lit skin
   pays neither the pixels nor the frame. */
.rk-lights {
  position: fixed;
  z-index: -1;
  top: 50%;
  left: 50%;
  width: 170vw;
  height: 170vh;
  translate: -50% -50%;
  pointer-events: none;
  background-image: var(--bg-page-lights);
  background-repeat: no-repeat;
  animation: var(--bg-lights-drift);
}

.rk-room-shell,
.rk-room-shell__now { min-height: 100dvh; }

.rk-room-shell {
  position: relative;
  isolation: isolate;
}

.rk-room-shell--overlay .rk-room-shell__now {
  height: 100dvh;
  overflow: hidden;
  opacity: 0.55;
  filter: blur(2px);
  transform: scale(0.985);
  transform-origin: center;
}

.rk-room-overlay {
  position: fixed;
  z-index: 20;
  inset: 0;
  overflow-y: auto;
  overscroll-behavior: contain;
}

.rk-room-overlay > .rk-screen {
  background-color: var(--bg-page);
  background-image: var(--bg-page-texture);
  box-shadow: var(--edge-shadow-float);
}

.rk-room-overlay--tv {
  background-color: var(--bg-page);
  background-image: var(--bg-page-texture);
}

.rk-room-shell--tv .rk-room-shell__now { visibility: hidden; }

.rk-screen__nav {
  position: sticky;
  bottom: 0;
  margin-top: auto;
}

.rk-screen__bottom {
  position: sticky;
  z-index: 10;
  bottom: 0;
  margin-top: auto;
}

.rk-screen__bottom .rk-screen__nav {
  position: static;
  margin-top: 0;
}

/* A slot is a Turbo target, not a box. The room column is a flex stack with a
   gap, so a slot whose panel is folded has to be its title bar and nothing
   else. */
.rk-panel-slot { display: contents; }

/* -------------------------------------------------------------- playback */

.rk-playback,
.rk-speaker,
.rk-listener {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
}

.rk-volume__heading,
.rk-volume__control {
  display: flex;
  align-items: center;
  gap: var(--space-2);
}

.rk-volume__heading { justify-content: space-between; }
.rk-volume__heading output { font-variant-numeric: tabular-nums; }
.rk-volume__control .rk-meter { flex: 1 1 auto; }
.rk-volume__control .rk-button { flex: 0 0 auto; min-width: var(--control-height); }

.rk-volume__meter { height: var(--control-height); }

.rk-volume__slider {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  margin: 0;
  opacity: 0;
  cursor: pointer;
}

.rk-volume__slider:disabled { cursor: not-allowed; }

.rk-volume__meter:focus-within {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}

.rk-volume__icon {
  display: block;
  width: 16px;
  height: 16px;
  background-color: currentColor;
  -webkit-mask-position: center;
  mask-position: center;
  -webkit-mask-repeat: no-repeat;
  mask-repeat: no-repeat;
  -webkit-mask-size: 16px 16px;
  mask-size: 16px 16px;
}

.rk-volume__icon--down {
  -webkit-mask-image: var(--control-decrement-icon);
  mask-image: var(--control-decrement-icon);
}

.rk-volume__icon--up {
  -webkit-mask-image: var(--control-increment-icon);
  mask-image: var(--control-increment-icon);
}

.rk-tv .rk-volume { display: none; }

/* The waiting surface belongs to TV mode; phones use the people menu. */
.rk-speaker-player-slot > .rk-tv__standby { display: none; }

.rk-playback__clock {
  color: var(--accent);
  font-family: var(--font-readout);
  font-variant-numeric: tabular-nums;
}

.rk-playback__paused,
.rk-playback__disconnected,
.rk-playback__notice:not(:empty) {
  padding: var(--space-2) var(--space-3);
  border: var(--edge-width) solid var(--danger);
  color: var(--danger);
  font-family: var(--font-label);
  font-size: var(--label-size);
}

.rk-playback__paused {
  border-color: var(--accent-secondary);
  color: var(--accent-secondary);
}

.rk-disclosure summary {
  color: var(--ink-muted);
  cursor: pointer;
  font-family: var(--font-label);
  font-size: var(--label-size);
}

.rk-disclosure p { margin-top: var(--space-2); }

/* Two whole-width actions, one under the other: each is a sentence a host has
   to read before pressing, so neither shares a line. */
.rk-danger-actions {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
  min-width: 0;
}

.rk-danger-actions__form { min-width: 0; }

.rk-people-names { overflow-wrap: anywhere; }

.rk-member + .rk-member {
  padding-top: var(--space-3);
  border-top: var(--edge-width) solid var(--edge-hairline);
}

.rk-playback__notice:empty { display: none; }

.rk-speaker__player {
  width: 100%;
  min-width: 200px;
  min-height: 200px;
  aspect-ratio: 16 / 9;
  background: var(--surface-sunken);
}

.rk-speaker__standby { display: none; }

.rk-speaker__player iframe {
  display: block;
  width: 100%;
  height: 100%;
  min-width: 200px;
  min-height: 200px;
  border: 0;
}

.rk-listener__player {
  width: 100%;
  min-width: 200px;
  min-height: 200px;
  aspect-ratio: 16 / 9;
  background: var(--surface-sunken);
}

.rk-listener__mount,
.rk-listener__mount iframe {
  display: block;
  width: 100%;
  height: 100%;
  min-width: 200px;
  min-height: 200px;
  border: 0;
}

.rk-listener__controls {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-2);
}

.rk-listener__controls p { flex: 1 1 260px; }

.rk-listener__status {
  font-family: var(--font-label);
  font-size: var(--label-size);
  text-align: center;
}

.rk-speaker__controls {
  display: flex;
  flex-direction: column;
  gap: var(--space-1);
}

.rk-speaker__status-row {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2);
  align-items: baseline;
}

.rk-speaker__wake-status {
  color: var(--accent-secondary);
  font-family: var(--font-label);
  font-size: var(--label-size);
}

/* ---------------------------------------------------------- room actions */

/* The transport row lives in system/room_now.css. The listener slot is a Turbo
   target that is empty for whichever of the speaker and the listener this
   device is not, and an empty flex child still claims a gap. :has rather than
   :empty because the slot holds the template's whitespace. */
.rk-listener-player-slot:not(:has(*)) { display: none; }

/* ------------------------------------------------------------ landing hero */

.rk-hero {
  display: flex;
  flex-direction: column;
  gap: var(--space-1);
  align-items: center;
  text-align: center;
  padding-top: var(--space-5);
}

.rk-hero__brand {
  color: var(--ink-primary);
  font-family: var(--font-display);
  font-size: var(--text-3xl);
  font-weight: var(--title-weight);
  letter-spacing: var(--title-tracking);
  text-transform: var(--title-transform);
}


/* ---------------------------------------------------------- rooms you're in */

.rk-my-rooms {
  display: grid;
  gap: var(--space-1);
  width: 100%;
  min-width: 0;
  margin: 0;
  padding: 0;
  list-style: none;
}

/* The landing page's list stops at three rows and scrolls past them, so a
   regular does not have to scroll the whole page to reach "Start a party".
   The row height is rebuilt out of the very tokens the row is made of -- its
   padding, its two line boxes, the gap between them -- so a skin that changes
   its type scale moves the cut with it instead of clipping. `auto` is what
   keeps the scrollbar away until there is a fourth room. */
.rk-my-rooms--capped {
  --rk-room-rows: 3;
  --rk-room-row: calc(2 * var(--space-2) + var(--space-1)
                      + (var(--text-md) + 1em) * var(--body-line));
  max-height: calc(var(--rk-room-rows) * var(--rk-room-row)
                   + (var(--rk-room-rows) - 1) * var(--space-1));
  overflow-y: auto;
  overscroll-behavior: contain;
}

.rk-my-room { min-width: 0; }

.rk-my-room__link {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  min-width: 0;
  padding: var(--space-2);
  border-radius: var(--control-radius);
  color: var(--ink-secondary);
  text-decoration: none;
}

.rk-my-room__link:hover {
  background: var(--surface-raised);
  color: var(--ink-primary);
}

.rk-my-room__copy {
  display: flex;
  flex: 1 1 auto;
  flex-direction: column;
  gap: var(--space-1);
  min-width: 0;
}

.rk-my-room__name {
  color: var(--ink-primary);
  font-family: var(--font-display);
  font-size: var(--text-md);
  letter-spacing: var(--title-tracking);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.rk-my-room__meta {
  color: var(--ink-muted);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.rk-my-room__side {
  display: flex;
  flex: 0 0 auto;
  align-items: center;
  gap: var(--space-2);
}

.rk-my-room__listeners {
  color: var(--ink-muted);
  font-family: var(--font-label);
  font-size: var(--text-xs);
  font-variant-numeric: tabular-nums;
  letter-spacing: var(--label-tracking);
  text-transform: var(--label-transform);
}
/* -------------------------------------------------------------- back links */

.rk-backlink {
  align-self: flex-start;
  color: var(--ink-muted);
  font-family: var(--font-label);
  font-size: var(--label-size);
  letter-spacing: var(--label-tracking);
  text-transform: var(--label-transform);
  text-decoration: none;
}

.rk-backlink:hover { color: var(--ink-primary); }

.rk-link { color: var(--accent); }

/* ------------------------------------------------------------------- forms */

.rk-field {
  display: flex;
  flex-direction: column;
  gap: var(--space-1);
}

.rk-input {
  width: 100%;
  height: var(--control-height);
  padding: 0 var(--space-3);
  background: var(--surface-sunken);
  border-style: solid;
  border-width: var(--edge-width);
  border-top-color: var(--edge-inset-top);
  border-left-color: var(--edge-inset-left);
  border-right-color: var(--edge-inset-right);
  border-bottom-color: var(--edge-inset-bottom);
  border-radius: var(--control-radius);
  color: var(--ink-primary);
  font-family: var(--font-body);
  font-size: var(--text-md);
}

.rk-input::placeholder { color: var(--ink-muted); }

.rk-input--multiline {
  height: auto;
  min-height: 10rem;
  padding: var(--space-3);
  resize: vertical;
}

.rk-input:disabled { opacity: 0.7; cursor: not-allowed; }

.rk-input:is(input, textarea):focus-visible {
  outline: none;
  box-shadow: var(--focus-shadow);
  transition: box-shadow var(--motion-fast) var(--ease);
}

.rk-setting-check {
  display: flex;
  align-items: flex-start;
  gap: var(--space-2);
  cursor: pointer;
}

.rk-setting-check > input {
  flex: 0 0 auto;
  width: 1.1rem;
  height: 1.1rem;
  margin-top: var(--space-1);
  accent-color: var(--accent);
}

.rk-setting-check > span { display: flex; flex-direction: column; gap: var(--space-1); }
.rk-setting-check:has(input:disabled) { opacity: 0.7; cursor: not-allowed; }

.rk-skin-picker {
  min-width: 0;
  color: var(--ink-secondary);
}

.rk-skin-picker__summary,
.rk-skin-picker__item {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  min-width: 0;
  padding: var(--space-3);
  background: var(--surface-panel);
  color: var(--ink-secondary);
  text-decoration: none;
  border-style: solid;
  border-width: var(--edge-width);
  border-top-color: var(--edge-top);
  border-left-color: var(--edge-left);
  border-right-color: var(--edge-right);
  border-bottom-color: var(--edge-bottom);
}

/* The closed summary is the part that meets the page, so it frosts on its own;
   the items do not, because --menu carries the filter for all of them. */
.rk-skin-picker__summary {
  list-style: none;
  border-radius: var(--control-radius);
  cursor: pointer;
  -webkit-backdrop-filter: var(--surface-blur);
  backdrop-filter: var(--surface-blur);
}

.rk-skin-picker__summary::-webkit-details-marker { display: none; }

.rk-skin-picker__copy {
  display: flex;
  flex: 1 1 auto;
  flex-direction: column;
  gap: var(--space-1);
  min-width: 0;
}

.rk-skin-picker__name {
  color: var(--ink-primary);
  font-family: var(--font-display);
  font-size: var(--text-md);
  letter-spacing: var(--title-tracking);
}

.rk-skin-picker__tagline {
  color: var(--ink-muted);
  font-family: var(--font-label);
  font-size: var(--label-size);
  letter-spacing: var(--label-tracking);
  text-transform: var(--label-transform);
}

.rk-skin-picker__swatches {
  display: flex;
  flex: 0 0 auto;
  gap: var(--space-1);
}

.rk-skin-picker__swatch {
  width: 18px;
  height: 18px;
  border: var(--edge-width) solid var(--edge-hairline);
  border-radius: var(--edge-radius-sm);
  background: var(--rk-swatch);
}

.rk-skin-picker__chevron {
  flex: 0 0 auto;
  transition: transform var(--motion-base) var(--ease);
}

.rk-skin-picker[open] .rk-skin-picker__chevron { transform: rotate(180deg); }

.rk-skin-picker__menu {
  display: grid;
  gap: var(--space-1);
  margin-top: var(--space-1);
  padding: var(--space-1);
  background: var(--surface-sunken);
  -webkit-backdrop-filter: var(--surface-blur);
  backdrop-filter: var(--surface-blur);
  border: var(--edge-width) solid var(--edge-hairline);
  border-radius: var(--control-radius);
  box-shadow: var(--edge-shadow-float);
}

.rk-skin-picker__item {
  cursor: pointer;
  border-radius: var(--control-radius);
}

.rk-skin-picker__item > input {
  flex: 0 0 auto;
  accent-color: var(--accent);
}

.rk-skin-picker__item--selected,
.rk-skin-picker__item:has(input:checked) {
  background: var(--surface-raised);
  color: var(--ink-primary);
}

.rk-skin-picker__item--selected .rk-skin-picker__name,
.rk-skin-picker__item:has(input:checked) .rk-skin-picker__name { color: var(--accent); }

.rk-skin-picker__item:has(input:disabled) { opacity: 0.7; cursor: not-allowed; }

/* The same disclosure shrunk to footer scale: the summary takes on label
   typography and drops its chrome, while the menu keeps its full shape and
   opens upward, because the footer sits at the bottom of a screen. */

.rk-skin-picker--compact { position: relative; }

.rk-skin-picker--compact .rk-skin-picker__summary {
  gap: var(--space-2);
  padding: 0;
  background: none;
  border: 0;
  border-radius: 0;
  color: var(--ink-muted);
  font-family: var(--font-label);
  font-size: var(--text-xs);
  letter-spacing: var(--label-tracking);
  text-transform: var(--label-transform);
}

.rk-skin-picker--compact .rk-skin-picker__summary:hover { color: var(--ink-primary); }

.rk-skin-picker--compact .rk-skin-picker__summary .rk-skin-picker__copy { flex: 0 1 auto; }

.rk-skin-picker--compact .rk-skin-picker__summary .rk-skin-picker__name {
  color: inherit;
  font: inherit;
  letter-spacing: inherit;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.rk-skin-picker--compact .rk-skin-picker__summary .rk-skin-picker__tagline { display: none; }

.rk-skin-picker--compact .rk-skin-picker__summary .rk-skin-picker__swatch {
  width: 12px;
  height: 12px;
}

.rk-skin-picker--compact .rk-skin-picker__chevron { width: 12px; height: 12px; }

.rk-skin-picker--compact .rk-skin-picker__menu {
  position: absolute;
  bottom: calc(100% + var(--space-2));
  left: 50%;
  z-index: 30;
  width: max-content;
  max-width: min(320px, calc(100vw - var(--space-5)));
  margin: 0;
  transform: translateX(-50%);
  text-align: start;
}


/* ------------------------------------------------------------ result lists */

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

.rk-result {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  padding: var(--space-2) var(--space-3);
  border-bottom: var(--edge-width) solid var(--edge-hairline);
}

.rk-result:last-child { border-bottom: none; }

.rk-result__text { min-width: 0; }

/* The fallback playlist is a list to manage, not a list to read: it is only
   ever the host, deciding what stays. So each song is one line with its own
   remove control on it, rather than a card with the control parked underneath,
   and the list stops at four rows and scrolls past them -- the way the landing
   page's rooms stop at three -- so the import form is still on a 390x720 phone's
   first screen, with the add button under it, however long the playlist grows.

   The row height is rebuilt out of the tokens the row is made of: its padding,
   its two line boxes, the gap between them, its hairline -- against the tap
   target, because on a skin with a small type scale the button is the taller
   of the two. A skin that changes its type scale moves the cut with it instead
   of clipping a row in half. */
.rk-fallback-list {
  --rk-fallback-rows: 4;
  --rk-fallback-line-gap: var(--space-1);
  --rk-fallback-row: calc(2 * var(--space-2) + var(--edge-width)
                          + max(var(--space-7),
                                var(--rk-fallback-line-gap)
                                + (var(--text-md) + var(--text-sm)) * var(--body-line)));
  max-height: calc(var(--rk-fallback-rows) * var(--rk-fallback-row));
  overflow-y: auto;
  overscroll-behavior: contain;
}

/* The row carries the hover, not the control, because the control is a glyph on
   a transparent square: without it, aiming at the trash lights nothing until
   the pointer is already on it. */
.rk-fallback-item { transition: background var(--motion-fast) var(--ease); }

.rk-fallback-item:hover { background: var(--surface-raised); }

/* Two lines of one song, closer than the stack's own rhythm -- and the same gap
   the height formula above counts, so the two cannot drift apart and cut a row
   in half. */
.rk-fallback-item__text { gap: var(--rk-fallback-line-gap); }

.rk-fallback-item__form { flex: 0 0 auto; }

/* The glyph and the target are two boxes: the trash keeps its drawn size while
   the square around it stays a thumb's, out of a structural token so no skin
   can shrink it. It rests in the row's muted ink -- twelve of these should not
   read as twelve warnings -- and answers in --danger under a pointer or a focus
   ring. */
.rk-fallback-item__remove,
.rk-shelf__remove {
  width: var(--space-7);
  height: var(--space-7);
  color: var(--ink-muted);
}

.rk-fallback-item__remove:hover:not(:active),
.rk-fallback-item__remove:focus-visible,
.rk-shelf__remove:hover:not(:active),
.rk-shelf__remove:focus-visible { color: var(--danger); }

/* The saved-playlist shelf is a list of rows like the two above it, so it
   inherits .rk-result's rhythm and only says what is its own. A form is a flex
   item: without this the rename field and the buttons beside it would be
   squeezed by a long playlist name rather than the other way round. */
.rk-shelf__form { flex: 0 0 auto; }

.rk-shelf__rename { min-width: 0; }

.rk-shelf__text { min-width: 0; }

/* Wraps rather than shrinking: on a phone the count belongs under the name, not
   crushed against the delete control. */
.rk-shelf__row { flex-wrap: wrap; row-gap: var(--space-2); }

.rk-shelf__count { flex: 0 0 auto; }

.rk-result__source,
.rk-result-group__label {
  color: var(--accent);
  font-family: var(--font-label);
  font-size: var(--text-xs);
  letter-spacing: var(--label-tracking);
  text-transform: var(--label-transform);
}

.rk-result__thumbnail {
  flex: 0 0 auto;
  width: 78px;
  height: 44px;
  object-fit: cover;
  border-radius: var(--control-radius);
}

.rk-search-empty { padding: var(--space-3); }

/* The room's search results live in a frame that is empty until someone types.
   A flex column still spaces an empty child, so an untouched field would sit
   above a gap the size of a panel. */
.rk-room-search { display: contents; }
.rk-room-search turbo-frame:empty { display: none; }

.rk-result-group + .rk-result-group {
  border-top: var(--edge-width) solid var(--edge-hairline);
}

.rk-result-group[data-version-count]:not([data-version-count="1"]) {
  margin: var(--space-2);
  border: var(--edge-width) solid var(--edge-hairline);
  border-radius: var(--control-radius);
  background: var(--surface-sunken);
}

.rk-result-group__label { padding: var(--space-2) var(--space-3) 0; }

.rk-search-provider-action {
  display: grid;
  gap: var(--space-2);
  padding: var(--space-3);
  border-top: var(--edge-width) solid var(--edge-hairline);
}

/* The pasted link, proving itself. Sunken like every other well so the video
   reads as something Rocola is holding rather than something it has queued. */
.rk-embed {
  width: 100%;
  aspect-ratio: 16 / 9;
  overflow: hidden;
  background: var(--surface-sunken);
  border-style: solid;
  border-width: var(--edge-width);
  border-top-color: var(--edge-inset-top);
  border-left-color: var(--edge-inset-left);
  border-right-color: var(--edge-inset-right);
  border-bottom-color: var(--edge-inset-bottom);
  border-radius: var(--control-radius);
}

.rk-embed iframe {
  display: block;
  width: 100%;
  height: 100%;
  border: 0;
}

/* -------------------------------------------------------- public discovery */

.rk-public-rooms {
  display: grid;
  gap: var(--space-3);
  width: 100%;
  min-width: 0;
  margin: 0;
  padding: 0;
  list-style: none;
}

.rk-public-room {
  width: 100%;
  min-width: 0;
}

.rk-public-room__details {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: var(--space-3);
  min-width: 0;
}

.rk-public-room__now-playing { min-width: 0; }

.rk-public-room .rk-panel__body,
.rk-public-room .rk-panel__chrome,
.rk-public-room .rk-panel__chrome-title { min-width: 0; }

.rk-public-room .rk-panel__chrome {
  height: auto;
  min-height: var(--chrome-height);
  white-space: normal;
}

.rk-public-room .rk-panel__chrome-title-text {
  min-width: 0;
  overflow-wrap: anywhere;
}

.rk-public-room__skin {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-2);
}

.rk-public-room__swatches { display: flex; gap: var(--space-1); }

.rk-public-room__swatch {
  width: 1.25rem;
  aspect-ratio: 1;
  border: var(--edge-width) solid var(--edge-hairline);
  border-radius: var(--control-radius);
  background: var(--rk-swatch);
}

.rk-public-room__track {
  min-width: 0;
  overflow: hidden;
  font-weight: 600;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.rk-public-room__listeners { font-variant-numeric: tabular-nums; }

/* --------------------------------------------------------------- admin */

.rk-admin {
  display: flex;
  flex-direction: column;
  gap: var(--space-4);
  width: min(1100px, 100%);
  min-height: 100dvh;
  margin-inline: auto;
  padding: var(--space-5) var(--space-4);
}

.rk-admin-nav {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-3);
  align-items: center;
}

.rk-admin-stats {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
  gap: var(--space-3);
}

.rk-admin-stat {
  display: flex;
  flex-direction: column;
  gap: var(--space-1);
  padding: var(--space-4);
  color: inherit;
  text-decoration: none;
}

.rk-admin-stat strong {
  color: var(--accent);
  font-family: var(--font-readout);
  font-size: var(--text-3xl);
}

.rk-admin-filter {
  display: flex;
  gap: var(--space-2);
  padding: var(--space-3);
}

.rk-admin-table-wrap { overflow-x: auto; }

.rk-admin-table {
  width: 100%;
  border-collapse: collapse;
  font-size: var(--text-sm);
}

.rk-admin-table th,
.rk-admin-table td {
  padding: var(--space-2) var(--space-3);
  border-bottom: var(--edge-width) solid var(--edge-hairline);
  text-align: start;
  vertical-align: middle;
}

.rk-admin-table th {
  color: var(--ink-muted);
  font-family: var(--font-label);
  letter-spacing: var(--label-tracking);
  text-transform: var(--label-transform);
}

.rk-admin-actions {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2);
}

.rk-admin-moderation {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-1);
}

.rk-admin-moderation .rk-input {
  width: min(16rem, 100%);
}

.rk-suggestion {
  padding: var(--space-3);
  overflow-wrap: anywhere;
}

.rk-suggestion__body { white-space: pre-wrap; }

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

/* -------------------------------------------------------------- user tools */

.rk-user-tools {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  align-items: center;
  gap: var(--space-3);
  max-width: 100%;
  padding: var(--space-2);
  font-family: var(--font-label);
  font-size: var(--text-xs);
  letter-spacing: var(--label-tracking);
  text-transform: var(--label-transform);
}

.rk-user-tools__item {
  display: inline-flex;
  align-items: center;
  gap: var(--space-1);
  color: var(--ink-muted);
  text-decoration: none;
}

.rk-user-tools__item:hover { color: var(--ink-primary); }
.rk-user-tools__item[aria-current] { color: var(--accent); }

.rk-locale-switcher {
  display: inline-flex;
  gap: var(--space-2);
}

/* The theme picker takes a centred row of its own so its upward menu has room
   on both sides of it, whatever else the footer is carrying. */
.rk-user-tools__theme {
  display: flex;
  flex: 1 0 100%;
  justify-content: center;
  min-width: 0;
}
