/*
 * The app shell — the ink rail on the left, the ivory page on the right — and
 * every dashboard panel, on the Kairo design system.
 *
 * The aliases below map the shell's own names onto the system's tokens. The
 * rail and the headline bands are the system's ink regions: ivory type, lime
 * for the one thing on them that is lit. Everything on the ivory page is ink,
 * with violet where a hand should land and nothing lime — lime on a light
 * canvas is the one pairing the system forbids outright. Figures and headings
 * are set in Space Grotesk, everything read in Manrope, and dates, ids and
 * measurement in DM Mono at normal case: the metadata voice, never a costume.
 */

:root {
  --ink: var(--k-color-ink);
  --paper: var(--k-color-ivory);
  --card: var(--k-color-paper);
  --line: var(--k-color-line);
  --accent: var(--k-color-violet);
  --accent-deep: var(--k-color-violet-deep);
  --lime: var(--k-color-lime);
  --green: var(--k-color-success);
  --sidebar: 252px;
  --topbar: 64px;
}

/* Below this the rail leaves the flow and slides in over the panel instead. */
@media (width <= 920px) {
  :root {
    --sidebar: 0px;
  }
}

body.dashboard {
  color: var(--ink);
  font-family: var(--sans);
  background: var(--paper);
}

.app-shell {
  min-height: 100vh;
}

/* Left column */

.sidebar {
  position: fixed;
  inset: 0 auto 0 0;
  z-index: 30;
  display: flex;
  flex-direction: column;
  width: var(--sidebar);
  color: var(--k-color-ivory);
  background-color: var(--ink);
  border-right: 1px solid var(--ink-line);
}

/* Lime is the focus colour on ink, as the system's dark theme has it. */
.sidebar :focus-visible {
  outline-color: var(--lime);
}

.brand {
  display: flex;
  align-items: center;
  gap: 10px;
  height: var(--topbar);
  padding: 0 20px;
  border-bottom: 1px solid var(--ink-line);
}

.brand > div:last-child {
  display: flex;
  flex-direction: column;
}

.brand strong {
  font-family: var(--display);
  font-size: 20px;
  font-weight: 700;
  letter-spacing: -0.03em;
  line-height: 1.1;
}

.brand span {
  font-size: 12px;
  color: var(--ink-muted);
}

/* The orbit mark, drawn in CSS so it takes the colour of the surface it sits
   on: lime here on the rail, and again in the ink bands. The image file of
   the same mark is violet, for the light pages. */
.neo-mark {
  position: relative;
  flex-shrink: 0;
  width: 30px;
  height: 30px;
  border: 1px solid color-mix(in srgb, var(--lime) 50%, transparent);
  border-radius: 50%;
}

.neo-mark::before,
.neo-mark::after,
.neo-mark i {
  content: "";
  position: absolute;
  border-radius: 50%;
}

.neo-mark::before {
  inset: 6px;
  border: 1px solid var(--lime);
}

.neo-mark::after {
  inset: 11px;
  background: var(--lime);
}

.neo-mark i {
  width: 3px;
  height: 3px;
  background: var(--lime);
}

.neo-mark i:first-child { top: 2px; left: 14px; }
.neo-mark i:nth-child(2) { right: 2px; bottom: 5px; }
.neo-mark i:nth-child(3) { bottom: 3px; left: 5px; }

/* Brand switcher — only rendered when the user holds more than one brand. */

.brand-switcher {
  position: relative;
  margin: 16px 10px 0;
}

.brand-switcher__current {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  padding: 9px 12px;
  background: var(--ink-raised);
  border: 1px solid var(--ink-line);
  border-radius: var(--k-radius-control);
  cursor: pointer;
  list-style: none;
}

/* Safari draws its own triangle from the summary's default marker. */
.brand-switcher__current::-webkit-details-marker {
  display: none;
}

.brand-switcher__current:hover,
.brand-switcher[open] .brand-switcher__current {
  border-color: color-mix(in srgb, var(--lime) 45%, transparent);
}

.brand-switcher__current small {
  display: block;
  font-size: 13px;
  font-weight: 700;
  color: var(--ink-muted);
}

.brand-switcher__current strong {
  display: block;
  overflow: hidden;
  max-width: 150px;
  font-size: 14px;
  font-weight: 600;
  white-space: nowrap;
  text-overflow: ellipsis;
  color: var(--k-color-ivory);
}

.brand-switcher__caret {
  flex-shrink: 0;
  width: 7px;
  height: 7px;
  margin-top: -3px;
  border-right: 1.5px solid var(--ink-muted);
  border-bottom: 1.5px solid var(--ink-muted);
  transform: rotate(45deg);
}

.brand-switcher[open] .brand-switcher__caret {
  margin-top: 3px;
  transform: rotate(-135deg);
}

.brand-switcher__menu {
  position: absolute;
  z-index: 40;
  right: 0;
  left: 0;
  margin: 6px 0 0;
  padding: 6px;
  list-style: none;
  background: var(--ink-raised);
  border: 1px solid var(--ink-line);
  border-radius: var(--k-radius-control);
  box-shadow: var(--k-shadow-raised);
}

.brand-switcher__option {
  display: block;
  overflow: hidden;
  /* Same reason as .nav-item: a button that fills its menu without spilling
     out of it. */
  box-sizing: border-box;
  width: 100%;
  padding: 9px 10px;
  font-family: inherit;
  font-size: 13px;
  font-weight: 500;
  text-align: left;
  white-space: nowrap;
  text-overflow: ellipsis;
  color: var(--ink-muted);
  background: none;
  border: 0;
  border-radius: 6px;
  cursor: pointer;
}

.brand-switcher__option:hover {
  color: var(--k-color-ivory);
  background: var(--ink);
}

.brand-switcher__option[aria-current] {
  color: var(--lime);
  background: color-mix(in srgb, var(--lime) 12%, transparent);
}

.primary-nav {
  padding: 22px 10px 18px;
}

/* Account business, held at the foot of the rail however short the nav above
   it is. The rule reads as the line between reporting and everything else. */
.primary-nav--foot {
  margin-top: auto;
  padding-top: 14px;
  border-top: 1px solid var(--ink-line);
}

.nav-item {
  position: relative;
  display: flex;
  align-items: center;
  gap: 12px;
  /* There is no border-box reset in this app, so the 100% that lets a <button>
     fill the rail has to be told to keep the padding inside it — otherwise the
     item runs 24px past the rail and over the panel. */
  box-sizing: border-box;
  width: 100%;
  height: 48px;
  padding: 0 12px;
  font-family: inherit;
  font-size: 14px;
  font-weight: 600;
  text-align: left;
  text-decoration: none;
  color: var(--ink-muted);
  background: none;
  border: 0;
  border-radius: var(--k-radius-control);
  cursor: pointer;
  transition: color var(--k-duration-fast) var(--k-ease-standard),
    background-color var(--k-duration-fast) var(--k-ease-standard);
}

.nav-item:hover {
  color: var(--k-color-ivory);
  background: var(--ink-raised);
}

/* The current section: lime, the one lit thing on the rail, with a bar in the
   gutter so the item reads as marked rather than merely hovered. */
.nav-item.active {
  color: var(--lime);
  background: color-mix(in srgb, var(--lime) 12%, transparent);
}

.nav-item.active::before {
  content: "";
  position: absolute;
  left: -10px;
  width: 2px;
  height: 22px;
  background: var(--lime);
}

.nav-icon {
  position: relative;
  display: inline-flex;
  flex-shrink: 0;
  align-items: center;
  justify-content: center;
  width: 17px;
  height: 17px;
  opacity: 0.9;
}

/* Two offset rules drawn with spread-shrunk shadows — no image needed. */
.grid-icon {
  border: 1px solid;
  box-shadow: 5px 0 0 -4px, 0 5px 0 -4px;
}

/* Head and shoulders, same trick: a circle and a half-round below it. Both
   inherit the item's colour, so hover and the active state carry the icon. */
.person-icon::before,
.person-icon::after {
  content: "";
  position: absolute;
  left: 50%;
  translate: -50% 0;
  border: 1px solid;
}

.person-icon::before {
  top: 1px;
  width: 6px;
  height: 6px;
  border-radius: 50%;
}

.person-icon::after {
  bottom: 2px;
  width: 12px;
  height: 6px;
  border-bottom: 0;
  border-radius: 6px 6px 0 0;
}

/* Two rails with a knob apiece — the settings register, for the item that
   leads off the dashboard and into administration. The rails are the element's
   two background gradients, the knobs its two pseudo-elements; everything is
   currentColor, so the icon follows hover and active like the others. */
.sliders-icon {
  background-image:
    linear-gradient(currentColor, currentColor),
    linear-gradient(currentColor, currentColor);
  background-repeat: no-repeat;
  background-size: 15px 1px;
  background-position: center 5px, center 12px;
}

.sliders-icon::before,
.sliders-icon::after {
  content: "";
  position: absolute;
  width: 5px;
  height: 5px;
  background: currentColor;
  border-radius: 50%;
}

.sliders-icon::before {
  top: 3px;
  left: 3px;
}

.sliders-icon::after {
  top: 10px;
  right: 3px;
}

/* An open bracket with an arrow leaving it, drawn the same way: the bracket is
   a box missing its right border, the arrowhead two borders of a square turned
   45°. Both inherit currentColor, so they follow hover and active like the
   others. The arrow's shaft is a 1px gradient rather than a third box, because
   there are only two pseudo-elements to spend. */
.exit-icon {
  background-image: linear-gradient(currentColor, currentColor);
  background-repeat: no-repeat;
  background-size: 7px 1px;
  background-position: 7px center;
}

.exit-icon::before,
.exit-icon::after {
  content: "";
  position: absolute;
  border: 1px solid;
}

.exit-icon::before {
  left: 0;
  width: 6px;
  height: 12px;
  border-right: 0;
  border-radius: 2px 0 0 2px;
}

.exit-icon::after {
  right: 2px;
  width: 5px;
  height: 5px;
  border-bottom: 0;
  border-left: 0;
  rotate: 45deg;
}

/* A pennant on a staff — the same mark the chart plants on a day Neo acted, so
   the rail's item and the flags on the plot read as the same thing. The staff
   is the gradient, the pennant the one pseudo-element. */
.flag-icon {
  background-image: linear-gradient(currentColor, currentColor);
  background-repeat: no-repeat;
  background-size: 1px 13px;
  background-position: 3px center;
}

.flag-icon::before {
  content: "";
  position: absolute;
  top: 2px;
  left: 4px;
  width: 8px;
  height: 6px;
  border: 1px solid;
  border-radius: 2px;
}

/* Two heads over one pair of shoulders — the people behind the figures. The
   heads are filled and the shoulders outlined, so the glyph reads as a group
   at 17px rather than as the profile icon drawn twice. */
.people-icon::before,
.people-icon::after {
  content: "";
  position: absolute;
  left: 50%;
  translate: -50% 0;
}

.people-icon::before {
  top: 2px;
  width: 5px;
  height: 5px;
  margin-left: -3px;
  background: currentColor;
  border-radius: 50%;
  box-shadow: 6px 0 0 currentColor;
}

.people-icon::after {
  bottom: 2px;
  width: 14px;
  height: 6px;
  border: 1px solid;
  border-bottom: 0;
  border-radius: 6px 6px 0 0;
}

/* A shield — square shoulders, a point below — for what the store lets in.
   The outline is the one pseudo-element; the tick inside is the other, two
   borders of a small square turned 45°, so the glyph reads as "checked"
   rather than as a badge. currentColor throughout, like the rest. */
.shield-icon::before,
.shield-icon::after {
  content: "";
  position: absolute;
  border: 1px solid;
}

.shield-icon::before {
  top: 1px;
  left: 50%;
  width: 11px;
  height: 14px;
  translate: -50% 0;
  border-radius: 2px 2px 6px 6px / 2px 2px 8px 8px;
}

.shield-icon::after {
  top: 4px;
  left: 50%;
  width: 3px;
  height: 6px;
  translate: -50% 0;
  border-top: 0;
  border-left: 0;
  rotate: 45deg;
}

/* Right column */

.main {
  min-width: 0;
  margin-left: var(--sidebar);
}

.mobile-menu {
  display: none;
}

.page-content {
  max-width: 1560px;
  margin: 0 auto;
  padding: 32px 28px 20px;
}

/* Top bar — sits at the height of the rail's brand block and stays there. */

.topbar {
  position: sticky;
  top: 0;
  z-index: 20;
  background: color-mix(in srgb, var(--paper) 92%, transparent);
  backdrop-filter: blur(14px);
  border-bottom: 1px solid var(--line);
}

/* The bar spans the column, but its contents line up with the page's. */
.topbar__inner {
  display: flex;
  align-items: center;
  gap: 20px;
  max-width: 1560px;
  height: var(--topbar);
  margin: 0 auto;
  padding: 0 28px;
}

.crumbs {
  display: flex;
  align-items: center;
  gap: 10px;
  min-width: 0;
  font-size: 13px;
  font-weight: 600;
  color: var(--k-color-muted);
}

.crumbs > * {
  overflow: hidden;
  white-space: nowrap;
  text-overflow: ellipsis;
}

/* The separator belongs to the section, so a brandless page has none. */
.crumbs span + b::before,
.crumbs span + span::before {
  content: "/";
  margin-right: 10px;
  font-weight: 400;
  color: var(--k-color-control-border);
}

.crumbs b {
  font-weight: 700;
  color: var(--k-color-ink-soft);
}

.crumbs a {
  color: inherit;
  text-decoration: none;
}

.crumbs a:hover {
  color: var(--accent-deep);
}

.topbar__controls {
  display: flex;
  align-items: center;
  gap: 10px;
  margin-left: auto;
}

/* Reporting window */

.period-switch {
  display: flex;
  gap: 2px;
  padding: 0;
  background: var(--k-color-lavender-soft);
  border: 1px solid var(--line);
  border-radius: var(--k-radius-control);
}

.period-switch__option {
  display: inline-flex;
  align-items: center;
  /* The option is the target, not the group around it: 44px on its own. */
  min-height: 44px;
  padding: 0 13px;
  font-size: 13px;
  font-weight: 700;
  text-decoration: none;
  color: var(--k-color-ink-soft);
  border-radius: 6px;
}

.period-switch__option:hover {
  color: var(--ink);
}

.period-switch__option.active {
  color: var(--accent-deep);
  background: var(--card);
  box-shadow: 0 1px 2px rgb(23 32 51 / 10%);
}

/* The custom option is a button among links, and has to look like one of them:
   the same face, and a popover hung off the group underneath it. */
.period-switch {
  position: relative;
}

.period-switch__option--custom {
  font: inherit;
  font-size: 13px;
  font-weight: 700;
  white-space: nowrap;
  border: 0;
  background: none;
  cursor: pointer;
}

/* The chosen range is a pair of dates, so that one reads in the meta voice. */
.period-switch__option--custom.active {
  font-family: var(--mono);
  font-size: 12px;
  font-weight: 500;
}

.period-switch__option--custom[aria-expanded="true"] {
  color: var(--ink);
}

.period-popover {
  position: absolute;
  top: calc(100% + 8px);
  right: 0;
  z-index: 30;
  display: grid;
  gap: 14px;
  width: min(340px, calc(100vw - 24px));
  padding: 16px;
  background: var(--card);
  border: 1px solid var(--line);
  border-radius: var(--k-radius-panel);
  box-shadow: var(--k-shadow-raised);
}

/* `display: grid` above would otherwise beat the attribute the controller
   toggles, and the popover would be open on every page load. */
.period-popover[hidden] {
  display: none;
}

.period-popover__fields {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 10px;
}

.period-popover__field {
  display: grid;
  gap: 6px;
  font-size: 12px;
  font-weight: 700;
  color: var(--k-color-ink-soft);
}

.period-popover__field input {
  min-width: 0;
  height: 44px;
  padding: 0 10px;
  font: inherit;
  font-family: var(--sans);
  font-size: 13px;
  font-weight: 500;
  color: var(--ink);
  background: var(--card);
  border: 1px solid var(--k-color-control-border);
  border-radius: var(--k-radius-control);
}

.period-popover__field input:hover {
  border-color: var(--ink);
}

.period-popover__note {
  margin: 0;
  font-size: 12px;
  color: var(--k-color-muted);
}

.period-popover__actions {
  display: flex;
  justify-content: flex-end;
  gap: 8px;
}

.period-popover__actions .button {
  min-height: 44px;
  margin-top: 0;
  padding: 0 14px;
  font-size: 13px;
}

/* Top-bar buttons. Every one of them is disabled until it has something behind
   it, so the disabled state is the one that has to look deliberate. They share
   the brand's button corner: three controls on one row with two radii between
   them would read as two kinds of thing. */

.topbar-pill,
.ask-neo,
.topbar-icon {
  display: flex;
  align-items: center;
  gap: 8px;
  flex-shrink: 0;
  height: 44px;
  font-family: inherit;
  font-size: 13px;
  font-weight: 700;
  border-radius: var(--k-radius-button);
  cursor: pointer;
}

.topbar-pill:disabled,
.ask-neo:disabled,
.topbar-icon:disabled {
  cursor: default;
  opacity: 0.7;
}

.topbar-pill {
  padding: 0 14px;
  color: var(--k-color-ink-soft);
  background: var(--card);
  border: 1px solid var(--line);
}

/* Three overlapping chips, where the connected sources will sit. */
.sources-icon {
  display: flex;
  gap: 2px;
}

.sources-icon i {
  width: 11px;
  height: 11px;
  background: var(--line);
  border: 1.5px solid var(--card);
  border-radius: 50%;
}

.sources-icon i + i {
  margin-left: -6px;
}

.ask-neo {
  padding: 0 16px 0 9px;
  color: var(--k-color-paper);
  background: var(--accent);
  border: 1px solid var(--accent);
}

.ask-neo .neo-mark {
  border-color: color-mix(in srgb, var(--k-color-paper) 55%, transparent);
}

.ask-neo .neo-mark::before {
  border-color: var(--k-color-paper);
}

.ask-neo .neo-mark::after {
  background: var(--k-color-paper);
}

.topbar-icon {
  justify-content: center;
  width: 44px;
  padding: 0;
  color: var(--k-color-ink-soft);
  background: var(--card);
  border: 1px solid var(--line);
}

.topbar-icon svg {
  width: 16px;
  height: 16px;
  fill: none;
  stroke: currentcolor;
  stroke-width: 1.5;
  stroke-linecap: round;
}

/* The rail's mark again, sized for a button rather than a masthead. */
.neo-mark--sm {
  width: 22px;
  height: 22px;
}

.neo-mark--sm::before {
  inset: 4px;
}

.neo-mark--sm::after {
  inset: 8px;
}

.neo-mark--sm i {
  display: none;
}

/* Page header */

.welcome {
  display: flex;
  justify-content: space-between;
  align-items: flex-end;
  gap: 30px;
  margin-bottom: 26px;
}

/* The metadata line over the heading: what the page is reporting on, and
   whether it is live. Set in the meta voice at normal case, as the system
   sets every date and identifier. */
.eyebrow {
  display: flex;
  align-items: center;
  gap: 8px;
  margin: 0 0 10px;
  font-family: var(--mono);
  font-size: 13px;
  color: var(--k-color-muted);
}

.status-pulse {
  flex-shrink: 0;
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: var(--green);
  box-shadow: 0 0 0 3px var(--k-color-success-bg);
}

/* The system's headline step: fluid 32–44px, Space Grotesk, tracked to the
   floor it sets. Balanced so a two-line heading breaks evenly. */
.welcome h1 {
  margin: 0;
  font-family: var(--display);
  font-size: clamp(32px, 3.5vw, 44px);
  font-weight: 600;
  letter-spacing: -0.035em;
  line-height: 1.12;
  text-wrap: balance;
}

.welcome p {
  margin: 10px 0 0;
  font-size: 15px;
  color: var(--k-color-muted);
}

.period-label {
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  text-align: right;
}

.period-label span {
  font-size: 12px;
  font-weight: 700;
  color: var(--k-color-muted);
}

.period-label strong {
  margin-top: 4px;
  font-family: var(--mono);
  font-size: 13px;
  font-weight: 500;
}

.period-label small {
  margin-top: 3px;
  font-size: 12px;
  color: var(--k-color-muted);
}

/* Category tabs */

.category-tabs {
  position: sticky;
  top: var(--topbar);
  z-index: 15;
  display: grid;
  grid-template-columns: repeat(5, 1fr);
  margin: 0 0 10px;
  background: var(--card);
  border: 1px solid var(--line);
  border-radius: var(--k-radius-panel);
  overflow: hidden;
}

.category-tabs button {
  position: relative;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  min-width: 0;
  height: 56px;
  font-family: inherit;
  font-size: 13px;
  font-weight: 700;
  color: var(--k-color-muted);
  background: none;
  border: 0;
  border-right: 1px solid var(--line);
  cursor: pointer;
  transition: color var(--k-duration-fast) var(--k-ease-standard),
    background-color var(--k-duration-fast) var(--k-ease-standard);
}

.category-tabs button:last-child {
  border-right: 0;
}

/* Focus inside the strip: the strip clips its corners, so the ring is drawn
   inside the tab rather than around it. */
.category-tabs button:focus-visible {
  outline-offset: -3px;
}

/* The underline of the current tab, sat on top of the container border — the
   system's selected tab is deep violet with a rule under it. */
.category-tabs button::after {
  content: "";
  position: absolute;
  bottom: 0;
  left: 18px;
  right: 18px;
  height: 2px;
}

.category-tabs button:hover {
  color: var(--ink);
  background: var(--k-color-lavender-soft);
}

.category-tabs button.active {
  color: var(--accent-deep);
  background: var(--k-color-lavender-soft);
}

.category-tabs button.active::after {
  background: currentcolor;
}

.category-tabs i {
  display: grid;
  place-items: center;
  width: 26px;
  height: 26px;
  font-family: var(--mono);
  font-size: 12px;
  font-weight: 500;
  font-style: normal;
  color: var(--k-color-ink-soft);
  background: var(--k-color-lavender);
  border-radius: 6px;
}

.category-tabs button.active i {
  color: var(--k-color-paper);
  background: var(--accent);
}

.category-tabs b {
  display: grid;
  place-items: center;
  width: 20px;
  height: 20px;
  font-family: var(--mono);
  font-size: 12px;
  font-weight: 500;
  color: var(--k-color-paper);
  background: var(--accent);
  border-radius: 50%;
}

/* Tab panels */

.panel-empty {
  margin: 0;
  padding: 72px 0;
  font-size: 14px;
  text-align: center;
  color: var(--k-color-muted);
}

/*
 * Deltas are the system's semantic pair: success for a figure that rose,
 * warning for one that fell — a fall is something to look at, not an error.
 * Both clear 4.5:1 on paper and ivory.
 */
.delta {
  font-family: var(--mono);
  font-weight: 500;
  font-variant-numeric: tabular-nums;
}

.delta--up {
  color: var(--k-color-success);
}

.delta--down {
  color: var(--k-color-warning);
}

/* No measurable change, or nothing to compare against. Neither good nor bad,
   and it must not read as either. */
.delta--flat {
  color: var(--k-color-muted);
}

/* A figure that moved, where the direction it moved in is not an outcome — ad
   spend being the one. Darker than --flat, because the change is real and only
   its goodness is undecided. */
.delta--neutral {
  color: var(--k-color-ink-soft);
}

/* Access we have not been granted yet, stated where the shortfall would
   otherwise show up as data. */
.notice {
  margin: 0 0 14px;
  padding: 11px 16px;
  font-size: 13px;
  color: var(--k-color-warning);
  background: var(--k-color-warning-bg);
  border: 1px solid color-mix(in srgb, var(--k-color-warning) 25%, transparent);
  border-radius: var(--k-radius-control);
}

/* Revenue headline band */

/* The system's ink region, holding the page's one headline figure. Ivory
   type, lime for the pace line and a rise, nothing violet — violet on ink is
   the pairing the system keeps for light surfaces. */
.revenue-band {
  margin-top: 14px;
  color: var(--k-color-ivory);
  background: var(--ink);
  border-radius: var(--k-radius-panel);
}

.revenue-band :focus-visible {
  outline-color: var(--lime);
}

.revenue-band__body {
  display: grid;
  /* The two auto columns hold the figures and the link; the headline gives
     way first, so the link at the end of the row is never the thing that
     runs out of room. */
  grid-template-columns: minmax(220px, 1fr) minmax(200px, 0.8fr) auto auto;
  align-items: center;
  gap: 28px;
  padding: 24px 30px 22px;
}

.revenue-band .eyebrow {
  color: var(--ink-muted);
  /* "Net revenue · Jul 5 – Aug 3" breaking after the dash reads as two
     facts; the column is wide enough once it is told not to. */
  white-space: nowrap;
}

.revenue-band .delta--up {
  color: var(--lime);
}

.revenue-band .delta--down {
  color: var(--ink-amber);
}

.revenue-band__headline strong {
  display: block;
  font-family: var(--display);
  font-size: clamp(40px, 4.2vw, 64px);
  font-weight: 600;
  letter-spacing: -0.04em;
  line-height: 1.04;
  font-variant-numeric: tabular-nums;
}

.revenue-band__headline p {
  margin: 10px 0 0;
  font-size: 14px;
  color: var(--ink-muted);
}

.revenue-pace svg {
  display: block;
  width: 100%;
  height: 48px;
  fill: none;
  stroke: var(--lime);
  stroke-width: 2;
  stroke-linecap: round;
  stroke-linejoin: round;
}

.revenue-pace {
  margin: 0;
}

/* Wraps to two rows rather than letting either label break mid-phrase. */
.revenue-pace figcaption {
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
  gap: 4px 14px;
  margin-top: 10px;
  font-family: var(--mono);
  font-size: 13px;
  white-space: nowrap;
}

.revenue-pace figcaption span {
  color: var(--ink-muted);
}

.revenue-pace figcaption b {
  font-weight: 500;
  color: var(--k-color-ivory);
}

.revenue-band__figures {
  display: flex;
  gap: clamp(26px, 3vw, 54px);
  margin: 0;
}

.revenue-band__figures div {
  display: flex;
  flex-direction: column;
}

.revenue-band__figures dd {
  margin: 0;
  font-family: var(--display);
  font-size: clamp(26px, 2.2vw, 34px);
  font-weight: 600;
  letter-spacing: -0.025em;
  line-height: 1;
  font-variant-numeric: tabular-nums;
}

.revenue-band__figures dt {
  margin-top: 9px;
  font-size: 13px;
  white-space: nowrap;
  color: var(--ink-muted);
}

/* A figure's basis — the coverage a gross margin was computed over. It travels
   with the number it qualifies, never separately. */
.revenue-band__figures dt small {
  display: block;
  margin-top: 3px;
  font-size: 12px;
  white-space: normal;
  color: var(--ink-faint);
}

.revenue-band__open {
  display: flex;
  align-self: stretch;
  align-items: center;
  gap: 10px;
  padding-left: 24px;
  font-size: 13px;
  font-weight: 600;
  text-decoration: none;
  white-space: nowrap;
  color: var(--ink-muted);
  border-left: 1px solid var(--ink-line);
}

.revenue-band__open:hover {
  color: var(--k-color-ivory);
}

.revenue-band__trail {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  padding: 12px 30px;
  font-family: var(--mono);
  font-size: 12px;
  border-top: 1px solid var(--ink-line);
}

.revenue-band__trail p {
  display: flex;
  align-items: center;
  gap: 10px;
  margin: 0;
}

.revenue-band__trail span {
  color: var(--ink-muted);
}

.revenue-band__trail b {
  font-weight: 500;
  color: var(--k-color-ivory);
}

.revenue-band__trail a {
  text-decoration: none;
  color: var(--ink-muted);
}

.revenue-band__trail a:hover {
  color: var(--k-color-ivory);
}

/*
 * Marketing headline band
 *
 * A sibling of the revenue band, not a copy of it: the same ink region and
 * mono detailing, deliberately smaller — the revenue band is the page's
 * headline, and this one is the headline of a tab inside it.
 */

.marketing-band,

.support-band {
  margin-top: 14px;
  color: var(--k-color-ivory);
  background: var(--ink);
  border-radius: var(--k-radius-panel);
}

.marketing-band :focus-visible,
.support-band :focus-visible {
  outline-color: var(--lime);
}

.marketing-band__body,

.support-band__body {
  display: grid;
  /* The first column's floor is what the eyebrow needs on one line. Wrapped
     across two it pushes the figure down and stops the band reading as a
     single sentence. */
  grid-template-columns: minmax(250px, 0.85fr) minmax(0, 2fr) auto;
  align-items: center;
  gap: 30px;
  padding: 22px 30px;
}

.marketing-band .eyebrow,

.support-band .eyebrow {
  color: var(--ink-muted);
}

.marketing-band__headline strong,

.support-band__headline strong {
  display: block;
  font-family: var(--display);
  font-size: clamp(38px, 3.4vw, 52px);
  font-weight: 600;
  letter-spacing: -0.035em;
  line-height: 1.04;
  font-variant-numeric: tabular-nums;
}

.marketing-band__headline p,

.support-band__headline p {
  margin: 10px 0 0;
  font-size: 13px;
  color: var(--ink-muted);
}

/* Spend has no good direction, so its delta gets neither of the two colours
   that mean one. See the comment in the partial. */
.marketing-band .delta,
.support-band .delta {
  color: var(--k-color-lavender);
}

.marketing-band__figures,

.support-band__figures {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  margin: 0;
}

.marketing-band__figures div,

.support-band__figures div {
  padding: 4px 0 4px 22px;
  border-left: 1px solid var(--ink-line);
}

.marketing-band__figures div:first-child,

.support-band__figures div:first-child {
  padding-left: 0;
  border-left: 0;
}

.marketing-band__figures dt,

.support-band__figures dt {
  font-family: var(--mono);
  font-size: 13px;
  color: var(--ink-muted);
}

.marketing-band__figures dd,

.support-band__figures dd {
  margin: 9px 0 0;
  font-family: var(--display);
  font-size: clamp(21px, 1.7vw, 27px);
  font-weight: 600;
  letter-spacing: -0.025em;
  line-height: 1;
  font-variant-numeric: tabular-nums;
}

/* How the figure above was derived, or — where it could not be — why not. It
   travels with the number it qualifies, never separately. */
.marketing-band__figures dd small,
.support-band__figures dd small {
  display: block;
  margin-top: 8px;
  font-family: var(--sans);
  font-size: 12px;
  font-weight: 400;
  letter-spacing: 0;
  line-height: 1.35;
  color: var(--ink-faint);
}

/* The system's accent button: lime on ink, the one place lime is an action. */
.marketing-band__open,

.support-band__open {
  align-self: center;
  padding: 0 16px;
  height: 44px;
  font-family: inherit;
  font-size: 13px;
  font-weight: 700;
  white-space: nowrap;
  color: var(--ink);
  background: var(--lime);
  border: 0;
  border-radius: var(--k-radius-button);
  cursor: pointer;
}

.marketing-band__open:hover,
.support-band__open:hover {
  background: var(--k-color-paper);
}

/* Inert until the analysis it opens exists — the same treatment the top bar's
   unbuilt controls get, so a control that looks live while doing nothing never
   appears on this page. */
.marketing-band__open:disabled,
.support-band__open:disabled {
  cursor: default;
  opacity: 0.45;
}

.marketing-band__open:disabled:hover,
.support-band__open:disabled:hover {
  background: var(--lime);
}

.marketing-band__health,

.support-band__health {
  display: flex;
  align-items: center;
  gap: 10px 20px;
  flex-wrap: wrap;
  padding: 12px 30px;
  font-family: var(--mono);
  font-size: 12px;
  border-top: 1px solid var(--ink-line);
}

.marketing-band__health p,

.support-band__health p {
  margin: 0;
}

.marketing-band__health span,

.support-band__health span {
  color: var(--ink-muted);
}

.marketing-band__health b,

.support-band__health b {
  font-weight: 500;
  color: var(--k-color-ivory);
}

/* Days the rollup could not reconcile exactly. Not errors — which is why they
   sit under the figures they qualify rather than in a log nobody reads. */
.marketing-band__caveats,
.support-band__caveats {
  color: var(--ink-amber);
}

/* Metric cards */

.metric-cards {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(212px, 1fr));
  gap: 14px;
  margin-top: 14px;
}

/* A button, not an article: the whole card opens the drawer behind it, and a
   click target that size has to be reachable by keyboard and announced as
   something that does anything. border-box because this stylesheet has no
   global reset and the card's padding would otherwise widen its grid track. */
.metric-card {
  position: relative;
  box-sizing: border-box;
  width: 100%;
  padding: 20px 20px 18px;
  font: inherit;
  color: inherit;
  text-align: left;
  cursor: pointer;
  background: var(--card);
  border: 1px solid var(--line);
  border-radius: var(--k-radius-panel);
  transition: border-color var(--k-duration-fast) var(--k-ease-standard);
}

.metric-card:hover {
  border-color: var(--k-color-control-border);
}

/* The marketing cards, which have nothing behind them to open. Same card, minus
   every affordance that would say otherwise. */
.metric-card--static,
.metric-card--static:hover {
  cursor: default;
  border-color: var(--line);
}

.metric-card:hover .metric-card__go {
  color: var(--accent-deep);
}

/* How many of Neo's actions claim this figure. The diamond is the same mark
   the chart uses, so the two read as one annotation seen from two angles. */
.metric-card__actions {
  position: absolute;
  top: 44px;
  right: 18px;
  font-family: var(--mono);
  font-size: 12px;
  color: var(--k-color-muted);
}

.metric-card h2 {
  margin: 0;
  font-size: 14px;
  font-weight: 600;
  color: var(--k-color-ink-soft);
}

.metric-card__go {
  position: absolute;
  top: 18px;
  right: 18px;
  font-size: 13px;
  color: var(--k-color-muted);
}

.metric-card strong {
  display: block;
  margin-top: 16px;
  font-family: var(--display);
  font-size: clamp(28px, 2.5vw, 36px);
  font-weight: 600;
  letter-spacing: -0.03em;
  line-height: 1;
  font-variant-numeric: tabular-nums;
}

.metric-card p {
  display: flex;
  gap: 8px;
  margin: 16px 0 0;
  font-size: 12px;
  color: var(--k-color-muted);
}

/* Detail panels — the momentum chart and the product mix beside it */

.detail-row {
  display: grid;
  grid-template-columns: minmax(0, 1.3fr) minmax(340px, 0.9fr);
  gap: 14px;
  margin-top: 14px;
}

.panel {
  min-width: 0;
  background: var(--card);
  border: 1px solid var(--line);
  border-radius: var(--k-radius-panel);
}

.panel-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 20px;
  padding: 18px 20px;
  border-bottom: 1px solid var(--line);
}

.panel-head h2 {
  margin: 0;
  font-family: var(--display);
  font-size: 20px;
  font-weight: 600;
  letter-spacing: -0.02em;
  line-height: 1.25;
}

/* The line over a panel's heading, naming what kind of panel it is. Meta
   voice, normal case. */
.panel-kicker {
  margin: 0 0 4px;
  font-family: var(--mono);
  font-size: 13px;
  color: var(--k-color-muted);
}

.legend {
  display: flex;
  flex-shrink: 0;
  align-items: center;
  gap: 7px;
  margin: 0;
  white-space: nowrap;
  font-family: var(--mono);
  font-size: 12px;
  color: var(--k-color-muted);
}

.legend-line {
  width: 16px;
  height: 2px;
  background: var(--accent);
}

/* The mark for a day Neo acted on. A rotated square rather than a glyph so it
   matches the flags on the plot at any font size. */
.legend-diamond {
  width: 7px;
  height: 7px;
  margin-left: 6px;
  background: var(--ink);
  transform: rotate(45deg);
}

/* A control that is where the design put it but has nothing to do yet. */
.quiet-button {
  display: flex;
  align-items: center;
  height: 34px;
  padding: 0 12px;
  font-family: inherit;
  font-size: 12px;
  font-weight: 700;
  color: var(--k-color-muted);
  background: var(--k-color-lavender-soft);
  border: 1px solid var(--line);
  border-radius: var(--k-radius-control);
}

.quiet-button:disabled {
  opacity: 0.62;
}

/* Chart panel */

.chart-summary {
  display: flex;
  gap: clamp(24px, 3vw, 42px);
  margin: 0;
  padding: 18px 20px 0 74px;
}

.chart-summary > div {
  display: flex;
  flex-direction: column;
}

.chart-summary dt {
  font-family: var(--mono);
  font-size: 12px;
  color: var(--k-color-muted);
}

.chart-summary dd {
  margin: 5px 0 0;
  font-family: var(--display);
  font-size: 20px;
  font-weight: 600;
  letter-spacing: -0.02em;
  font-variant-numeric: tabular-nums;
}

/* The chart takes whatever height the row ends up with — the mix beside it is
   as tall as the products it lists, and a chart that stopped short of that
   would leave the panel half empty. */
.chart-panel {
  display: flex;
  flex-direction: column;
}

.chart-wrap {
  display: grid;
  flex: 1;
  grid-template-columns: 60px minmax(0, 1fr);
  grid-template-rows: minmax(0, 1fr) auto;
  gap: 0 10px;
  min-height: 268px;
  margin: 0;
  padding: 18px 20px 14px;
}

.chart-ylabels {
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  text-align: right;
  font-family: var(--mono);
  font-size: 12px;
  line-height: 1;
  color: var(--k-color-muted);
}

.chart-plot {
  position: relative;
  min-width: 0;
}

/* The gridlines the y labels are read against: quarters of the box, which is
   the scale RevenueChart rounds its axis to. */
.chart-grid {
  position: absolute;
  inset: 0;
  background: repeating-linear-gradient(
    #0000 0 calc(25% - 1px),
    var(--line) calc(25% - 1px) 25%
  );
  border-bottom: 1px solid var(--k-color-control-border);
}

.chart-plot svg {
  position: relative;
  display: block;
  width: 100%;
  height: 100%;
  overflow: visible;
}

.chart-area {
  fill: url("#chart-fill");
}

#chart-fill stop {
  stop-color: var(--accent);
}

.chart-line {
  fill: none;
  stroke: var(--accent);
  stroke-width: 2.5;
  stroke-linecap: round;
  stroke-linejoin: round;
}

/* Today's figure. Sits on the right edge, half outside the plot. */
.chart-dot {
  position: absolute;
  right: 0;
  width: 11px;
  height: 11px;
  background: var(--accent);
  border-radius: 50%;
  box-shadow: 0 0 0 3px var(--card);
  transform: translate(50%, -50%);
}

/* A day Neo acted on: a full-height rule through the plot with a diamond at the
   top, opening the same drawer the net revenue card does. The rule is what ties
   the decision to the shape of the line under it — a marker floating above the
   plot would leave the reader estimating the date. */
.chart-marker {
  position: absolute;
  inset: 0 auto 0 0;
  width: 9px;
  padding: 0;
  cursor: pointer;
  background: none;
  border: 0;
  transform: translateX(-50%);
}

.chart-marker::before {
  position: absolute;
  inset: 0 auto 0 50%;
  width: 1px;
  content: "";
  background: repeating-linear-gradient(color-mix(in srgb, var(--ink) 30%, transparent) 0 3px, #0000 3px 7px);
}

.chart-marker:hover::before,
.chart-marker:focus-visible::before {
  background: var(--ink);
}

/* Inside the plot rather than above it: the chart shares its top edge with the
   panel's padding, and a flag hung over that edge is clipped on short panels. */
.chart-marker__flag {
  position: absolute;
  top: 4px;
  left: 50%;
  display: flex;
  align-items: center;
  gap: 5px;
  padding: 4px 6px;
  font-family: var(--mono);
  font-size: 12px;
  line-height: 1;
  white-space: nowrap;
  color: var(--k-color-ivory);
  background: var(--ink);
  border-radius: 6px;
  transform: translateX(-50%);
}

.chart-marker__flag i {
  font-size: 7px;
  font-style: normal;
  color: var(--lime);
}

/* The label is a tooltip, not standing text. Several actions in one month land
   within a few pixels of each other on a panel this wide, and permanent labels
   would overlap into something unreadable — so the diamond is always there and
   the words arrive on hover or focus, one at a time. */
.chart-marker__label {
  display: none;
}

.chart-marker:hover,
.chart-marker:focus-visible {
  z-index: 1;
  outline: none;
}

.chart-marker:hover .chart-marker__label,
.chart-marker:focus-visible .chart-marker__label {
  display: inline;
}

.chart-xlabels {
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  grid-column: 2;
  height: 24px;
  margin: 0;
  padding-top: 8px;
  font-family: var(--mono);
  font-size: 12px;
  color: var(--k-color-muted);
}

/* Product mix panel */

.product-list {
  margin: 0;
  padding: 4px 20px 12px;
  list-style: none;
}

.product-row {
  display: grid;
  grid-template-columns: 28px minmax(0, 1fr) auto;
  align-items: center;
  gap: 12px;
  min-height: 72px;
  border-bottom: 1px solid var(--line);
}

.product-row:last-child {
  border-bottom: 0;
}

.product-rank {
  font-family: var(--mono);
  font-size: 12px;
  color: var(--k-color-muted);
}

.product-detail {
  display: flex;
  flex-direction: column;
  min-width: 0;
}

.product-detail strong {
  overflow: hidden;
  font-size: 13px;
  font-weight: 700;
  white-space: nowrap;
  text-overflow: ellipsis;
}

.product-detail small {
  margin-top: 4px;
  font-size: 12px;
  color: var(--k-color-muted);
}

.product-bar {
  overflow: hidden;
  height: 4px;
  margin-top: 8px;
  background: var(--k-color-lavender);
  border-radius: 2px;
}

.product-bar i {
  display: block;
  height: 100%;
  background: var(--accent);
  border-radius: 2px;
}

.product-result {
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  white-space: nowrap;
}

.product-result strong {
  font-family: var(--mono);
  font-size: 13px;
  font-weight: 500;
}

.product-result span {
  margin-top: 5px;
  font-size: 12px;
  color: var(--k-color-muted);
}

/* Customer mix panel */

/* The chart earns the wider half of the row above; here the cohort grid does,
   because it has six columns to fit and the donut has one figure. */
.detail-row--customers {
  grid-template-columns: minmax(0, 0.85fr) minmax(0, 1.15fr);
}

.customer-mix-panel {
  display: flex;
  flex-direction: column;
}

/* Names the source rather than claiming an endorsement. The system's tag:
   a lavender pill with deep violet text. */
.source-pill {
  flex-shrink: 0;
  padding: 5px 10px;
  font-size: 12px;
  font-weight: 700;
  line-height: 1.5;
  color: var(--accent-deep);
  white-space: nowrap;
  background: var(--k-color-lavender);
  border-radius: var(--k-radius-pill);
}

.customer-mix-content {
  display: grid;
  grid-template-columns: 136px minmax(0, 1fr);
  gap: 24px;
  align-items: center;
  padding: 22px 20px;
  /* The cohort grid beside this one sets the row's height. Rather than leave
     the slack as a gap under the donut, the split takes it and centres in it. */
  flex: 1;
  align-content: center;
}

/* The split itself, drawn as a sweep. --new-share is set on the element by the
   view, so the arc and the figure inside it cannot disagree. The two hues are
   the system's brand violet and its sky, a categorical pair. */
.customer-donut {
  display: grid;
  place-items: center;
  width: 136px;
  height: 136px;
  background: conic-gradient(var(--accent) 0 var(--new-share), var(--k-color-sky) var(--new-share) 100%);
  border-radius: 50%;
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--ink) 40%, transparent);
}

.customer-donut::before {
  content: "";
  grid-area: 1 / 1;
  width: 88px;
  height: 88px;
  background: var(--card);
  border-radius: 50%;
  box-shadow: 0 0 0 1px color-mix(in srgb, var(--ink) 40%, transparent);
}

.customer-donut > div {
  z-index: 1;
  display: flex;
  flex-direction: column;
  grid-area: 1 / 1;
  align-items: center;
}

.customer-donut strong {
  font-family: var(--display);
  font-size: 28px;
  font-weight: 600;
  letter-spacing: -0.04em;
}

.customer-donut span {
  font-size: 12px;
  color: var(--k-color-muted);
}

.mix-legend {
  display: grid;
  gap: 18px;
  margin: 0;
}

.mix-legend > div {
  display: grid;
  grid-template-columns: 9px minmax(0, 1fr) auto;
  gap: 7px;
  align-items: center;
}

.mix-legend dt {
  min-width: 0;
  font-size: 12px;
  color: var(--k-color-muted);
}

.mix-legend dd {
  margin: 0;
  font-family: var(--mono);
  font-size: 13px;
  font-weight: 500;
}

.mix-legend small {
  grid-column: 2 / 4;
  font-family: var(--mono);
  font-size: 12px;
  color: var(--k-color-muted);
}

.mix-dot {
  width: 7px;
  height: 7px;
  border-radius: 2px;
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--ink) 40%, transparent);
}

.mix-dot--new {
  background: var(--accent);
}

.mix-dot--returning {
  background: var(--k-color-sky);
}

/* Only rendered when some of the period could not be attributed to a customer,
   so the two shares above are not read as covering everything. */
.mix-coverage {
  margin: -6px 0 0;
  padding: 0 20px 14px;
  font-size: 12px;
  color: var(--k-color-muted);
}

.retention-stats {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  margin: 0;
  /* Pushed to the foot of the panel so the two panels in the row end level
     however tall the donut half happens to be. */
  margin-top: auto;
  border-top: 1px solid var(--line);
}

.retention-stats > div {
  display: flex;
  flex-direction: column;
  padding: 16px 18px;
  border-right: 1px solid var(--line);
}

.retention-stats > div:last-child {
  border-right: 0;
}

.retention-stats dt {
  font-size: 12px;
  color: var(--k-color-muted);
}

.retention-stats dd {
  margin: 5px 0 0;
  font-family: var(--display);
  font-size: 20px;
  font-weight: 600;
  letter-spacing: -0.02em;
  font-variant-numeric: tabular-nums;
}

.retention-stats small {
  margin-top: 3px;
  font-family: var(--mono);
  font-size: 12px;
  font-weight: 500;
}

/* What the figure rests on — the cohort it was measured over, or why there was
   nothing to measure. Set in the body face, since it is a sentence. */
.retention-stats__note {
  font-family: var(--sans);
  font-weight: 400;
  color: var(--k-color-muted);
}

/* Cohort grid */

.cohort-panel {
  display: flex;
  flex-direction: column;
}

/* Six columns have a floor below which they stop being readable; past it the
   grid scrolls rather than crushing the cells. */
.cohort-scroll {
  overflow-x: auto;
  padding: 6px 20px 2px;
}

.cohort-table {
  width: 100%;
  min-width: 420px;
  border-collapse: collapse;
  font-family: var(--mono);
  font-variant-numeric: tabular-nums;
  text-align: center;
}

.cohort-table th,
.cohort-table td {
  padding: 0 4px;
}

.cohort-table thead th {
  padding-bottom: 10px;
  font-size: 12px;
  font-weight: 500;
  color: var(--k-color-muted);
}

.cohort-table tbody th,
.cohort-table tbody td {
  height: 39px;
  font-size: 12px;
  font-weight: 500;
  color: var(--k-color-ink-soft);
  border-top: 1px solid var(--line);
}

.cohort-table thead th:first-child,
.cohort-table tbody th {
  width: 26%;
  text-align: left;
}

.cohort-table tbody th {
  font-family: var(--sans);
  font-size: 12px;
  font-weight: 700;
  color: var(--ink);
}

.cohort-table tbody th small {
  margin-left: 6px;
  font-family: var(--mono);
  font-size: 12px;
  font-weight: 400;
  color: var(--k-color-muted);
}

/* Every cell is a share of the same denominator, so the tint marks which window
   a figure belongs to rather than how large it is — a heat map keyed to value
   would compete with the numbers for the same job. The tints are steps of the
   system's lavender, with deep violet on every one of them. */
.cohort-cell {
  display: grid;
  place-items: center;
  min-height: 23px;
  color: var(--accent-deep);
  background: var(--k-color-lavender);
  border-radius: 2px;
}

.cohort-cell--m1 {
  background: color-mix(in srgb, var(--k-color-lavender) 92%, var(--accent-deep));
}

.cohort-cell--m2 {
  background: var(--k-color-lavender-soft);
}

.cohort-cell--m3 {
  background: color-mix(in srgb, var(--k-color-lavender) 45%, var(--card));
}

.cohort-repeat {
  font-weight: 500;
}

.panel-footnote {
  display: flex;
  gap: 10px;
  align-items: flex-start;
  margin: 8px 20px 18px;
  margin-top: auto;
  padding: 13px 15px;
  background: var(--k-color-lavender-soft);
  border-radius: var(--k-radius-control);
}

.panel-footnote p {
  margin: 0;
  font-size: 12px;
  line-height: 1.5;
  color: var(--k-color-muted);
}

.mini-orbit {
  display: grid;
  place-items: center;
  flex-shrink: 0;
  width: 22px;
  height: 22px;
  font-size: 10px;
  color: var(--accent-deep);
  background: var(--card);
  border: 1px solid var(--k-color-lavender);
  border-radius: 50%;
}

/*
 * Marketing breakdowns — spend by channel, and the return by creative format.
 */

/* The table has six columns to fit and the format list has three, so the split
   is nearer even than the revenue row's. */
.detail-row--marketing {
  grid-template-columns: minmax(0, 1.1fr) minmax(340px, 0.9fr);
  align-items: start;
}

.channel-panel,
.creative-panel {
  display: flex;
  flex-direction: column;
}

/* A definition the columns above it depend on, so it reads as prose rather
   than as a figure — no mono. */
.panel-caption {
  margin: 0;
  padding: 14px 20px 2px;
  font-size: 12px;
  line-height: 1.5;
  color: var(--k-color-muted);
}

/* Six columns do not compress below this, and squeezing them would set the
   figures in a size nobody reads. The panel scrolls instead. */
.channel-scroll {
  overflow-x: auto;
  padding: 6px 20px 4px;
}

.channel-table {
  width: 100%;
  min-width: 560px;
  border-collapse: collapse;
}

.channel-table th,
.channel-table td {
  padding: 0;
  text-align: right;
  white-space: nowrap;
}

.channel-table thead th {
  padding-bottom: 10px;
  font-family: var(--mono);
  font-size: 12px;
  font-weight: 500;
  color: var(--k-color-muted);
  border-bottom: 1px solid var(--line);
}

.channel-table tbody th,
.channel-table thead th:first-child {
  text-align: left;
}

.channel-table tbody th,
.channel-table tbody td {
  height: 54px;
  border-bottom: 1px solid var(--line);
}

.channel-table tbody tr:last-child th,
.channel-table tbody tr:last-child td {
  border-bottom: 0;
}

/* Laid out inline rather than as a flex row. `display: flex` on a cell takes it
   out of table layout, and it stops stretching to the row — the bottom border
   then lands above every other cell's. */
.channel-table tbody th {
  font-size: 13px;
  font-weight: 700;
}

.channel-table tbody th span {
  vertical-align: middle;
}

.channel-table tbody td {
  font-family: var(--mono);
  font-size: 12px;
  font-weight: 500;
  font-variant-numeric: tabular-nums;
}

/* The platform's initial in a lozenge. A letter rather than a logo: this app
   ships no platform wordmarks, and the colours below are the ones each
   platform is recognised by rather than an imitation of its badge. */
.source-mark {
  display: inline-grid;
  place-items: center;
  width: 22px;
  height: 22px;
  margin-right: 9px;
  vertical-align: middle;
  font-family: var(--mono);
  font-size: 12px;
  font-style: normal;
  font-weight: 500;
  color: #fff;
  background: var(--k-color-ink-soft);
  border-radius: 6px;
}

.source-mark--meta {
  background: #1d45d8;
}

.source-mark--google {
  color: #3c4043;
  background: linear-gradient(135deg, #4285f4 0 45%, #fbbc05 45% 64%, #34a853 64%);
}

.source-mark--tiktok {
  background: #0b0e0f;
  box-shadow: 2px 0 #ff345e, -2px 0 #30f2ed;
}

/* The two inboxes, coloured the way each is recognised — as the ad platforms
   above are — rather than with a wordmark. */
.source-mark--instagram {
  background: linear-gradient(45deg, #f9ce34 0%, #ee2a7b 50%, #6228d7 100%);
}

.source-mark--whatsapp {
  background: #25d366;
}

/*
 * Customer support — the inbox chart, the queue beside it, and the channel
 * table under both. The headline band shares the marketing band's rules; see
 * the comma-joined selectors above.
 */

/* The chart needs the width; the queue is a list of six and does not. Each
   panel takes its own height: stretched to the taller one, the chart's date
   labels would drift away from the bars they name. */
.detail-row--support {
  grid-template-columns: minmax(0, 1.3fr) minmax(340px, 0.9fr);
  align-items: start;
}

.support-channels {
  margin-top: 14px;
}

/* The chart's own svg is not stretched, so the wrap sizes to the bars rather
   than the other way round, and the gridlines are drawn in the svg where the
   bars can be placed against them exactly. */
.support-chart__wrap {
  grid-template-rows: auto auto;
  min-height: 0;
}

.support-chart__wrap .chart-ylabels {
  height: 220px;
  padding-top: 18px;
  box-sizing: border-box;
}

.support-chart__grid {
  stroke: var(--line);
  stroke-width: 1;
}

/* The floor the bars stand on, drawn as the revenue chart's grid draws its
   own bottom edge. */
.support-chart__floor {
  stroke: var(--k-color-control-border);
  stroke-width: 1;
}

.support-chart__hit {
  fill: transparent;
}

.support-chart__day:hover .support-chart__hit {
  fill: var(--k-color-lavender-soft);
}

/* Violet for what a customer sent, sky for what the store sent back — the
   same pair the admin's inbox chart uses. */
.support-chart__bar--inbound {
  fill: var(--accent);
}

.support-chart__bar--outbound {
  fill: var(--k-color-sky);
  stroke: color-mix(in srgb, var(--ink) 40%, transparent);
  stroke-width: 1;
}

/* A day before the connection: a floor, not the day, so it is drawn as one. */
.support-chart__day--partial .support-chart__bar {
  opacity: 0.35;
}

.legend-swatch {
  display: inline-block;
  width: 10px;
  height: 10px;
  margin-left: 10px;
  border-radius: 2px;
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--ink) 40%, transparent);
}

.legend-swatch:first-child {
  margin-left: 0;
}

.legend-swatch--inbound {
  background: var(--accent);
}

.legend-swatch--outbound {
  background: var(--k-color-sky);
}

.legend-swatch--partial {
  background: color-mix(in srgb, var(--accent) 35%, transparent);
}

/* The queue */

.queue-panel {
  display: flex;
  flex-direction: column;
}

.queue-list {
  margin: 0;
  padding: 4px 20px 8px;
  list-style: none;
}

.queue-row {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr) auto;
  align-items: center;
  gap: 12px;
  padding: 13px 0;
  border-bottom: 1px solid var(--line);
}

.queue-row:last-child {
  border-bottom: 0;
}

.queue-row .source-mark {
  margin-right: 0;
}

.queue-detail {
  min-width: 0;
}

.queue-detail strong {
  display: block;
  font-size: 13px;
  font-weight: 700;
}

.queue-detail strong small {
  margin-left: 6px;
  font-family: var(--mono);
  font-size: 12px;
  font-weight: 400;
  color: var(--k-color-muted);
}

.queue-detail p {
  overflow: hidden;
  margin: 3px 0 0;
  font-size: 12px;
  line-height: 1.4;
  color: var(--k-color-muted);
  text-overflow: ellipsis;
  white-space: nowrap;
}

.queue-wait {
  font-family: var(--mono);
  font-size: 13px;
  font-weight: 500;
  white-space: nowrap;
}

/* Past the target the wait is the finding, in the system's warning rather
   than the red that would call it an error. */
.queue-wait--overdue {
  color: var(--k-color-warning);
}

/* A channel whose history is here and whose feed has stopped. */
.channel-state {
  display: block;
  margin-top: 3px;
  margin-left: 31px;
  font-family: var(--mono);
  font-size: 12px;
  color: var(--k-color-warning);
}

/* Under the empty state, the two things a merchant can do about it. */
.panel-empty__actions {
  display: flex;
  gap: 10px;
  justify-content: center;
  flex-wrap: wrap;
  margin: 0 0 24px;
}

.panel-empty__actions .source__link {
  margin-top: 0;
}

/* The sentence above carries the tab's empty-state padding; the links sit
   under it, not a second padding away. */
.panel-empty + .panel-empty__actions {
  margin-top: -44px;
}

/* Creative mix */

.creative-list {
  margin: 0;
  padding: 6px 20px 12px;
  list-style: none;
}

.creative-row {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(80px, 0.75fr) auto;
  align-items: center;
  gap: 14px;
  min-height: 72px;
  border-bottom: 1px solid var(--line);
}

.creative-row:last-child {
  border-bottom: 0;
}

.creative-detail {
  display: flex;
  flex-direction: column;
  min-width: 0;
}

.creative-detail strong {
  font-size: 13px;
  font-weight: 700;
}

.creative-detail small {
  margin-top: 4px;
  font-size: 12px;
  line-height: 1.4;
  color: var(--k-color-muted);
}

.creative-bar {
  overflow: hidden;
  height: 5px;
  background: var(--k-color-lavender);
  border-radius: 2px;
}

.creative-bar i {
  display: block;
  height: 100%;
  border-radius: 2px;
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--ink) 40%, transparent);
}

/* One colour per format, so a format keeps its colour as the ranking moves.
   Set on the fill rather than on the row: the track underneath is the same
   lavender in every row and is what makes the lengths comparable. The
   colours are the system's categorical set — violet, then sky, coral, mint —
   with soft ink for the fifth. */
.creative-bar--video {
  background: var(--accent);
}

.creative-bar--carousel {
  background: var(--k-color-sky);
}

.creative-bar--dynamic {
  background: var(--k-color-coral);
}

.creative-bar--static {
  background: var(--k-color-mint);
}

.creative-bar--collection {
  background: var(--k-color-ink-soft);
}

/* Grey, and not a colour from the scale above: an unclassified row is spend we
   could not file, not a sixth kind of creative. */
.creative-bar--unclassified {
  background: var(--k-color-control-border);
}

.creative-result {
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  white-space: nowrap;
}

.creative-result strong {
  font-family: var(--mono);
  font-size: 15px;
  font-weight: 500;
}

.creative-result span {
  margin-top: 5px;
  font-family: var(--mono);
  font-size: 12px;
  color: var(--k-color-muted);
}

/*
 * Profile
 *
 * The form furniture (.field, .button, .flash) is defined in application.css
 * on the same tokens, so only the spacing inside a panel is restated here.
 */

.page-content--narrow {
  max-width: 1080px;
}

.profile-row {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  align-items: start;
  gap: 14px;
  margin-top: 14px;
}

.profile-facts {
  margin: 0;
  padding: 6px 20px 4px;
}

.profile-facts > div {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 20px;
  padding: 13px 0;
  border-bottom: 1px solid var(--line);
}

.profile-facts > div:last-child {
  border-bottom: 0;
}

.profile-facts dt {
  font-size: 12px;
  font-weight: 700;
  color: var(--k-color-muted);
}

.profile-facts dd {
  margin: 0;
  font-size: 14px;
  text-align: right;
  color: var(--ink);
}

.profile-note {
  margin: 4px 20px 18px;
  padding: 13px 15px;
  font-size: 12px;
  line-height: 1.5;
  color: var(--k-color-muted);
  background: var(--k-color-lavender-soft);
  border-radius: var(--k-radius-control);
}

.profile-form {
  display: flex;
  flex-direction: column;
  gap: 16px;
  padding: 20px;
}

.profile-form .field__hint {
  margin: -4px 0 0;
  font-size: 12px;
  line-height: 1.5;
  color: var(--k-color-muted);
}

/* The one button that commits a change sits on the left axis of the form it
   commits, at its own width — stretched across the panel it would read as
   the panel's footer rather than the form's action. */
.profile-form .button {
  align-self: start;
}

/* The paste-a-token form under the Instagram login button. Folded away
   because it is the path for an operator, not the merchant: shown open, two
   ways to do one thing reads as a choice the merchant has to make. */
.fallback {
  margin: 0 20px 4px;
  border-top: 1px solid var(--line);
}

.fallback > summary {
  min-height: 44px;
  display: list-item;
  align-content: center;
  font-size: 12px;
  font-weight: 600;
  color: var(--k-color-muted);
  cursor: pointer;
}

.fallback > summary:hover {
  color: var(--ink);
}

.fallback > .profile-form {
  padding: 4px 0 20px;
}

.page-content .flash {
  margin: 0 0 14px;
  font-size: 13px;
}

/* Responsive */

@media (width <= 1240px) {
  .revenue-band__body {
    grid-template-columns: minmax(240px, 1fr) minmax(180px, 0.8fr);
    row-gap: 26px;
  }

  .revenue-band__open {
    grid-column: 1 / -1;
    align-self: start;
    padding: 18px 0 0;
    border-top: 1px solid var(--ink-line);
    border-left: 0;
  }

  /* The four figures need the full width before the headline does, so the
     button drops below them rather than squeezing them into two columns while
     there is still room for four. */
  .marketing-band__body,
  .support-band__body {
    grid-template-columns: minmax(220px, 0.85fr) minmax(0, 2fr);
    row-gap: 24px;
  }

  .marketing-band__open,
  .support-band__open {
    grid-column: 1 / -1;
    justify-self: start;
  }
}

@media (width <= 1080px) {
  /* The chart needs the full width before the mix does; below this they stop
     competing for it and stack instead. */
  .detail-row,
  .detail-row--customers,
  .detail-row--marketing,
  .detail-row--support {
    grid-template-columns: minmax(0, 1fr);
  }

  .category-tabs {
    grid-template-columns: repeat(5, minmax(max-content, 1fr));
    overflow-x: auto;
    scroll-snap-type: x proximity;
    scroll-padding-inline: 12px;
  }

  .category-tabs button {
    padding: 0 18px;
    white-space: nowrap;
    scroll-snap-align: start;
  }

  .profile-row {
    grid-template-columns: minmax(0, 1fr);
  }
}

@media (width <= 920px) {
  .sidebar {
    width: 236px;
    transform: translateX(-102%);
    transition: transform var(--k-duration-standard) var(--k-ease-standard);
  }

  .sidebar.mobile-open {
    transform: translateX(0);
  }

  .mobile-menu {
    display: grid;
    place-items: center;
    flex-shrink: 0;
    width: 44px;
    height: 44px;
    font-size: 15px;
    color: var(--k-color-ink-soft);
    background: var(--card);
    border: 1px solid var(--line);
    border-radius: var(--k-radius-control);
    cursor: pointer;
  }
}

@media (width <= 900px) {
  /* Two by two rather than four across. The dividers move with them, so the
     left column keeps the edge the first cell had. Before the phone width,
     because at a tablet's the labels were already running into the rules. */
  .marketing-band__figures,
  .support-band__figures {
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 20px 0;
  }

  .marketing-band__figures div:nth-child(odd),
  .support-band__figures div:nth-child(odd) {
    padding-left: 0;
    border-left: 0;
  }
}

@media (width <= 720px) {
  .category-tabs {
    margin-left: -12px;
    margin-right: -12px;
    border-radius: 0;
  }
}

/* The window switch is the one control that has to survive to the narrowest
   screen; the rest give up their room to it. */
@media (width <= 860px) {
  .topbar__inner {
    gap: 12px;
  }

  .topbar-pill,
  .crumbs span,
  .crumbs span + b::before {
    display: none;
  }
}

/* Below this the crumb had shrunk to an ellipsis and a letter; the tab strip
   under it names the section, so it goes rather than being squeezed. */
@media (width <= 680px) {
  .crumbs {
    display: none;
  }
}

@media (width <= 680px) {
  .page-content {
    padding: 24px 12px 16px;
  }

  .topbar__inner {
    padding: 0 12px;
  }

  .welcome {
    align-items: flex-start;
  }

  .period-label {
    display: none;
  }

  /* The bell has nothing behind it yet, and Ask Neo folds to its mark: the
     text is still the button's name, only not drawn. Both give their room
     to the window switch, which has to fit at this width. */
  .topbar-icon {
    display: none;
  }

  .ask-neo {
    justify-content: center;
    gap: 0;
    width: 44px;
    padding: 0;
    font-size: 0;
  }

  .period-switch__option {
    padding: 0 9px;
  }

  .revenue-band__body {
    grid-template-columns: 1fr;
    gap: 24px;
    padding: 22px 18px 20px;
  }

  .revenue-band__trail {
    flex-wrap: wrap;
    padding: 12px 18px;
  }

  .marketing-band__body,

  .support-band__body {
    grid-template-columns: 1fr;
    gap: 24px;
    padding: 22px 18px 20px;
  }

  .marketing-band__health,

  .support-band__health {
    padding: 12px 18px;
  }

  .panel-head,
  .product-list,
  .customer-mix-content,
  .cohort-scroll {
    padding-right: 16px;
    padding-left: 16px;
  }

  /* The legend never breaks inside a label, so at this width it drops under
     the heading instead of squeezing it to a word a line. */
  .panel-head {
    flex-wrap: wrap;
    row-gap: 10px;
  }

  /* The donut and its legend stop fitting side by side well before the panel
     runs out of room; the legend gets the width and the donut centres above it. */
  .customer-mix-content {
    grid-template-columns: minmax(0, 1fr);
    justify-items: center;
    gap: 20px;
  }

  .mix-legend {
    width: 100%;
  }

  .retention-stats {
    grid-template-columns: minmax(0, 1fr);
  }

  .retention-stats > div {
    border-right: 0;
    border-bottom: 1px solid var(--line);
  }

  .retention-stats > div:last-child {
    border-bottom: 0;
  }

  /* The summary lines up with the plot on a wide panel; at this width there is
     no room for the gutter it was indented by. */
  .chart-summary {
    gap: 20px;
    padding: 16px 16px 0;
  }

  .chart-wrap {
    grid-template-columns: 46px minmax(0, 1fr);
    height: 240px;
    padding: 16px 16px 12px;
  }
}

/*
 * Metric drawer — what Neo did that moved the card you clicked.
 *
 * Ivory, like the page it slides over, with one ink card at the top holding
 * the figure. That inversion is the point: the drawer is still the store
 * reporting, and the only thing in it that is not up for interpretation is the
 * number the rest of the panel is a claim about.
 */

.drawer-scrim {
  position: fixed;
  inset: 0;
  z-index: 40;
  padding: 0;
  cursor: default;
  background: rgb(23 32 51 / 45%);
  backdrop-filter: blur(2px);
  border: 0;
}

.drawer {
  position: fixed;
  inset: 0 0 0 auto;
  z-index: 41;
  display: flex;
  flex-direction: column;
  box-sizing: border-box;
  width: min(510px, 100%);
  background: var(--paper);
  border-left: 1px solid var(--line);
  box-shadow: -12px 0 40px rgb(23 32 51 / 14%);
  transform: translateX(105%);
  transition: transform 0.27s var(--k-ease-standard);
}

.drawer--open {
  transform: translateX(0);
}

/* `display: flex` above outranks the user agent's `[hidden] { display: none }`,
   which would leave every drawer on the page open at once. */
.drawer[hidden] {
  display: none;
}

.drawer__head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  min-height: 92px;
  padding: 16px 22px;
  background: var(--card);
  border-bottom: 1px solid var(--line);
}

.drawer__head h2 {
  margin: 4px 0 0;
  font-family: var(--display);
  font-size: 24px;
  font-weight: 600;
  letter-spacing: -0.03em;
  line-height: 1.2;
}

.drawer__head .panel-kicker {
  margin-bottom: 0;
}

.drawer__close {
  display: flex;
  flex: none;
  align-items: center;
  justify-content: center;
  width: 36px;
  height: 36px;
  font-size: 22px;
  font-weight: 300;
  line-height: 1;
  color: var(--k-color-muted);
  cursor: pointer;
  background: var(--k-color-lavender-soft);
  border: 1px solid var(--line);
  border-radius: 50%;
}

.drawer__close:hover {
  color: var(--ink);
  border-color: var(--k-color-control-border);
}

/* min-height: 0 so the body, not the drawer, is what scrolls — without it a
   flex child refuses to shrink below its content and the ask strip below is
   pushed off the bottom of the screen. */
.drawer__body {
  flex: 1;
  min-height: 0;
  padding: 16px 22px 26px;
  overflow-y: auto;
}

.drawer__figure {
  display: grid;
  grid-template-columns: 1.2fr 0.8fr;
  align-items: center;
  gap: 14px;
  min-height: 116px;
  padding: 18px;
  color: var(--k-color-ivory);
  background: var(--ink);
  border-radius: var(--k-radius-panel);
}

/* The three cards with no daily series behind them give the whole card to the
   figure rather than leaving a hole where the mark would be. */
.drawer__figure--wide {
  grid-template-columns: 1fr;
}

.drawer__figure .panel-kicker {
  color: var(--ink-muted);
}

.drawer__figure strong {
  display: block;
  margin-top: 7px;
  font-family: var(--display);
  font-size: 36px;
  font-weight: 600;
  letter-spacing: -0.04em;
  line-height: 1;
  font-variant-numeric: tabular-nums;
}

.drawer__figure p {
  margin: 9px 0 0;
  font-family: var(--mono);
  font-size: 12px;
  color: var(--ink-muted);
}

.drawer__spark {
  width: 100%;
  height: 62px;
}

.drawer__spark polyline {
  fill: none;
  stroke: var(--lime);
  stroke-width: 1.5;
  stroke-linecap: round;
  stroke-linejoin: round;
}

/* On the ink card the paper deltas are too dark to read, so they take the
   rail's pair instead: lime for a rise, amber for a fall. */
.drawer__figure .delta--up {
  color: var(--lime);
}

.drawer__figure .delta--down {
  color: var(--ink-amber);
}

.drawer__section {
  margin-top: 22px;
}

.drawer__section-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding-bottom: 10px;
  border-bottom: 1px solid var(--line);
}

.drawer__section-head h3 {
  margin: 0;
  font-size: 16px;
  font-weight: 700;
}

.drawer__section-head span {
  font-family: var(--mono);
  font-size: 12px;
  color: var(--k-color-muted);
}

.drawer__empty {
  margin: 14px 0 0;
  font-size: 13px;
  line-height: 1.5;
  color: var(--k-color-muted);
}

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

.action-list__item {
  display: grid;
  grid-template-columns: 23px minmax(0, 1fr) auto;
  align-items: center;
  gap: 10px;
  min-height: 73px;
  padding: 12px 0;
  border-bottom: 1px solid var(--line);
}

.action-list__item:last-child {
  border-bottom: 0;
}

.action-list__mark {
  display: grid;
  place-items: center;
  width: 20px;
  height: 20px;
  font-size: 8px;
  border-radius: 50%;
}

.action-list__mark--measured {
  color: var(--k-color-success);
  background: var(--k-color-success-bg);
}

.action-list__mark--forecast {
  color: var(--k-color-warning);
  background: var(--k-color-warning-bg);
}

.action-list__item strong {
  display: block;
  font-size: 13px;
  font-weight: 700;
}

.action-list__item p {
  margin: 5px 0 0;
  font-size: 12px;
  line-height: 1.5;
  color: var(--k-color-muted);
}

.action-list__item .delta {
  flex-shrink: 0;
  font-size: 12px;
}

.action-list__when {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 6px;
  margin-top: 4px;
  font-family: var(--mono);
  font-size: 12px;
  color: var(--k-color-muted);
}

/* Measured against forecast is the distinction that matters most here, so it is
   the one the colour carries: success for a figure that happened, warning for
   one that has not yet. Status is quieter — it qualifies the claim rather than
   changing what kind of claim it is. */
.action-list .badge {
  padding: 0.1rem 0.45rem;
  font-size: 12px;
}

.action-list .badge--measured {
  color: var(--k-color-success);
  background: var(--k-color-success-bg);
}

.action-list .badge--forecast {
  color: var(--k-color-warning);
  background: var(--k-color-warning-bg);
}

.action-list .badge--validated,
.action-list .badge--monitoring {
  color: var(--k-color-ink-soft);
  background: var(--k-color-lavender-soft);
}

.action-list .badge--todo {
  color: var(--k-color-ink-soft);
  background: var(--k-color-paper);
  box-shadow: inset 0 0 0 1px var(--k-color-line);
}

.drawer__ask {
  display: flex;
  flex: none;
  align-items: center;
  gap: 8px;
  min-height: 69px;
  padding: 12px 22px;
  background: var(--card);
  border-top: 1px solid var(--line);
}

.drawer__ask input {
  box-sizing: border-box;
  flex: 1;
  min-width: 0;
  height: 46px;
  padding: 0 13px;
  font-family: var(--sans);
  font-size: 13px;
  color: var(--ink);
  background: var(--card);
  border: 1px solid var(--k-color-control-border);
  border-radius: var(--k-radius-control);
}

.drawer__ask input::placeholder {
  color: var(--k-color-muted);
}

.drawer__ask button {
  display: grid;
  flex: none;
  place-items: center;
  width: 46px;
  height: 46px;
  font-size: 17px;
  color: var(--k-color-paper);
  background: var(--accent);
  border: 0;
  border-radius: var(--k-radius-control);
}

/* Both are inert. They read as placed rather than broken — no dimming, but no
   pointer or focus ring promising they will do something either. */
.drawer__ask input:disabled,
.drawer__ask button:disabled {
  cursor: default;
  opacity: 1;
}

@media (width <= 560px) {
  .drawer__head,
  .drawer__body,
  .drawer__ask {
    padding-right: 18px;
    padding-left: 18px;
  }
}

/*
 * Action trail
 *
 * The drawer lists one metric's actions in a 340px column; this is the same
 * records given a whole page, so an action's impacts are a list under it rather
 * than a single figure at the end of a row. The date leads, because the
 * question the page answers is "in what order did this happen".
 */

.trail-panel {
  display: flex;
  flex-direction: column;
  margin-top: 14px;
}

.quiet-note {
  font-family: var(--mono);
  font-size: 12px;
  color: var(--k-color-muted);
}

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

.trail__item {
  display: grid;
  grid-template-columns: 118px minmax(0, 1fr) auto;
  align-items: start;
  gap: 18px;
  padding: 18px 20px;
  border-bottom: 1px solid var(--line);
}

.trail__item:last-child {
  border-bottom: 0;
}

/* Mono, so the dates stack into a column the eye can run down. */
.trail__when {
  display: flex;
  flex-direction: column;
  gap: 3px;
  font-family: var(--mono);
  font-size: 12px;
  color: var(--k-color-muted);
}

.trail__when b {
  font-weight: 500;
  color: var(--k-color-ink-soft);
}

.trail__body strong {
  display: block;
  font-size: 15px;
  font-weight: 700;
  letter-spacing: -0.01em;
}

.trail__body p {
  margin: 6px 0 0;
  font-size: 13px;
  line-height: 1.55;
  color: var(--k-color-muted);
}

.trail__impacts {
  display: flex;
  flex-wrap: wrap;
  gap: 8px 18px;
  margin: 11px 0 0;
  padding: 0;
  list-style: none;
}

.trail__impacts li {
  display: flex;
  align-items: center;
  gap: 7px;
  padding: 5px 10px;
  font-size: 12px;
  background: var(--k-color-lavender-soft);
  border-radius: var(--k-radius-control);
}

.trail__metric {
  color: var(--k-color-muted);
}

/* An action linked to nothing is still a record of something that happened, so
   it is stated rather than left as a gap where the impacts would be. */
.trail__unlinked {
  font-style: italic;
}

/* The same distinctions the drawer makes, on the same tokens. */
.trail .badge--measured {
  color: var(--k-color-success);
  background: var(--k-color-success-bg);
}

.trail .badge--forecast {
  color: var(--k-color-warning);
  background: var(--k-color-warning-bg);
}

.trail .badge--validated,
.trail .badge--monitoring {
  color: var(--k-color-ink-soft);
  background: var(--k-color-lavender-soft);
}

.trail .badge--todo {
  color: var(--k-color-ink-soft);
  background: var(--k-color-paper);
  box-shadow: inset 0 0 0 1px var(--k-color-line);
}

/* The status badge is the row's last column and must not be squeezed by a long
   title beside it. */
.trail__item > .badge {
  flex-shrink: 0;
  font-size: 12px;
}

@media (width <= 700px) {
  .trail__item {
    grid-template-columns: minmax(0, 1fr) auto;
  }

  /* The date leads on a narrow screen too, so it takes the row above rather
     than a column that would leave the title two words wide. */
  .trail__when {
    flex-direction: row;
    grid-column: 1 / -1;
    gap: 8px;
  }
}

/* ---- Data sources -------------------------------------------------------
 *
 * The panel behind the top bar's Sources pill. Deliberately plainer than the
 * metric drawer: that one opens onto a figure worth looking at, this one opens
 * onto a list of yes-or-no answers, and giving it the same ink headline card
 * would dress "Meta Ads is not connected" up as a result.
 */

.sources-pill {
  position: relative;
}

.sources-pill:hover {
  color: var(--ink);
  border-color: var(--k-color-control-border);
}

/* A lit chip is a source actually feeding the dashboard. Specificity beats the
   unlit `.sources-icon i` above without restating its geometry. */
.sources-icon .sources-icon__chip--live {
  background: var(--accent);
}

/* Enough to make someone open the panel, and nothing more — which source and
   why are inside. The warning hue rather than the error one: a missing scope
   or a stale sync is something to look at, not an outage. */
.sources-pill__flag {
  position: absolute;
  top: -3px;
  right: -3px;
  box-sizing: border-box;
  width: 9px;
  height: 9px;
  background: var(--k-color-warning);
  border: 1.5px solid var(--card);
  border-radius: 50%;
}

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

.source {
  padding: 17px 0;
  border-bottom: 1px solid var(--line);
}

.source:last-child {
  border-bottom: 0;
}

.source__head {
  display: grid;
  grid-template-columns: 9px minmax(0, 1fr) auto;
  align-items: center;
  gap: 11px;
}

.source__dot {
  width: 9px;
  height: 9px;
  background: var(--k-color-control-border);
  border-radius: 50%;
}

.source--connected .source__dot {
  background: var(--green);
}

.source--attention .source__dot {
  background: var(--k-color-warning);
}

/* An unbuilt connector is not a source that failed, so its row is dimmed out
   of the reading order rather than given a colour of its own. */
.source--unsupported {
  opacity: 0.55;
}

.source__title strong {
  display: block;
  font-size: 13px;
  font-weight: 700;
}

.source__headline {
  display: block;
  margin-top: 3px;
  overflow: hidden;
  font-family: var(--mono);
  font-size: 12px;
  color: var(--k-color-muted);
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* The state in words, beside the dot that colours it. */
.source__status {
  flex-shrink: 0;
  font-size: 12px;
  font-weight: 700;
  color: var(--k-color-muted);
}

.source--connected .source__status {
  color: var(--k-color-success);
}

.source--attention .source__status {
  color: var(--k-color-warning);
}

/* Auto-fit rather than a fixed three: the Kairo-sourced store shows two facts
   and the Shopify one shows three, and a fixed track would leave a hole. */
.source__facts {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(118px, 1fr));
  gap: 10px;
  margin: 13px 0 0 20px;
}

.source__facts dt {
  font-size: 12px;
  font-weight: 700;
  color: var(--k-color-muted);
}

.source__facts dd {
  margin: 4px 0 0;
  font-size: 12px;
  font-weight: 500;
}

.source__warning,
.source__note,
.source__handoff {
  margin: 11px 0 0 20px;
  font-size: 12px;
  line-height: 1.5;
}

.source__warning {
  padding: 9px 11px;
  color: var(--k-color-warning);
  background: var(--k-color-warning-bg);
  border-radius: var(--k-radius-control);
}

.source__note,
.source__handoff {
  color: var(--k-color-muted);
}

.source__action {
  margin-left: 20px;
}

/* The system's primary button at the drawer's scale. */
.source__link {
  display: inline-flex;
  align-items: center;
  height: 36px;
  margin-top: 12px;
  padding: 0 14px;
  font-size: 13px;
  font-weight: 700;
  color: var(--k-color-paper);
  text-decoration: none;
  background: var(--accent);
  border-radius: var(--k-radius-button);
  transition: background-color var(--k-duration-fast) var(--k-ease-standard);
}

.source__link:hover {
  background: var(--accent-deep);
}

/* The ad accounts already connected, on the merchant's own Meta page. */

/* `.panel` carries no padding of its own — every child provides it, the way
   .panel-head and .profile-form do. */
.connected-list {
  margin: 0;
  padding: 4px 20px;
  list-style: none;
}

.connected-list__item {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding: 14px 0;
  border-bottom: 1px solid var(--line);
}

.connected-list__item:last-child {
  border-bottom: 0;
}

.connected-list__item strong {
  display: block;
  font-size: 13px;
  font-weight: 700;
}

/* The account's currency and timezone, which is why they are mono: they are
   identifiers to be compared against another account's, not prose. */
.connected-list__item span:not(.badge) {
  display: block;
  margin-top: 4px;
  font-family: var(--mono);
  font-size: 12px;
  color: var(--k-color-muted);
}

/* Four controls on one row is more than a narrow panel holds, so they wrap and
   stay right-aligned rather than pushing the account name out of the row. */
.connected-list__state {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: flex-end;
  gap: 8px;
}

/* The row's buttons are secondary to the connect form below, and to each other
   only by colour — they are all one tap and none of them is the reason the
   page exists. */
.connected-list__state .button {
  min-height: 36px;
  margin-top: 0;
  padding: 0 12px;
  font-size: 12px;
}

.connected-list__error {
  flex-basis: 100%;
  margin: 0;
  font-size: 12px;
  line-height: 1.5;
  color: var(--k-color-warning);
}

/* The ad accounts a Facebook login can see, each behind a checkbox. The
   whole row is the label, because the checkbox alone is a small target and
   the row already reads as one thing. Inside .profile-form, which pads the
   panel, so the list's own side padding comes off. */
.pick-list {
  padding: 0 0 12px;
}

.pick-list__choice {
  display: flex;
  align-items: center;
  gap: 12px;
  width: 100%;
  cursor: pointer;
}

.pick-list__choice .field__check {
  flex: none;
  width: 16px;
  height: 16px;
  accent-color: var(--accent);
}

.connected-list .badge--measured {
  color: var(--k-color-success);
  background: var(--k-color-success-bg);
}

.connected-list .badge--forecast {
  color: var(--k-color-warning);
  background: var(--k-color-warning-bg);
}

/* A link doing a button's job. `.button` is written for <button> and <input>,
   which need no underline reset; an anchor does, or it underlines itself. */
a.button {
  text-decoration: none;
}

/* The system's secondary button: paper with a visible border. Disconnecting
   is not the action anyone came to this page for, so it does not get the
   weight of the button that is, and a Cancel next to a submit must not look
   identical to it. */
.button--quiet,
.profile-form .button--quiet {
  color: var(--ink);
  background: var(--card);
  border: 1px solid var(--k-color-control-border);
}

.button--quiet:hover,
.profile-form .button--quiet:hover {
  color: var(--ink);
  background: var(--k-color-lavender-soft);
  border-color: var(--k-color-control-border);
}

/* A submit and its way out, side by side. */
.form-row {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 10px;
}

.form-row .button {
  margin: 0;
}

/*
 * Customers — everyone the store knows, one person per row, and the merge
 * bar that says two rows are one person. The table is the channel table's:
 * same head, same row height, mono figures on the right. What is new is the
 * first column of ticks and the list of identities under each name.
 */

.directory-search {
  display: flex;
  gap: 2px;
  padding: 3px;
  background: var(--k-color-lavender);
  border: 1px solid var(--line);
  border-radius: var(--k-radius-control);
}

.directory-search__input {
  width: min(280px, 50vw);
  padding: 7px 11px;
  font: inherit;
  font-size: 13px;
  color: var(--ink);
  background: var(--card);
  border: 0;
  border-radius: 6px;
  outline-offset: 2px;
}

.directory-search__input::placeholder {
  color: var(--k-color-muted);
}

.directory-search__button {
  padding: 6px 13px;
  font: inherit;
  font-size: 12px;
  font-weight: 700;
  color: var(--k-color-ink-soft);
  background: none;
  border: 0;
  border-radius: 6px;
  cursor: pointer;
}

.directory-search__button:hover {
  color: var(--accent-deep);
}

.directory-panel {
  display: flex;
  flex-direction: column;
  margin-top: 14px;
}

.merge-bar {
  display: flex;
  align-items: center;
  gap: 12px;
}

.merge-bar__count {
  font-family: var(--mono);
  font-size: 12px;
  color: var(--k-color-muted);
}

.merge-bar__submit[disabled] {
  cursor: default;
  opacity: 0.45;
}

.directory-table {
  min-width: 720px;
}

/* The ticks: the one column that is neither a name nor a figure, so it takes
   no more room than the box. */
.directory-table__tick {
  width: 28px;
  padding-right: 8px !important;
  text-align: left !important;
}

.directory-table__tick input {
  width: 15px;
  height: 15px;
  margin: 0;
  vertical-align: middle;
  accent-color: var(--accent);
  cursor: pointer;
}

/* The name column is the second, behind the ticks, so the channel table's
   first-child rule does not reach it. */
.directory-table thead th:nth-child(2) {
  text-align: left;
}

/* A name over a list of identities is taller than a figure, so the row grows
   past the channel table's fixed height and the cells pad it instead. */
.directory-table tbody th,
.directory-table tbody td {
  height: auto;
  padding: 12px 0;
  vertical-align: top;
}

.directory-table tbody td {
  padding-top: 15px;
}

.directory-table tbody th {
  padding-right: 24px;
  white-space: normal;
}

/* The name is the way into the person's page; it reads as a name until it
   is pointed at, so the table stays a table of people and not of links. */
.directory-table__name {
  display: block;
  font-size: 13px;
  font-weight: 700;
  color: inherit;
  text-decoration: none;
  cursor: pointer;
}

.directory-table__name:hover {
  color: var(--accent-deep);
  text-decoration: underline;
  text-underline-offset: 4px;
}

/* A merged person is one the merchant made; the tag marks the rows that
   would not exist without a decision, so that a mistaken one is findable. */
.directory-table__merged .directory-table__name::after {
  content: "merged";
  margin-left: 8px;
  padding: 1px 7px;
  font-size: 12px;
  font-weight: 700;
  vertical-align: 1px;
  color: var(--accent-deep);
  background: var(--k-color-lavender);
  border-radius: var(--k-radius-pill);
}

.identity-list {
  display: flex;
  flex-wrap: wrap;
  gap: 6px 14px;
  margin: 6px 0 0;
  padding: 0;
  list-style: none;
}

.identity {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-size: 12px;
  font-weight: 500;
  color: var(--k-color-ink-soft);
}

.identity .source-mark {
  width: 18px;
  height: 18px;
  margin-right: 0;
  font-size: 9px;
}

.identity__detail {
  font-family: var(--mono);
  font-size: 13px;
  color: var(--k-color-muted);
}

.identity__separate-form {
  display: inline;
}

/* Separating is the undo, and reads as a quiet link rather than a button so
   the row is still a row of names and not a row of controls. */
.identity__separate {
  padding: 0;
  font: inherit;
  font-size: 13px;
  color: var(--k-color-error);
  text-decoration: underline;
  text-underline-offset: 3px;
  background: none;
  border: 0;
  cursor: pointer;
}

.identity__separate:hover {
  color: color-mix(in srgb, var(--k-color-error) 75%, var(--ink));
}

.directory-pagination {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding: 14px 20px;
  border-top: 1px solid var(--line);
}

.directory-pagination__controls {
  display: flex;
  gap: 16px;
}

.directory-pagination__link {
  font-size: 12px;
  font-weight: 700;
  color: var(--k-color-ink-soft);
  text-decoration: none;
}

.directory-pagination__link:hover {
  color: var(--accent-deep);
  text-decoration: underline;
  text-underline-offset: 4px;
}

/* One customer's page. The heading is the list's name, tagged as the row
   is when the merchant made the person; the chips under it are the row's. */
.customer-name--merged::after {
  content: "merged";
  margin-left: 12px;
  padding: 2px 9px;
  font-family: var(--sans);
  font-size: 12px;
  font-weight: 700;
  letter-spacing: 0;
  vertical-align: middle;
  color: var(--accent-deep);
  background: var(--k-color-lavender);
  border-radius: var(--k-radius-pill);
}

.identity-list--page {
  margin-top: 12px;
}

.identity-list--page .identity {
  font-size: 13px;
}

/* Orders and threads down the left, what Shopify holds on the right; one
   column once there is no room for two. */
.customer-layout {
  display: grid;
  grid-template-columns: minmax(0, 1.5fr) minmax(280px, 0.7fr);
  gap: 14px;
  align-items: start;
  margin-top: 14px;
}

.customer-layout__main,
.customer-layout__side {
  display: flex;
  flex-direction: column;
  gap: 14px;
  min-width: 0;
}

.orders-table {
  min-width: 640px;
}

.orders-table tbody th,
.orders-table tbody td {
  height: auto;
  padding: 12px 0;
  vertical-align: top;
}

.orders-table tbody th {
  font-family: var(--mono);
  font-weight: 500;
  white-space: nowrap;
}

/* Words read from the left; only the total is a figure. */
.orders-table th:not(:last-child),
.orders-table td:not(:last-child) {
  padding-right: 20px;
  text-align: left;
}

.orders-table__items {
  max-width: 320px;
  white-space: normal;
}

/* A cancelled or test order is on the list, since it happened, and faded,
   since it counts for nothing. */
.orders-table__row--void {
  color: var(--k-color-muted);
}

.orders-table__row--void th {
  text-decoration: line-through;
}

.orders-table__refund {
  display: block;
  font-size: 11px;
  color: var(--k-color-muted);
}

.customer-thread .panel-head h2 {
  display: flex;
  align-items: center;
  gap: 8px;
}

.customer-thread .panel-head .source-mark {
  width: 20px;
  height: 20px;
  margin-right: 0;
  font-size: 10px;
}

/* Both class names sit on one list, and `.queue-thread__messages` zeroes the
   padding further down this file, so the panel's own inset is written at a
   specificity that does not depend on which rule comes last. The thread is a
   column of its own, no wider than a conversation reads comfortably, on the
   ivory ground so paper and ink bubbles both stand off it. */
.customer-thread .customer-thread__messages {
  gap: 3px;
  padding: 8px 24px 24px;
  background: var(--paper);
  border-radius: 0 0 var(--k-radius-panel) var(--k-radius-panel);
}

.customer-thread .queue-msg {
  max-width: min(72%, 560px);
}

/* A run from one side sits tight; the other side's answer stands apart. */
.customer-thread .queue-msg--opens {
  margin-top: 12px;
}

.customer-thread .queue-msg__body {
  padding: 9px 14px;
  background: var(--card);
  border-color: var(--line);
  border-radius: 18px;
}

/* One tail a run, on its last bubble, where the time hangs. */
.customer-thread .queue-msg--closes .queue-msg__body {
  border-bottom-left-radius: 4px;
}

.customer-thread .queue-msg__at {
  margin-bottom: 0;
}

/* The thread in both directions: the customer hung left on paper, the
   merchant hung right on ink — the side carries the direction and the fill
   repeats it, so a long thread can be scanned for who spoke last. */
.customer-thread .queue-msg--outbound {
  align-self: flex-end;
  align-items: flex-end;
}

.customer-thread .queue-msg--outbound .queue-msg__body {
  color: var(--k-color-paper);
  background: var(--k-color-ink);
  border-color: var(--k-color-ink);
  border-bottom-left-radius: 18px;
}

.customer-thread .queue-msg--outbound.queue-msg--closes .queue-msg__body {
  border-bottom-right-radius: 4px;
}

.customer-thread .queue-msg--outbound .queue-msg__body--described {
  color: var(--ink-muted);
}

.customer-thread .queue-msg--outbound .queue-msg__at {
  padding-right: 4px;
  padding-left: 0;
}

/* The day, said once across the thread rather than under every bubble. */
.thread-day {
  display: flex;
  align-items: center;
  gap: 12px;
  margin-top: 20px;
  font-family: var(--mono);
  font-size: 11px;
  color: var(--k-color-muted);
}

.thread-day::before,
.thread-day::after {
  flex: 1;
  height: 1px;
  content: "";
  background: var(--line);
}

@media (width <= 640px) {
  .customer-thread .customer-thread__messages {
    padding: 4px 14px 18px;
  }

  .customer-thread .queue-msg {
    max-width: 86%;
  }
}

.customer-footnote {
  border-top: 0;
}

@media (width <= 1080px) {
  .customer-layout {
    grid-template-columns: minmax(0, 1fr);
  }
}

/* Off-screen, still read out: the tick column's heading. */
.visually-hidden {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

@media (width <= 720px) {
  .directory-search__input {
    width: 100%;
  }

  .merge-bar {
    width: 100%;
    justify-content: space-between;
  }
}

/*
 * Security — the Shopify app audits. The same audit Kairo publishes on its
 * site, set on the dashboard's own furniture: the search is a panel, every
 * card is a panel, the findings are panels with a coloured rule. Three hues
 * carry the reading: the system's accent trio (mint, sky, coral) for the
 * decorative marks — the score ring, the finding rule — and its semantic
 * trio (success, warning, error) wherever a state is said in words on a tint,
 * because a status is never stated in colour alone.
 */

.audit-em {
  font-style: normal;
  color: var(--accent-deep);
}

/* The one way in: paste the App Store page. */
.audit-ask {
  padding: 20px;
}

.audit-search label {
  display: block;
  margin-bottom: 10px;
  font-size: 13px;
  font-weight: 700;
  color: var(--k-color-ink-soft);
}

.audit-search__row {
  display: flex;
  gap: 10px;
  max-width: 720px;
}

.audit-search__input {
  flex: 1;
  min-width: 0;
  min-height: 44px;
  padding: 0 14px;
  font: inherit;
  font-size: 14px;
  color: var(--ink);
  background: var(--card);
  border: 1px solid var(--k-color-control-border);
  border-radius: var(--k-radius-control);
  outline-offset: 2px;
}

.audit-search__input::placeholder {
  color: var(--k-color-muted);
}

.audit-search__input:focus {
  border-color: var(--accent);
  box-shadow: 0 0 0 3px var(--k-color-lavender);
  outline: none;
}

.audit-search__button {
  flex: none;
  margin-top: 0;
}

.audit-search--compact .audit-search__row {
  flex-direction: column;
}

.audit-search__error {
  margin: 12px 0 0;
  padding: 10px 14px;
  font-size: 13px;
  font-weight: 600;
  line-height: 1.5;
  color: var(--k-color-error);
  background: var(--k-color-error-bg);
  border: 1px solid color-mix(in srgb, var(--k-color-error) 25%, transparent);
  border-radius: var(--k-radius-control);
}

/* The brand's list of audits. */
.audit-index {
  margin-top: 36px;
}

.audit-index__heading {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  justify-content: space-between;
  gap: 12px 40px;
  margin-bottom: 18px;
}

.audit-index__heading h2 {
  margin: 0;
  font-family: var(--display);
  font-size: clamp(24px, 2.6vw, 32px);
  font-weight: 600;
  letter-spacing: -0.03em;
  line-height: 1.12;
}

.audit-index__heading > p {
  flex: 1 1 320px;
  max-width: 52ch;
  margin: 0;
  font-size: 14px;
  line-height: 1.55;
  color: var(--k-color-muted);
}

.audit-cards {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
  gap: 14px;
  margin: 0;
  padding: 0;
  list-style: none;
}

.audit-card__link {
  display: grid;
  grid-template-columns: 56px minmax(0, 1fr) auto;
  gap: 16px;
  height: 100%;
  padding: 20px;
  color: inherit;
  text-decoration: none;
  background: var(--card);
  border: 1px solid var(--line);
  border-radius: var(--k-radius-panel);
  transition: border-color var(--k-duration-fast) var(--k-ease-standard),
    box-shadow var(--k-duration-fast) var(--k-ease-standard);
}

.audit-card__link:hover,
.audit-card__link:focus-visible {
  border-color: var(--accent);
  box-shadow: var(--k-shadow-raised);
}

.audit-card__icon {
  width: 56px;
  height: 56px;
  border-radius: 14px;
}

/* An app whose listing has not been read yet has no icon to show. */
.audit-card__icon--blank {
  display: block;
  background: var(--k-color-lavender-soft);
  border: 1px dashed var(--line);
}

.audit-card__body strong {
  display: block;
  font-family: var(--display);
  font-size: 16px;
  font-weight: 600;
  letter-spacing: -0.02em;
  line-height: 1.25;
}

.audit-card__body small {
  display: block;
  margin: 3px 0 8px;
  font-size: 12px;
  color: var(--k-color-muted);
}

.audit-card__body p {
  margin: 0;
  font-size: 13px;
  line-height: 1.5;
  color: var(--k-color-ink-soft);
}

/* The score, or the state where there is no score yet. The words carry the
   grade; the tint only supplements them. */
.audit-grade {
  display: grid;
  align-self: start;
  justify-items: center;
  gap: 2px;
  min-width: 68px;
  padding: 10px 8px;
  font-family: var(--mono);
  font-size: 11px;
  line-height: 1.3;
  text-align: center;
  border-radius: var(--k-radius-control);
  color: var(--k-color-ink-soft);
  background: var(--k-color-lavender-soft);
}

.audit-grade b {
  font-family: var(--display);
  font-size: 24px;
  font-weight: 600;
  letter-spacing: -0.04em;
  line-height: 1;
}

.audit-grade.is-low-risk,
.is-low-risk .audit-score-grade {
  color: var(--k-color-success);
  background: var(--k-color-success-bg);
}

.audit-grade.is-moderate-risk,
.is-moderate-risk .audit-score-grade {
  color: var(--k-color-warning);
  background: var(--k-color-warning-bg);
}

.audit-grade.is-higher-risk,
.is-higher-risk .audit-score-grade {
  color: var(--k-color-error);
  background: var(--k-color-error-bg);
}

.audit-grade.is-failed {
  color: var(--k-color-warning);
  background: var(--k-color-warning-bg);
}

.audit-grade.is-missing {
  color: var(--k-color-muted);
}

.audit-empty {
  padding: 40px 20px;
  border: 1px dashed var(--k-color-control-border);
  border-radius: var(--k-radius-panel);
}

/* How an audit is made: three panels, one per section of the report. */
.audit-method {
  margin-top: 44px;
}

.audit-method h2 {
  margin: 0 0 14px;
  font-family: var(--display);
  font-size: 20px;
  font-weight: 600;
  letter-spacing: -0.02em;
}

.audit-method__grid {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 14px;
}

.audit-method__grid div {
  padding: 20px;
  background: var(--card);
  border: 1px solid var(--line);
  border-radius: var(--k-radius-panel);
}

.audit-method__grid strong {
  display: block;
  margin-bottom: 6px;
  font-family: var(--display);
  font-size: 16px;
  font-weight: 600;
}

.audit-method__grid p {
  margin: 0;
  font-size: 13px;
  line-height: 1.6;
  color: var(--k-color-ink-soft);
}

/* One audit: the app and its score, then the findings beside the sidebar. */
.audit-hero {
  display: grid;
  grid-template-columns: minmax(0, 1.5fr) minmax(280px, 0.6fr);
  align-items: start;
  gap: 28px;
  margin-bottom: 32px;
}

.audit-title-row {
  display: flex;
  align-items: center;
  gap: 18px;
  margin-bottom: 16px;
}

.audit-icon {
  flex: none;
  width: 72px;
  height: 72px;
  border-radius: 18px;
  box-shadow: var(--k-shadow-raised);
}

.audit-title-row h1 {
  margin: 0;
  font-family: var(--display);
  font-size: clamp(28px, 3vw, 40px);
  font-weight: 600;
  letter-spacing: -0.035em;
  line-height: 1.05;
  text-wrap: balance;
}

.audit-title-row h1 span {
  display: block;
  margin-top: 4px;
  font-size: 0.5em;
  letter-spacing: -0.01em;
  color: var(--accent-deep);
}

.audit-byline {
  margin: 8px 0 0;
  font-size: 14px;
  color: var(--k-color-muted);
}

.audit-byline a {
  color: var(--ink);
  text-decoration: underline;
  text-underline-offset: 3px;
}

.audit-lede {
  max-width: 68ch;
  margin: 0 0 18px;
  font-size: 16px;
  line-height: 1.6;
  color: var(--k-color-ink-soft);
}

.audit-facts {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  margin: 0;
  padding: 0;
  list-style: none;
}

.audit-facts li {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 6px 12px;
  font-size: 13px;
  font-weight: 600;
  color: var(--k-color-ink-soft);
  background: var(--card);
  border: 1px solid var(--line);
  border-radius: var(--k-radius-pill);
}

.audit-facts__badge {
  color: var(--accent-deep);
  background: var(--k-color-lavender);
  border-color: var(--k-color-lavender);
}

.audit-stars {
  letter-spacing: 0.05em;
  color: var(--accent);
}

/* The score card: a ring drawn with a conic gradient, so it needs no image
   and no script. The ring is the accent hue; the grade under it is the
   semantic one, so the state is read in words on a tint. */
.audit-score-card {
  display: grid;
  justify-items: center;
  gap: 12px;
  padding: 28px 24px;
  text-align: center;
  background: var(--card);
  border: 1px solid var(--line);
  border-radius: var(--k-radius-panel);
}

.audit-score-card p {
  margin: 4px 0 0;
  font-size: 12px;
  line-height: 1.5;
  color: var(--k-color-muted);
}

.audit-score-card p a {
  color: var(--ink);
  text-decoration: underline;
  text-underline-offset: 3px;
}

.audit-score-ring {
  --ring: var(--k-color-mint);
  display: grid;
  place-content: center;
  width: 140px;
  height: 140px;
  border-radius: 50%;
  background:
    radial-gradient(closest-side, var(--card) 78%, transparent 79% 100%),
    conic-gradient(var(--ring) calc(var(--score) * 1%), var(--k-color-lavender) 0);
}

.audit-score-ring b {
  display: block;
  font-family: var(--display);
  font-size: 44px;
  font-weight: 600;
  letter-spacing: -0.05em;
  line-height: 1;
}

.audit-score-ring small {
  font-family: var(--mono);
  font-size: 11px;
  color: var(--k-color-muted);
}

.audit-score-grade {
  display: inline-block;
  padding: 6px 14px;
  font-family: var(--display);
  font-size: 15px;
  font-weight: 600;
  letter-spacing: -0.01em;
  border-radius: var(--k-radius-pill);
}

.is-low-risk .audit-score-ring { --ring: var(--k-color-mint); }
.is-moderate-risk .audit-score-ring { --ring: var(--k-color-sky); }
.is-higher-risk .audit-score-ring { --ring: var(--k-color-coral); }

.audit-score-counts {
  display: flex;
  gap: 14px;
  margin: 4px 0 0;
  padding: 0;
  font-size: 12px;
  list-style: none;
  color: var(--k-color-muted);
}

.audit-score-counts b {
  font-family: var(--display);
  font-size: 15px;
  color: var(--ink);
}

.audit-score-counts li::before {
  content: "";
  display: inline-block;
  width: 8px;
  height: 8px;
  margin-right: 5px;
  border-radius: 50%;
  background: var(--k-color-lavender);
}

.audit-score-counts .is-warning::before { background: var(--k-color-coral); }
.audit-score-counts .is-note::before { background: var(--k-color-sky); }
.audit-score-counts .is-good::before { background: var(--k-color-mint); }

.audit-layout {
  display: grid;
  grid-template-columns: minmax(0, 1fr) 300px;
  gap: 40px;
}

.audit-main {
  min-width: 0;
}

.audit-section + .audit-section {
  margin-top: 44px;
  padding-top: 40px;
  border-top: 1px solid var(--line);
}

.audit-section h2 {
  margin: 0 0 8px;
  font-family: var(--display);
  font-size: 22px;
  font-weight: 600;
  letter-spacing: -0.02em;
  scroll-margin-top: calc(var(--topbar) + 20px);
}

.audit-section h3 {
  margin: 32px 0 12px;
  font-family: var(--display);
  font-size: 16px;
  font-weight: 600;
  letter-spacing: -0.01em;
}

.audit-section__lede {
  max-width: 64ch;
  margin: 0 0 18px;
  font-size: 14px;
  line-height: 1.6;
  color: var(--k-color-muted);
}

.audit-findings {
  display: grid;
  gap: 12px;
  margin: 0;
  padding: 0;
  list-style: none;
}

/* A finding is a panel with a rule down its left edge in the level's accent
   hue; the label on it names the level, so the rule is never the only signal. */
.audit-finding {
  --accent-rule: var(--k-color-sky);
  position: relative;
  padding: 18px 20px 18px 24px;
  background: var(--card);
  border: 1px solid var(--line);
  border-radius: var(--k-radius-panel);
}

.audit-finding::before {
  content: "";
  position: absolute;
  top: 16px;
  bottom: 16px;
  left: 0;
  width: 4px;
  border-radius: 0 4px 4px 0;
  background: var(--accent-rule);
}

.audit-finding.is-warning { --accent-rule: var(--k-color-coral); }
.audit-finding.is-note { --accent-rule: var(--k-color-sky); }
.audit-finding.is-good { --accent-rule: var(--k-color-mint); }

.audit-finding__level {
  display: inline-block;
  margin-bottom: 6px;
  font-family: var(--mono);
  font-size: 12px;
  color: var(--k-color-ink-soft);
}

.audit-finding.is-warning .audit-finding__level { color: var(--k-color-error); }
.audit-finding.is-good .audit-finding__level { color: var(--k-color-success); }

.audit-finding h3 {
  margin: 0 0 6px;
  font-size: 16px;
}

.audit-finding p {
  margin: 0;
  font-size: 14px;
  line-height: 1.6;
  color: var(--k-color-ink-soft);
}

.audit-permissions {
  display: grid;
  gap: 18px;
}

.audit-permissions table {
  width: 100%;
  overflow: hidden;
  font-size: 13px;
  background: var(--card);
  border: 1px solid var(--line);
  border-collapse: collapse;
  border-radius: var(--k-radius-panel);
}

.audit-permissions caption {
  padding: 12px 16px;
  font-family: var(--display);
  font-size: 15px;
  font-weight: 600;
  text-align: left;
  color: var(--ink);
  background: var(--k-color-lavender-soft);
}

.audit-permissions caption span {
  display: block;
  margin-top: 3px;
  font-family: var(--sans);
  font-size: 12px;
  font-weight: 500;
  color: var(--k-color-muted);
}

.audit-permissions th,
.audit-permissions td {
  padding: 10px 16px;
  text-align: left;
  vertical-align: top;
  border-top: 1px solid var(--line);
}

.audit-permissions thead th {
  font-family: var(--mono);
  font-size: 12px;
  font-weight: 400;
  color: var(--k-color-muted);
  border-top: 0;
}

.audit-permissions tbody th {
  width: 34%;
  font-weight: 700;
}

/* A write permission is marked with a coral dot before its name. */
.audit-permissions tr.is-edit th::before {
  content: "";
  display: inline-block;
  width: 7px;
  height: 7px;
  margin-right: 8px;
  vertical-align: middle;
  border-radius: 50%;
  background: var(--k-color-coral);
}

.audit-permissions td {
  color: var(--k-color-ink-soft);
}

.audit-aside-note {
  margin: 12px 0 0;
  font-size: 13px;
  color: var(--k-color-muted);
}

.audit-link {
  color: var(--accent-deep);
  text-decoration: underline;
  text-decoration-thickness: 1px;
  text-underline-offset: 3px;
}

.audit-breakdown {
  display: grid;
  gap: 8px;
  max-width: 520px;
  margin: 0;
  padding: 0;
  list-style: none;
}

.audit-breakdown li {
  display: grid;
  grid-template-columns: 52px minmax(0, 1fr) 40px 56px;
  align-items: center;
  gap: 12px;
  font-size: 13px;
}

.audit-breakdown i {
  display: block;
  height: 10px;
  border-radius: var(--k-radius-pill);
  background: linear-gradient(90deg, var(--accent) var(--share), var(--k-color-lavender) var(--share));
}

.audit-breakdown b {
  text-align: right;
}

.audit-breakdown small {
  font-family: var(--mono);
  font-size: 11px;
  text-align: right;
  color: var(--k-color-muted);
}

.audit-review {
  margin: 0 0 14px;
  padding: 18px 20px;
  background: var(--card);
  border: 1px solid var(--line);
  border-left: 4px solid var(--k-color-coral);
  border-radius: var(--k-radius-panel);
}

.audit-review header {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 12px;
  margin-bottom: 8px;
  font-size: 12px;
  color: var(--k-color-muted);
}

.audit-review header span {
  font-weight: 700;
  color: var(--ink);
}

.audit-review header time {
  font-family: var(--mono);
}

.audit-review p {
  margin: 0;
  font-size: 14px;
  line-height: 1.6;
  color: var(--k-color-ink-soft);
}

.audit-review__reply {
  margin-top: 12px !important;
  padding: 10px 12px;
  font-size: 13px !important;
  background: var(--k-color-lavender-soft);
  border-radius: var(--k-radius-control);
}

.audit-review footer {
  margin-top: 10px;
  font-size: 12px;
}

.audit-section--method p {
  max-width: 72ch;
  font-size: 14px;
  line-height: 1.65;
  color: var(--k-color-ink-soft);
}

.audit-side {
  position: sticky;
  top: calc(var(--topbar) + 14px);
  display: grid;
  align-content: start;
  gap: 14px;
}

.audit-side__card {
  padding: 20px;
}

.audit-side__card > strong {
  display: block;
  margin-bottom: 12px;
  font-family: var(--display);
  font-size: 15px;
  font-weight: 600;
  letter-spacing: -0.02em;
}

.audit-side__list {
  display: grid;
  gap: 9px;
  margin: 0;
  padding: 0;
  font-size: 13px;
  list-style: none;
}

.audit-side__list small {
  font-family: var(--mono);
  font-size: 11px;
  color: var(--k-color-muted);
}

/* Pending and missing: one panel that says what is happening and, where
   there is something to do, offers it. */
.audit-wait {
  padding: 36px 40px 32px;
}

.audit-wait h1 {
  margin: 0 0 14px;
  font-family: var(--display);
  font-size: clamp(26px, 2.8vw, 36px);
  font-weight: 600;
  letter-spacing: -0.035em;
  line-height: 1.12;
  text-wrap: balance;
}

.audit-wait p {
  max-width: 68ch;
  margin: 0 0 16px;
  font-size: 15px;
  line-height: 1.6;
  color: var(--k-color-ink-soft);
}

.audit-wait__retry {
  margin-bottom: 20px;
}

.audit-wait__links {
  margin: 20px 0 0;
  font-size: 13px;
}

@media (width <= 1080px) {
  .audit-hero,
  .audit-layout {
    grid-template-columns: minmax(0, 1fr);
  }

  .audit-side {
    position: static;
  }
}

@media (width <= 720px) {
  .audit-method__grid {
    grid-template-columns: minmax(0, 1fr);
  }

  .audit-search__row {
    flex-direction: column;
  }

  .audit-title-row {
    align-items: flex-start;
  }

  .audit-wait {
    padding: 24px 20px;
  }
}

@media (prefers-reduced-motion: reduce) {
  .sidebar,
  .drawer {
    transition: none;
  }
}

/* Support queue
   ------------------------------------------------------------------------
   The second tab of the Customers page, drawn as an inbox: everyone waiting
   down the left, newest first, and the open thread on the right. The strip
   above it holds two tabs rather than the command center's five, hence the
   modifier.

   The list and the threads interleave in the markup (row, thread, row,
   thread) and the grid sorts them: rows into the first column, each on the
   line the view wrote inline, and the open thread into the second, spanning
   every row. Below 1080px the grid is switched off and the same markup reads
   top to bottom, the open thread under its own row. The list column is the
   page's ivory, so the open row — paper, with its right edge open — joins
   the paper thread beside it like a folder tab, which is what marks it as
   current without a bar or a stripe. */

.category-tabs--pair {
  grid-template-columns: repeat(2, 1fr);
}

/* No `overflow: hidden` here, however tempting for the corners: it would
   make the panel the thread's sticky container and pin the thread 144px
   down inside it instead of under the tab strip. The column rounds itself. */
.queue-panel {
  display: flex;
  flex-direction: column;
  margin-top: 14px;
}

.queue {
  position: relative;
  display: grid;
  grid-template-columns: minmax(280px, 0.36fr) minmax(0, 1fr);
  grid-template-rows: repeat(var(--queue-rows), max-content) minmax(0, 1fr);
}

/* The ivory ground and the rule of the list column, one element behind
   every row. Sized by the grid, so it is exactly as tall as the panel. */
.queue::before {
  content: "";
  grid-column: 1;
  grid-row: 1 / -1;
  background: var(--k-color-ivory);
  border-right: 1px solid var(--line);
  border-top-left-radius: calc(var(--k-radius-panel) - 1px);
}

.queue__count {
  grid-column: 1;
  z-index: 1;
  margin: 0;
  padding: 14px 20px 12px;
  font-family: var(--mono);
  font-size: 12px;
  color: var(--k-color-muted);
  border-bottom: 1px solid var(--line);
}

/* One row of the list: the platform's lozenge, the name with the wait
   beside it, and the last thing they said on one line. */
.queue-item {
  grid-column: 1;
  position: relative;
  z-index: 1;
  display: flex;
  align-items: flex-start;
  gap: 2px;
  width: 100%;
  padding: 13px 20px 13px 18px;
  font: inherit;
  text-align: left;
  color: var(--ink);
  background: none;
  border: 0;
  border-bottom: 1px solid var(--line);
  cursor: pointer;
  transition: background-color var(--k-duration-fast) var(--k-ease-standard);
}

.queue-item .source-mark {
  flex-shrink: 0;
  margin-top: 1px;
}

.queue-item:hover {
  background: var(--k-color-lavender-soft);
}

/* The strip clips its corners, so the ring is drawn inside the row. */
.queue-item:focus-visible {
  outline-offset: -3px;
}

/* The open row: paper, joined to the thread through the column rule. The
   negative margin carries it over the rule; nothing else has to move. */
.queue-item[aria-selected="true"] {
  margin-right: -1px;
  background: var(--card);
}

.queue-item[aria-selected="true"] .queue-item__name {
  color: var(--accent-deep);
}

.queue-item__text {
  display: flex;
  flex: 1;
  flex-direction: column;
  gap: 3px;
  min-width: 0;
}

.queue-item__line {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 10px;
}

.queue-item__name {
  overflow: hidden;
  font-size: 13px;
  font-weight: 700;
  line-height: 1.4;
  white-space: nowrap;
  text-overflow: ellipsis;
}

/* The wait, in the list's own shorthand — "24m", "3h", "2d" — and, when the
   reply window is short or gone, a word saying so; the hue repeats the
   word, never replaces it. */
.queue-item__when {
  flex-shrink: 0;
  font-family: var(--mono);
  font-size: 12px;
  font-variant-numeric: tabular-nums;
  line-height: 1.4;
  color: var(--k-color-muted);
}

.queue-item__when--closing,
.queue-item__when--closed {
  font-weight: 500;
  color: var(--k-color-warning);
}

.queue-item__preview {
  overflow: hidden;
  font-size: 13px;
  line-height: 1.4;
  color: var(--k-color-muted);
  white-space: nowrap;
  text-overflow: ellipsis;
}

/* The open thread: pinned under the tab strip while a long list scrolls
   past it, so the reply box never leaves the screen. */
.queue-thread {
  grid-column: 2;
  grid-row: 1 / -1;
  position: sticky;
  top: calc(var(--topbar) + 56px + 10px + 14px);
  align-self: start;
  display: flex;
  flex-direction: column;
  gap: 20px;
  min-width: 0;
  padding: 22px 24px 24px;
}

/* `display: flex` above would otherwise beat the attribute. */
.queue-thread[hidden] {
  display: none;
}

.queue-thread__head {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-start;
  justify-content: space-between;
  gap: 8px 16px;
}

.queue-thread__who {
  display: flex;
  flex-direction: column;
  gap: 3px;
  min-width: 0;
}

.queue-thread__name {
  margin: 0;
  overflow: hidden;
  font-family: var(--display);
  font-size: 19px;
  font-weight: 600;
  letter-spacing: -0.02em;
  line-height: 1.2;
  white-space: nowrap;
  text-overflow: ellipsis;
}

.queue-thread__meta {
  margin: 0;
  font-family: var(--mono);
  font-size: 12px;
  color: var(--k-color-muted);
}

/* The reply window as a badge. Open is the ordinary state and the quietest;
   closing and closed are things to look at, in the warning pair — a wait
   that has run out is not a failure. */
.queue-window {
  flex-shrink: 0;
  padding: 3px 10px;
  font-size: 11px;
  font-weight: 700;
  line-height: 1.5;
  color: var(--k-color-ink-soft);
  background: var(--card);
  border-radius: var(--k-radius-pill);
  box-shadow: inset 0 0 0 1px var(--line);
}

.queue-window--closing,
.queue-window--closed {
  color: var(--k-color-warning);
  background: var(--k-color-warning-bg);
  box-shadow: none;
}

/* The customer's words, in bubbles hung left, the way the admin's thread
   view and every inbox draw a message from the other side. A run of texts
   shares one timestamp; the presenter decides which lines carry one. */
.queue-thread__messages {
  display: flex;
  flex-direction: column;
  gap: 6px;
  margin: 0;
  padding: 0;
  list-style: none;
}

.queue-msg {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 4px;
  max-width: min(100%, 600px);
}

.queue-msg__body {
  margin: 0;
  padding: 10px 14px;
  font-size: 14px;
  line-height: 1.5;
  color: var(--ink);
  background: var(--k-color-lavender-soft);
  border: 1px solid var(--line);
  border-radius: var(--k-radius-panel);
  border-bottom-left-radius: 4px;
  overflow-wrap: anywhere;
}

.queue-msg__body p {
  margin: 0;
}

.queue-msg__body p + p {
  margin-top: 6px;
}

/* A message with no text: what it was rather than what it said. */
.queue-msg__body--described {
  font-style: italic;
  color: var(--k-color-ink-soft);
}

.queue-msg__at {
  margin-bottom: 6px;
  padding-left: 4px;
  font-family: var(--mono);
  font-size: 11px;
  color: var(--k-color-muted);
}

/* The composer: the reply box across the top, then one row holding whose
   name the reply goes out under, the skip, and the send. The reply form is
   `display: contents` so its field and button take grid cells of their own
   beside the skip, which is a form of its own and must stay one. */
.queue-composer {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto auto;
  gap: 10px;
  align-items: center;
  margin-top: auto;
  padding-top: 20px;
  border-top: 1px solid var(--line);
}

.queue-reply {
  display: contents;
}

.queue-reply__input {
  grid-column: 1 / -1;
  grid-row: 1;
  box-sizing: border-box;
  width: 100%;
  min-height: 84px;
  padding: 11px 14px;
  font: inherit;
  font-size: 14px;
  line-height: 1.5;
  color: var(--ink);
  background: var(--card);
  border: 1px solid var(--k-color-control-border);
  border-radius: var(--k-radius-control);
  caret-color: var(--accent-deep);
  field-sizing: content;
  resize: vertical;
  transition: border-color var(--k-duration-fast) var(--k-ease-standard);
}

.queue-reply__input::placeholder {
  color: var(--k-color-muted);
}

.queue-reply__input:hover {
  border-color: var(--ink);
}

.queue-reply__input:focus-visible {
  border-color: var(--accent-deep);
}

.queue-composer__via {
  grid-column: 1;
  grid-row: 2;
  font-family: var(--mono);
  font-size: 12px;
  color: var(--k-color-muted);
}

.queue-reply__send {
  grid-column: 3;
  grid-row: 2;
  margin-top: 0;
}

/* Skip is quiet on purpose: it is the way out that sends nothing, and it
   should not compete with the reply for the eye. */
.queue-skip {
  grid-column: 2;
  grid-row: 2;
  display: flex;
}

.queue-composer__skip {
  min-height: 36px;
  padding: 0 14px;
  font: inherit;
  font-size: 13px;
  font-weight: 700;
  color: var(--ink);
  background: var(--card);
  border: 1px solid var(--k-color-control-border);
  border-radius: var(--k-radius-button);
  cursor: pointer;
  transition: background-color var(--k-duration-fast) var(--k-ease-standard);
}

.queue-composer__skip:hover {
  background: var(--k-color-lavender-soft);
}

/* Stands where the reply box would be when the window has closed: the
   reason, in the notice's warning pair, with the skip beside it. */
.queue-thread__note {
  grid-column: 1;
  grid-row: 2;
  margin: 0;
  padding: 11px 14px;
  font-size: 13px;
  line-height: 1.5;
  color: var(--k-color-warning);
  background: var(--k-color-warning-bg);
  border: 1px solid color-mix(in srgb, var(--k-color-warning) 25%, transparent);
  border-radius: var(--k-radius-control);
}

.queue-thread__note + .queue-skip {
  grid-column: 2 / -1;
}

/* One column: the list reads top to bottom and the open thread sits under
   its own row, on the same paper, ruled off below. */
@media (width <= 1080px) {
  .queue {
    display: block;
  }

  .queue::before {
    display: none;
  }

  .queue__count {
    background: var(--k-color-ivory);
  }

  .queue-item {
    background: var(--k-color-ivory);
  }

  .queue-item[aria-selected="true"] {
    margin-right: 0;
    background: var(--card);
    border-bottom-color: transparent;
  }

  .queue-thread {
    position: static;
    padding: 4px 20px 22px;
    border-bottom: 1px solid var(--line);
  }
}

@media (width <= 560px) {
  .queue-thread__head {
    flex-direction: column;
  }

  .queue-composer {
    grid-template-columns: minmax(0, 1fr) auto;
  }

  .queue-composer__via {
    grid-column: 1 / -1;
    grid-row: 3;
  }

  .queue-skip {
    grid-column: 1;
    justify-content: flex-start;
  }

  .queue-reply__send {
    grid-column: 2;
  }

  .queue-thread__note {
    grid-column: 1 / -1;
  }

  .queue-thread__note + .queue-skip {
    grid-column: 1;
    grid-row: 3;
  }
}
