/* ui/MainMenu — contract: ./MainMenu.spec.md. Tokens from ui/Theme. */

.qc-menu {
  display: grid;
  grid-template-columns: minmax(0, 1fr); /* track = viewport width, so content can't overflow */
  place-items: center;
  min-height: 100vh;
  min-height: 100dvh;
  padding: 56px 24px;
}

.qc-menu__inner {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 28px;
  /* Wide enough for the carousel to give the ship real size and still leave
     nine readable thumbnails on the strip under it. */
  width: min(1180px, 100%);
}

/* Ship identity colour, set once wherever a data-ship appears in the menu: the
   carousel frame, a strip thumbnail, the paint panel. An id Theme has no token for falls
   back to the accent inherited from the root. */
.qc-menu { --ship: var(--qc-accent); }
.qc-menu [data-ship="laser"] { --ship: var(--qc-ship-laser); }
.qc-menu [data-ship="tracerTank"] { --ship: var(--qc-ship-laser); }
.qc-menu [data-ship="plasma"] { --ship: var(--qc-ship-plasma); }
.qc-menu [data-ship="heTank"] { --ship: var(--qc-ship-plasma); }
.qc-menu [data-ship="rocket"] { --ship: var(--qc-ship-rocket); }
.qc-menu [data-ship="scatter"] { --ship: var(--qc-ship-scatter); }
.qc-menu [data-ship="canisterTank"] { --ship: var(--qc-ship-scatter); }
.qc-menu [data-ship="arc"] { --ship: var(--qc-ship-arc); }
.qc-menu [data-ship="graviton"] { --ship: var(--qc-ship-graviton); }
.qc-menu [data-ship="mortarTank"] { --ship: var(--qc-ship-graviton); }
.qc-menu [data-ship="shuriken"] { --ship: var(--qc-ship-shuriken); }
.qc-menu [data-ship="gatling"] { --ship: var(--qc-ship-gatling); }
.qc-menu [data-ship="tesla"] { --ship: var(--qc-ship-tesla); }
.qc-menu [data-ship="inferno"] { --ship: var(--qc-ship-inferno); }
.qc-menu [data-ship="flameTank"] { --ship: var(--qc-ship-inferno); }
.qc-menu [data-ship="warden"] { --ship: var(--qc-ship-warden); }
.qc-menu [data-ship="harpoon"] { --ship: var(--qc-ship-harpoon); }
.qc-menu [data-ship="chrono"] { --ship: var(--qc-ship-chrono); }
.qc-menu [data-ship="fuseTank"] { --ship: var(--qc-ship-chrono); }
.qc-menu [data-ship="foundry"] { --ship: var(--qc-ship-foundry); }

/* Ship silhouette: one clip-path per identity, in the ship colour. Shared by
   the carousel stage and the strip thumbnails; each sizes its own box. */
.qc-glyph {
  display: grid;
  place-items: center;
}

/* `--glyph` sizes the shape for its box: the carousel's stage blows it up, a
   strip thumbnail shrinks it. The shapes themselves stay one set of px sizes. */
.qc-glyph::before {
  content: "";
  width: 44px;
  height: 52px;
  background: linear-gradient(180deg, var(--ship), color-mix(in oklab, var(--ship) 35%, var(--qc-space-0)));
  clip-path: polygon(50% 0%, 100% 100%, 50% 78%, 0% 100%);
  transform: scale(var(--glyph, 1));
  transition: transform var(--qc-dur) var(--qc-ease-out);
}

.qc-menu [data-ship="laser"] .qc-glyph::before {
  width: 34px;
  height: 60px;
  clip-path: polygon(50% 0%, 63% 50%, 100% 100%, 50% 84%, 0% 100%, 37% 50%);
}

.qc-menu [data-ship="plasma"] .qc-glyph::before {
  width: 50px;
  height: 54px;
  clip-path: polygon(50% 0%, 88% 26%, 100% 70%, 50% 100%, 0% 70%, 12% 26%);
}

.qc-menu [data-ship="rocket"] .qc-glyph::before {
  width: 58px;
  height: 52px;
  clip-path: polygon(50% 0%, 100% 62%, 86% 100%, 50% 82%, 14% 100%, 0% 62%);
}

/* The six unlockable identities, matching client/Renderer's silhouettes. */
.qc-menu [data-ship="scatter"] .qc-glyph::before {
  width: 56px;
  height: 52px;
  clip-path: polygon(50% 0%, 62% 38%, 100% 100%, 76% 92%, 50% 70%, 24% 92%, 0% 100%, 38% 38%);
}

.qc-menu [data-ship="arc"] .qc-glyph::before {
  width: 44px;
  height: 58px;
  clip-path: polygon(50% 0%, 60% 26%, 82% 10%, 72% 50%, 80% 100%, 50% 72%, 20% 100%, 28% 50%, 18% 10%, 40% 26%);
}

.qc-menu [data-ship="graviton"] .qc-glyph::before {
  width: 58px;
  height: 54px;
  clip-path: polygon(50% 0%, 64% 8%, 72% 24%, 100% 36%, 100% 52%, 74% 50%, 70% 76%, 60% 92%, 50% 80%, 40% 92%, 30% 76%, 26% 50%, 0% 52%, 0% 36%, 28% 24%, 36% 8%);
}

.qc-menu [data-ship="shuriken"] .qc-glyph::before {
  width: 54px;
  height: 54px;
  clip-path: polygon(50% 0%, 62% 34%, 100% 46%, 64% 66%, 50% 100%, 36% 66%, 0% 46%, 38% 34%);
}

.qc-menu [data-ship="gatling"] .qc-glyph::before {
  width: 56px;
  height: 54px;
  clip-path: polygon(50% 0%, 58% 6%, 58% 34%, 74% 40%, 74% 56%, 100% 64%, 100% 98%, 62% 92%, 50% 80%, 38% 92%, 0% 98%, 0% 64%, 26% 56%, 26% 40%, 42% 34%, 42% 6%);
}

.qc-menu [data-ship="tesla"] .qc-glyph::before {
  width: 50px;
  height: 54px;
  clip-path: polygon(50% 0%, 68% 34%, 98% 24%, 92% 94%, 54% 84%, 50% 94%, 46% 84%, 8% 94%, 2% 24%, 32% 34%);
}

.qc-menu [data-ship="inferno"] .qc-glyph::before {
  width: 54px;
  height: 53px;
  clip-path: polygon(50% 0%, 66.4% 11%, 67.9% 3.3%, 80% 4.3%, 97.4% 18.6%, 99.8% 41.4%, 75.1% 70%, 83.9% 95.7%, 50% 78.6%, 16.1% 95.7%, 24.9% 70%, 0.2% 41.4%, 2.6% 18.6%, 20% 4.3%, 32.1% 3.3%, 33.6% 11%);
}

.qc-menu [data-ship="warden"] .qc-glyph::before {
  width: 60px;
  height: 50px;
  clip-path: polygon(50% 0%, 61.7% 7%, 62.5% 3%, 80% 3%, 100% 5%, 100% 39%, 83.3% 39%, 83.3% 80%, 72.9% 95%, 61.7% 95%, 50% 88%, 38.3% 95%, 27.1% 95%, 16.7% 80%, 16.7% 39%, 0% 39%, 0% 5%, 20% 3%, 37.5% 3%, 38.3% 7%);
}

.qc-menu [data-ship="harpoon"] .qc-glyph::before {
  width: 42px;
  height: 56px;
  clip-path: polygon(50% 0%, 59% 9%, 73% 25%, 58% 20%, 58% 36%, 68% 44%, 100% 79%, 97% 92%, 73% 85%, 66% 100%, 50% 90%, 34% 100%, 27% 85%, 3% 92%, 0% 79%, 32% 44%, 42% 36%, 42% 20%, 27% 25%, 41% 9%);
}

.qc-menu [data-ship="chrono"] .qc-glyph::before {
  width: 45px;
  height: 56px;
  clip-path: polygon(50% 0%, 70% 43.2%, 100% 67.6%, 100% 100%, 50% 81.1%, 0% 100%, 0% 67.6%, 30% 43.2%);
}

.qc-menu [data-ship="foundry"] .qc-glyph::before {
  width: 38px;
  height: 56px;
  clip-path: polygon(50% 0%, 75% 5.6%, 100% 22.2%, 100% 86.1%, 79.2% 100%, 50% 94.4%, 20.8% 100%, 0% 86.1%, 0% 22.2%, 25% 5.6%);
}

/* ------------------------------------------------------------ header --- */

.qc-menu__header {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 20px;
  text-align: center;
}

.qc-menu__title {
  margin: 0;
  font-size: clamp(30px, 6.4vw, 70px);
  font-weight: 200;
  line-height: 1;
  letter-spacing: 0.4em;
  text-indent: 0.4em; /* balances the trailing letter-spacing */
  text-transform: uppercase;
  color: var(--qc-text);
  background: linear-gradient(94deg, var(--qc-text) 18%, var(--qc-accent-2) 55%, var(--qc-accent) 88%);
  -webkit-background-clip: text;
  background-clip: text;
  -webkit-text-fill-color: transparent;
}

.qc-menu__tagline {
  display: flex;
  align-items: center;
  gap: 16px;
  margin: 0;
  color: var(--qc-text-dim);
}

.qc-menu__tagline::before,
.qc-menu__tagline::after {
  content: "";
  width: 64px;
  height: 1px;
  background: linear-gradient(90deg, transparent, var(--qc-line-strong));
}

.qc-menu__tagline::after {
  transform: scaleX(-1);
}

/* Pilot level: the account-wide level, its bar, and the XP into it. The bar is
   decoration (aria-hidden); the XP text carries the same progress in words. */
.qc-menu__pilot {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: center;
  gap: 6px 14px;
  margin: 0;
  font-size: 11px;
}

.qc-menu__pilot-level {
  color: var(--qc-text);
}

.qc-menu__pilot-bar {
  display: block;
  width: 180px;
  max-width: 45vw;
  height: 4px;
  overflow: hidden;
  background: var(--qc-line);
  border-radius: 2px;
}

.qc-menu__pilot-fill {
  display: block;
  width: calc(var(--fill, 0) * 100%);
  height: 100%;
  background: linear-gradient(90deg, var(--qc-accent-2), var(--qc-accent));
  border-radius: inherit;
  box-shadow: 0 0 10px color-mix(in oklab, var(--qc-accent) 60%, transparent);
}

.qc-menu__pilot-xp {
  color: var(--qc-text-dim);
  font-variant-numeric: tabular-nums;
}

.qc-menu__form {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 24px;
  width: 100%;
  margin: 0;
}

/* ---------------------------------------------------------- carousel --- */

/* The carousel: one glass frame holding the launch band and, under it, the
   strip of every ship. One region means one fixed height, which is what keeps
   Enter Arena above the fold on the short viewports a portal embed gets — the
   nine-card grid it replaced could not promise that at any width. Tinted and
   edged in the selected ship's colour, so the whole frame reads as that ship. */
.qc-carousel {
  display: grid;
  gap: 14px;
  width: 100%;
  padding: 16px 18px 14px;
  background:
    linear-gradient(112deg, color-mix(in oklab, var(--ship) 15%, transparent), transparent 64%),
    var(--qc-glass);
  border: 1px solid color-mix(in oklab, var(--ship) 45%, var(--qc-line));
  border-radius: var(--qc-radius);
  backdrop-filter: blur(6px);
  box-shadow: 0 26px 70px -48px var(--ship);
  transition: border-color var(--qc-dur) var(--qc-ease-out);
}

/* The launch band inside it: the carousel row, then the call to action. */
.qc-launch {
  display: grid;
  gap: 12px;
}

.qc-carousel__row {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr) auto;
  align-items: center;
  gap: 6px;
}

/* Pinned to the frame's edges, so a thumb finds them without aiming. */
.qc-carousel__arrow {
  display: grid;
  flex: none;
  place-items: center;
  min-width: 48px;
  min-height: 48px;
  padding: 0;
  background: color-mix(in oklab, var(--qc-space-1) 65%, transparent);
  border: 1px solid var(--qc-line);
  border-radius: 50%;
  color: var(--qc-text);
  cursor: pointer;
  transition:
    background-color var(--qc-dur) var(--qc-ease-out),
    border-color var(--qc-dur) var(--qc-ease-out),
    transform var(--qc-dur-fast) var(--qc-ease-out);
}

.qc-carousel__arrow:hover:not(:disabled) {
  background: color-mix(in oklab, var(--ship) 18%, var(--qc-space-1));
  border-color: color-mix(in oklab, var(--ship) 70%, transparent);
}

.qc-carousel__arrow:active:not(:disabled) {
  transform: scale(0.92);
}

.qc-carousel__arrow:disabled {
  color: var(--qc-text-faint);
  cursor: default;
  opacity: 0.4;
}

/* Two borders of a square, turned: a chevron with no glyph font to load. */
.qc-carousel__chevron {
  display: block;
  width: 11px;
  height: 11px;
  border-left: 2px solid currentColor;
  border-bottom: 2px solid currentColor;
}

.qc-carousel__arrow--prev .qc-carousel__chevron {
  transform: translateX(2px) rotate(45deg);
}

.qc-carousel__arrow--next .qc-carousel__chevron {
  transform: translateX(-2px) rotate(-135deg);
}

/* ------------------------------------------------------------- stage --- */

/* The ship at size, and the swipe surface. `pan-y` hands the browser every
   vertical gesture, so the menu keeps scrolling under a thumb and only the
   horizontal drag — the one that turns the carousel — reaches the block. */
.qc-stage {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: center;
  gap: 8px 26px;
  min-height: 184px;
  padding: 2px 6px;
  touch-action: pan-y;
  user-select: none;
  -webkit-user-select: none;
}

.qc-stage__glyph,
.qc-stage__preview {
  display: block;
  flex: none;
  width: 176px;
  height: 176px;
  filter: drop-shadow(0 0 20px color-mix(in oklab, var(--ship) 55%, transparent));
}

.qc-stage__glyph {
  --glyph: 2.2;
}

.qc-stage__id {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  align-items: start;
  flex: 1 1 320px;
  gap: 10px 16px;
  min-width: 0;
  max-width: 500px;
}

.qc-stage__head {
  display: grid;
  gap: 6px;
  grid-column: 1;
  min-width: 0;
}

.qc-stage__label {
  color: var(--qc-text-faint);
}

.qc-stage__name {
  overflow: hidden;
  font-size: 26px;
  font-weight: 600;
  line-height: 1.05;
  letter-spacing: 0.1em;
  text-overflow: ellipsis;
  text-transform: uppercase;
  white-space: nowrap;
}

/* Top right of the readout: "Mastery 7" over a bar in the ship colour. */
.qc-stage__mastery {
  display: grid;
  grid-column: 2;
  grid-row: 1;
  justify-items: end;
  justify-self: end;
  gap: 5px;
}

.qc-stage__mastery-label,
.qc-ship__mastery-label {
  font-weight: 600;
  line-height: 1;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  white-space: nowrap;
  font-variant-numeric: tabular-nums;
  color: var(--qc-text-dim);
}

.qc-stage__mastery-label {
  font-size: 10px;
}

.qc-stage__mastery-bar {
  display: block;
  width: 72px;
  height: 4px;
  overflow: hidden;
  background: var(--qc-line);
  border-radius: 2px;
}

.qc-stage__mastery-fill,
.qc-ship__mastery-fill {
  display: block;
  width: calc(var(--fill, 0) * 100%);
  height: 100%;
  background: var(--ship);
  border-radius: inherit;
  box-shadow: 0 0 8px color-mix(in oklab, var(--ship) 60%, transparent);
}

.qc-stage__mastery[data-maxed] .qc-stage__mastery-label,
.qc-ship__mastery[data-maxed] .qc-ship__mastery-label {
  color: var(--qc-rarity-legendary);
}

.qc-stage__mastery[data-maxed] .qc-stage__mastery-fill,
.qc-ship__mastery[data-maxed] .qc-ship__mastery-fill {
  background: var(--qc-rarity-legendary);
  box-shadow: 0 0 8px color-mix(in oklab, var(--qc-rarity-legendary) 60%, transparent);
}

/* A locked ship on the stage is still the sales pitch, so it is dimmed only
   enough to read as not-yours-yet: its colours, art and numbers all stay. */
.qc-stage[data-locked] :is(.qc-stage__glyph, .qc-stage__preview) {
  opacity: 0.72;
}

.qc-stage[data-locked] .qc-stage__label {
  color: var(--ship);
}

/* Padlock chip under the ship's name, reading the whole sentence the thumbnail
   has no room for. Shackle (::before) over body (::after). */
.qc-stage__lock {
  position: relative;
  grid-column: 1 / -1;
  justify-self: start;
  padding: 4px 12px 4px 28px;
  font-size: 11px;
  font-weight: 600;
  line-height: 1.35;
  letter-spacing: 0.04em;
  color: var(--qc-text);
  background: color-mix(in oklab, var(--ship) 16%, transparent);
  border: 1px solid color-mix(in oklab, var(--ship) 55%, var(--qc-line));
  border-radius: 999px;
}

.qc-stage__lock::before,
.qc-stage__lock::after {
  content: "";
  position: absolute;
  left: 12px;
  border: 1.5px solid currentColor;
}

.qc-stage__lock::before {
  top: 5px;
  width: 6px;
  height: 7px;
  margin-left: 1px;
  border-bottom: 0;
  border-radius: 3px 3px 0 0;
}

.qc-stage__lock::after {
  top: 12px;
  width: 8px;
  height: 6px;
  background: currentColor;
  border-radius: 1px;
}

.qc-stage__loadout {
  display: grid;
  grid-column: 1 / -1;
  gap: 7px;
}

.qc-stage__slot {
  display: grid;
  grid-template-columns: 58px minmax(0, 1fr);
  align-items: baseline;
  gap: 1px 12px;
}

.qc-stage__slot-label {
  font-size: 9px;
  color: var(--qc-text-faint);
}

.qc-stage__slot-name {
  overflow: hidden;
  font-size: 15px;
  font-weight: 600;
  line-height: 1.25;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.qc-stage__slot-summary {
  grid-column: 2;
  font-size: 11.5px;
  line-height: 1.35;
  color: var(--qc-text-dim);
}

.qc-stage__stats {
  display: grid;
  grid-column: 1 / -1;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 12px;
  padding-top: 11px;
  border-top: 1px solid var(--qc-line);
}

.qc-stage__stat {
  display: grid;
  gap: 5px;
  min-width: 0;
}

.qc-stage__stat-label {
  font-size: 9px;
}

/* ------------------------------------------------------------- strip --- */

/* All nine on one row, shrinking to fit rather than scrolling: the point of
   keeping a strip at all is that every ship stays comparable at a glance, and
   one that has scrolled out of view is not. */
.qc-menu__ships {
  display: flex;
  gap: 7px;
  width: 100%;
  min-width: 0;
  margin: 0;
  padding: 0;
  border: 0;
}

.qc-ship {
  position: relative;
  display: flex;
  flex: 1 1 0;
  flex-direction: column;
  align-items: center;
  gap: 6px;
  min-width: 0;
  padding: 9px 5px 8px;
  background: color-mix(in oklab, var(--qc-space-1) 40%, transparent);
  border: 1px solid var(--qc-line);
  border-radius: var(--qc-radius-sm);
  cursor: pointer;
  transition:
    transform var(--qc-dur-fast) var(--qc-ease-out),
    border-color var(--qc-dur) var(--qc-ease-out),
    background-color var(--qc-dur) var(--qc-ease-out),
    box-shadow var(--qc-dur) var(--qc-ease-out);
}

.qc-ship:hover:not([data-locked]) {
  transform: translateY(-2px);
  border-color: var(--qc-line-strong);
}

.qc-ship[data-selected] {
  background:
    linear-gradient(180deg, color-mix(in oklab, var(--ship) 18%, transparent), transparent 62%),
    color-mix(in oklab, var(--qc-space-1) 40%, transparent);
  border-color: color-mix(in oklab, var(--ship) 75%, transparent);
  box-shadow:
    0 0 0 1px color-mix(in oklab, var(--ship) 35%, transparent),
    0 18px 44px -30px var(--ship);
}

/* On the stage but not the ship that flies — only ever a locked one. A dashed
   ring, so it never reads as the filled ring of the selection beside it. */
.qc-ship[data-browsed]:not([data-selected]) {
  border-color: color-mix(in oklab, var(--ship) 70%, transparent);
  border-style: dashed;
}

.qc-ship[data-browsed] :is(.qc-ship__glyph, .qc-ship__preview) {
  opacity: 0.9;
}

.qc-ship[data-browsed] .qc-ship__name {
  color: var(--qc-text);
}

/* The radio is visually hidden, so the thumbnail wears its focus ring. */
.qc-ship:has(.qc-ship__radio:focus-visible) {
  outline: 2px solid var(--qc-accent-2);
  outline-offset: 3px;
}

.qc-menu__ships:disabled .qc-ship {
  cursor: default;
  opacity: 0.55;
  transform: none;
}

/* Visual order: art, then the name, then the mastery bar. The DOM keeps the
   name before the art, so a screen reader hears the ship before its picture. */
.qc-ship__glyph,
.qc-ship__preview {
  order: 1;
}

.qc-ship__head {
  order: 2;
  display: grid;
  justify-items: center;
  gap: 5px;
  width: 100%;
  min-width: 0;
}

.qc-ship__lock {
  order: 3;
}

.qc-ship__glyph {
  --glyph: 0.66;
  width: 100%;
  height: 54px;
}

/* The app sizes the backing store from this box; `aspect-ratio` keeps the two
   axes equal at every strip width, which is what its drawing code assumes. */
.qc-ship__preview {
  display: block;
  width: min(62px, 100%);
  height: auto;
  aspect-ratio: 1;
  margin-inline: auto;
}

/* Glyph and canvas share the treatment: dimmed with a soft glow until chosen. */
.qc-ship__glyph,
.qc-ship__preview {
  opacity: 0.55;
  filter: drop-shadow(0 0 8px color-mix(in oklab, var(--ship) 35%, transparent));
  transition:
    opacity var(--qc-dur),
    filter var(--qc-dur),
    transform var(--qc-dur) var(--qc-ease-out);
}

.qc-ship[data-selected] :is(.qc-ship__glyph, .qc-ship__preview) {
  opacity: 1;
  filter: drop-shadow(0 0 16px color-mix(in oklab, var(--ship) 70%, transparent));
}

.qc-ship__name {
  display: block;
  overflow: hidden;
  width: 100%;
  font-size: 9.5px;
  font-weight: 700;
  letter-spacing: 0.1em;
  text-align: center;
  text-overflow: ellipsis;
  text-transform: uppercase;
  white-space: nowrap;
  color: var(--qc-text-dim);
}

.qc-ship[data-selected] .qc-ship__name {
  color: var(--qc-text);
}

.qc-ship__mastery {
  display: grid;
  justify-items: center;
  gap: 4px;
  width: 100%;
}

.qc-ship__mastery-label {
  font-size: 8px;
}

.qc-ship__mastery-bar {
  display: block;
  width: min(52px, 100%);
  height: 3px;
  overflow: hidden;
  background: var(--qc-line);
  border-radius: 2px;
}

/* Locked: dimmed, dashed, and out of reach. The radio is disabled, so pointer
   and keyboard both skip the thumbnail; this is the visible half of that. */
.qc-ship[data-locked] {
  cursor: not-allowed;
  background: transparent;
  border-style: dashed;
}

.qc-ship[data-locked] :is(.qc-ship__glyph, .qc-ship__preview) {
  opacity: 0.28;
  filter: grayscale(0.55);
}

.qc-ship[data-locked][data-browsed] :is(.qc-ship__glyph, .qc-ship__preview) {
  opacity: 0.75;
  filter: grayscale(0.2);
}

.qc-ship[data-locked] .qc-ship__name {
  color: var(--qc-text-faint);
}

/* Padlock chip: shackle (::before) over body (::after), then the level. The
   full sentence is in the radio's description, which is what is read out; the
   chip is the glance version, and has to fit a thumbnail at any width. */
.qc-ship__lock {
  position: relative;
  display: block;
  padding: 2px 7px 2px 20px;
  font-size: 9px;
  font-weight: 600;
  line-height: 1.3;
  letter-spacing: 0.06em;
  white-space: nowrap;
  color: var(--qc-text-dim);
  background: color-mix(in oklab, var(--qc-space-1) 70%, transparent);
  border: 1px solid var(--qc-line);
  border-radius: 999px;
}

.qc-ship__lock-lead {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

.qc-ship__lock::before,
.qc-ship__lock::after {
  content: "";
  position: absolute;
  left: 7px;
  border: 1.5px solid currentColor;
}

.qc-ship__lock::before {
  top: 3px;
  width: 5px;
  height: 5px;
  margin-left: 1px;
  border-bottom: 0;
  border-radius: 3px 3px 0 0;
}

.qc-ship__lock::after {
  top: 8px;
  width: 7px;
  height: 5px;
  background: currentColor;
  border-radius: 1px;
}

.qc-rating {
  display: flex;
  gap: 3px;
}

.qc-rating__pip {
  flex: 1;
  height: 4px;
  background: var(--qc-line);
  border-radius: 2px;
}

.qc-rating__pip[data-filled] {
  background: var(--ship);
}

/* Narrow: the stage stacks, and the strip drops the words it has no room for. */
@media (max-width: 720px) {
  .qc-stage {
    gap: 10px;
  }

  .qc-stage__id {
    grid-template-columns: minmax(0, 1fr);
    flex-basis: 100%;
    justify-items: center;
    max-width: 380px;
  }

  .qc-stage__head {
    justify-items: center;
  }

  .qc-stage__mastery {
    grid-column: 1;
    grid-row: auto;
    justify-items: center;
    justify-self: center;
  }

  .qc-stage__loadout,
  .qc-stage__stats {
    width: 100%;
  }

  .qc-stage__lock {
    justify-self: center;
  }

  .qc-stage__slot {
    grid-template-columns: 52px minmax(0, 1fr);
  }
}

@media (max-width: 560px) {
  .qc-carousel {
    padding: 14px 10px 12px;
  }

  .qc-menu__ships {
    gap: 5px;
  }

  .qc-ship {
    gap: 4px;
    padding: 7px 3px 6px;
  }

  .qc-ship__glyph {
    --glyph: 0.46;
    height: 38px;
  }

  .qc-ship__preview {
    width: min(44px, 100%);
  }

  /* Nine names do not fit; each radio still carries the ship's name. */
  .qc-ship__name,
  .qc-ship__mastery-label {
    display: none;
  }

  /* A price does not fit a phone thumbnail: the padlock alone says locked,
     and the stage and the status line give the price. */
  .qc-ship__lock {
    width: 18px;
    height: 16px;
    margin-inline: auto;
    padding: 0;
    font-size: 8px;
  }

  .qc-ship__lock .qc-quanta__glyph,
  .qc-ship__lock-level {
    display: none;
  }

  .qc-ship__lock::before,
  .qc-ship__lock::after {
    left: 5px;
  }
}

/* -------------------------------------------------------- paint jobs --- */

.qc-paint {
  display: grid;
  grid-template-columns: 184px minmax(0, 1fr);
  align-items: center;
  gap: 28px;
  width: 100%;
  padding: 22px 24px 24px;
  background: var(--qc-glass);
  border: 1px solid var(--qc-line);
  border-radius: var(--qc-radius);
  backdrop-filter: blur(6px);
}

.qc-paint__preview {
  display: grid;
  justify-items: center;
  gap: 14px;
}

/* The app sizes the backing store from this box and draws the ship into it. */
.qc-paint__canvas {
  display: block;
  width: 160px;
  height: 160px;
  background:
    radial-gradient(circle at 50% 50%, color-mix(in oklab, var(--ship) 16%, transparent), transparent 68%),
    color-mix(in oklab, var(--qc-space-0) 55%, transparent);
  border: 1px solid var(--qc-line);
  border-radius: var(--qc-radius);
}

.qc-paint__selected {
  display: grid;
  justify-items: center;
  gap: 6px;
  margin: 0;
  text-align: center;
}

.qc-paint__selected-name {
  font-size: 14px;
  font-weight: 600;
}

.qc-paint__selected-tier {
  color: var(--tier);
}

.qc-paint__selected-none {
  font-size: 13px;
  color: var(--qc-text-faint);
}

.qc-paint__options {
  min-width: 0;
  margin: 0;
  padding: 0;
  border: 0;
}

.qc-paint__legend {
  padding: 0 0 14px;
  color: var(--qc-text-dim);
}

.qc-paint__grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(min(210px, 100%), 1fr));
  gap: 10px;
}

.qc-paint__option,
.qc-paint__selected {
  --tier: var(--qc-rarity-common);
}

[data-tier="rare"]:is(.qc-paint__option, .qc-paint__selected) { --tier: var(--qc-rarity-rare); }
[data-tier="epic"]:is(.qc-paint__option, .qc-paint__selected) { --tier: var(--qc-rarity-epic); }
[data-tier="legendary"]:is(.qc-paint__option, .qc-paint__selected) { --tier: var(--qc-rarity-legendary); }

.qc-paint__option {
  position: relative;
  display: grid;
  grid-template-columns: auto minmax(0, 1fr) auto;
  align-items: center;
  gap: 12px;
  min-height: 60px;
  padding: 10px 14px 10px 12px;
  background: color-mix(in oklab, var(--qc-space-1) 45%, transparent);
  border: 1px solid var(--qc-line);
  border-radius: var(--qc-radius-sm);
  cursor: pointer;
  transition:
    border-color var(--qc-dur) var(--qc-ease-out),
    background-color var(--qc-dur) var(--qc-ease-out),
    box-shadow var(--qc-dur) var(--qc-ease-out);
}

.qc-paint__option:not([data-locked]):hover {
  border-color: var(--qc-line-strong);
}

.qc-paint__option[data-selected] {
  background:
    linear-gradient(90deg, color-mix(in oklab, var(--ship) 14%, transparent), transparent 75%),
    color-mix(in oklab, var(--qc-space-1) 45%, transparent);
  border-color: color-mix(in oklab, var(--ship) 70%, transparent);
  box-shadow: 0 0 0 1px color-mix(in oklab, var(--ship) 30%, transparent);
}

/* The radio is visually hidden, so the tile wears its focus ring. */
.qc-paint__option:has(.qc-paint__radio:focus-visible) {
  outline: 2px solid var(--qc-accent-2);
  outline-offset: 2px;
}

.qc-paint__option[data-locked] {
  cursor: not-allowed;
  background: transparent;
  border-style: dashed;
}

.qc-paint__options:disabled .qc-paint__option {
  cursor: default;
  opacity: 0.55;
}

/* Two-tone swatch: hull body with a diagonal accent trim. */
.qc-paint__swatch {
  --swatch-hull: var(--qc-accent);
  --swatch-accent: var(--qc-accent);
  display: block;
  width: 30px;
  height: 30px;
  background: linear-gradient(135deg, var(--swatch-hull) 0 58%, var(--swatch-accent) 58% 100%);
  border-radius: 50%;
  box-shadow:
    inset 0 0 0 1px color-mix(in oklab, var(--qc-text) 22%, transparent),
    0 0 14px -2px color-mix(in oklab, var(--swatch-hull) 55%, transparent);
}

.qc-paint__swatch[data-hull="laser"] { --swatch-hull: var(--qc-ship-laser); }
.qc-paint__swatch[data-hull="plasma"] { --swatch-hull: var(--qc-ship-plasma); }
.qc-paint__swatch[data-hull="rocket"] { --swatch-hull: var(--qc-ship-rocket); }
.qc-paint__swatch[data-hull="scatter"] { --swatch-hull: var(--qc-ship-scatter); }
.qc-paint__swatch[data-hull="arc"] { --swatch-hull: var(--qc-ship-arc); }
.qc-paint__swatch[data-hull="graviton"] { --swatch-hull: var(--qc-ship-graviton); }
.qc-paint__swatch[data-hull="shuriken"] { --swatch-hull: var(--qc-ship-shuriken); }
.qc-paint__swatch[data-hull="gatling"] { --swatch-hull: var(--qc-ship-gatling); }
.qc-paint__swatch[data-hull="tesla"] { --swatch-hull: var(--qc-ship-tesla); }
.qc-paint__swatch[data-hull="inferno"] { --swatch-hull: var(--qc-ship-inferno); }
.qc-paint__swatch[data-hull="warden"] { --swatch-hull: var(--qc-ship-warden); }
.qc-paint__swatch[data-hull="harpoon"] { --swatch-hull: var(--qc-ship-harpoon); }
.qc-paint__swatch[data-hull="chrono"] { --swatch-hull: var(--qc-ship-chrono); }
.qc-paint__swatch[data-hull="foundry"] { --swatch-hull: var(--qc-ship-foundry); }
.qc-paint__swatch[data-hull="crimson"] { --swatch-hull: var(--qc-paint-crimson, var(--qc-accent)); }
.qc-paint__swatch[data-hull="solar"] { --swatch-hull: var(--qc-paint-solar, var(--qc-accent)); }
.qc-paint__swatch[data-hull="ember"] { --swatch-hull: var(--qc-paint-ember, var(--qc-accent)); }
.qc-paint__swatch[data-hull="emerald"] { --swatch-hull: var(--qc-paint-emerald, var(--qc-accent)); }
.qc-paint__swatch[data-hull="ice"] { --swatch-hull: var(--qc-paint-ice, var(--qc-accent)); }
.qc-paint__swatch[data-hull="chrome"] { --swatch-hull: var(--qc-paint-chrome, var(--qc-accent)); }
.qc-paint__swatch[data-hull="void"] { --swatch-hull: var(--qc-paint-void, var(--qc-accent)); }
.qc-paint__swatch[data-hull="magenta"] { --swatch-hull: var(--qc-paint-magenta, var(--qc-accent)); }
.qc-paint__swatch[data-hull="gold"] { --swatch-hull: var(--qc-paint-gold, var(--qc-accent)); }
.qc-paint__swatch[data-hull="aurora"] { --swatch-hull: var(--qc-paint-aurora, var(--qc-accent)); }

.qc-paint__swatch[data-accent="laser"] { --swatch-accent: var(--qc-ship-laser); }
.qc-paint__swatch[data-accent="plasma"] { --swatch-accent: var(--qc-ship-plasma); }
.qc-paint__swatch[data-accent="rocket"] { --swatch-accent: var(--qc-ship-rocket); }
.qc-paint__swatch[data-accent="scatter"] { --swatch-accent: var(--qc-ship-scatter); }
.qc-paint__swatch[data-accent="arc"] { --swatch-accent: var(--qc-ship-arc); }
.qc-paint__swatch[data-accent="graviton"] { --swatch-accent: var(--qc-ship-graviton); }
.qc-paint__swatch[data-accent="shuriken"] { --swatch-accent: var(--qc-ship-shuriken); }
.qc-paint__swatch[data-accent="gatling"] { --swatch-accent: var(--qc-ship-gatling); }
.qc-paint__swatch[data-accent="tesla"] { --swatch-accent: var(--qc-ship-tesla); }
.qc-paint__swatch[data-accent="inferno"] { --swatch-accent: var(--qc-ship-inferno); }
.qc-paint__swatch[data-accent="warden"] { --swatch-accent: var(--qc-ship-warden); }
.qc-paint__swatch[data-accent="harpoon"] { --swatch-accent: var(--qc-ship-harpoon); }
.qc-paint__swatch[data-accent="chrono"] { --swatch-accent: var(--qc-ship-chrono); }
.qc-paint__swatch[data-accent="foundry"] { --swatch-accent: var(--qc-ship-foundry); }
.qc-paint__swatch[data-accent="crimson"] { --swatch-accent: var(--qc-paint-crimson, var(--qc-accent)); }
.qc-paint__swatch[data-accent="solar"] { --swatch-accent: var(--qc-paint-solar, var(--qc-accent)); }
.qc-paint__swatch[data-accent="ember"] { --swatch-accent: var(--qc-paint-ember, var(--qc-accent)); }
.qc-paint__swatch[data-accent="emerald"] { --swatch-accent: var(--qc-paint-emerald, var(--qc-accent)); }
.qc-paint__swatch[data-accent="ice"] { --swatch-accent: var(--qc-paint-ice, var(--qc-accent)); }
.qc-paint__swatch[data-accent="chrome"] { --swatch-accent: var(--qc-paint-chrome, var(--qc-accent)); }
.qc-paint__swatch[data-accent="void"] { --swatch-accent: var(--qc-paint-void, var(--qc-accent)); }
.qc-paint__swatch[data-accent="magenta"] { --swatch-accent: var(--qc-paint-magenta, var(--qc-accent)); }
.qc-paint__swatch[data-accent="gold"] { --swatch-accent: var(--qc-paint-gold, var(--qc-accent)); }
.qc-paint__swatch[data-accent="aurora"] { --swatch-accent: var(--qc-paint-aurora, var(--qc-accent)); }

.qc-paint__option[data-locked] .qc-paint__swatch {
  opacity: 0.45;
  filter: saturate(0.5);
  box-shadow: inset 0 0 0 1px color-mix(in oklab, var(--qc-text) 22%, transparent);
}

.qc-paint__text {
  display: grid;
  gap: 5px;
  min-width: 0;
}

.qc-paint__name {
  overflow: hidden;
  font-size: 14px;
  font-weight: 600;
  white-space: nowrap;
  text-overflow: ellipsis;
}

.qc-paint__option[data-locked] .qc-paint__name {
  color: var(--qc-text-dim);
}

.qc-paint__details {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 4px 10px;
  font-size: 10px;
  font-weight: 600;
  line-height: 1;
  letter-spacing: 0.14em;
  text-transform: uppercase;
}

.qc-paint__tier {
  color: var(--tier);
}

/* Padlock drawn from two pseudo-elements: shackle over body. */
/* A locked paint job the caller will let you try: an offer, not a price tag. */
.qc-paint__ad {
  padding: 1px 5px;
  border: 1px solid color-mix(in oklab, var(--qc-accent-2) 55%, transparent);
  border-radius: var(--qc-radius-sm);
  color: var(--qc-accent-2);
  font-weight: 600;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  white-space: nowrap;
}

.qc-paint__option[data-preview="true"] {
  cursor: pointer;
}

.qc-paint__option[data-preview="true"]:hover .qc-paint__ad {
  background: color-mix(in oklab, var(--qc-accent-2) 18%, transparent);
}

.qc-paint__lock {
  position: relative;
  padding-left: 13px;
  color: var(--qc-text-faint);
  white-space: nowrap;
}

.qc-paint__lock::before,
.qc-paint__lock::after {
  content: "";
  position: absolute;
  left: 1px;
  border: 1.5px solid currentColor;
}

.qc-paint__lock::before {
  top: -3px;
  width: 5px;
  height: 6px;
  margin-left: 1px;
  border-bottom: 0;
  border-radius: 3px 3px 0 0;
}

.qc-paint__lock::after {
  top: 3px;
  width: 7px;
  height: 5px;
  background: currentColor;
  border-radius: 1px;
}

/* Selection marker, echoing the ship card's. */
.qc-paint__marker {
  display: block;
  width: 10px;
  height: 10px;
  border: 1.5px solid var(--qc-line-strong);
  border-radius: 50%;
  transition: background-color var(--qc-dur), border-color var(--qc-dur), box-shadow var(--qc-dur);
}

.qc-paint__option[data-locked] .qc-paint__marker {
  visibility: hidden;
}

.qc-paint__option[data-selected] .qc-paint__marker {
  background: var(--ship);
  border-color: var(--ship);
  box-shadow: 0 0 10px var(--ship);
}

@media (max-width: 640px) {
  .qc-paint {
    grid-template-columns: minmax(0, 1fr);
    gap: 22px;
    padding: 18px 16px 18px;
  }
}

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

/* What the match is played on, over the button that plays it. A segmented row,
   never a stack: the band must be the same height with one mode or three. */
/* A block, not a flex column: a fieldset's legend is laid out by the browser,
   not by the fieldset's formatting context, so centring it is text-align's job. */
.qc-menu__game-modes {
  display: block;
  margin: 0 0 14px;
  padding: 0;
  border: 0;
  min-width: 0;
  text-align: center;
}

.qc-menu__game-modes-legend {
  float: none;
  width: 100%;
  padding: 0 0 6px;
  text-align: center;
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--qc-text-faint);
}

.qc-menu__game-modes-row {
  display: inline-flex;
  flex-wrap: nowrap;
  gap: 4px;
  max-width: 100%;
  min-width: 0;
  padding: 3px;
  border: 1px solid var(--qc-line);
  border-radius: 999px;
  background: color-mix(in oklab, var(--qc-space-1) 70%, transparent);
}

.qc-game-mode {
  display: flex;
  flex: 0 1 auto;
  align-items: center;
  justify-content: center;
  min-width: 0;
  min-height: 34px;
  padding: 0 16px;
  border-radius: 999px;
  cursor: pointer;
  transition: background var(--qc-dur-fast), color var(--qc-dur-fast);
}

.qc-game-mode__name {
  overflow: hidden;
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.1em;
  text-overflow: ellipsis;
  white-space: nowrap;
  text-transform: uppercase;
  color: var(--qc-text-dim);
}

.qc-game-mode:hover .qc-game-mode__name {
  color: var(--qc-text);
}

.qc-game-mode[data-selected] {
  background: color-mix(in oklab, var(--qc-accent) 26%, transparent);
  box-shadow: inset 0 0 0 1px color-mix(in oklab, var(--qc-accent) 55%, transparent);
}

.qc-game-mode[data-selected] .qc-game-mode__name {
  color: var(--qc-text);
}

.qc-menu__game-modes:disabled .qc-game-mode {
  cursor: default;
  opacity: 0.5;
}

/* The radios are visually hidden, so the ring is drawn on the whole pill. */
.qc-game-mode:has(:focus-visible) {
  outline: 2px solid var(--qc-accent-2);
  outline-offset: 2px;
}

@media (max-width: 560px) {
  .qc-game-mode {
    padding: 0 10px;
  }

  .qc-game-mode__name {
    font-size: 10px;
    letter-spacing: 0.06em;
  }
}

.qc-menu__actions {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 14px;
}

.qc-menu__status {
  min-height: 1.45em;
  margin: 0;
  font-size: 13px;
  color: var(--qc-text-dim);
}

/* The idle line only repeats the ship the carousel shows: kept for a screen
   reader, hidden on screen. */
.qc-menu__status[data-quiet="true"] {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

.qc-menu__status--error {
  color: var(--qc-danger);
}

/* While a locked ship is on the stage this line is the one that says which
   ship the button actually flies, so it reads at full strength, not as a hint. */
.qc-carousel:has(.qc-stage[data-locked]) .qc-menu__status:not(.qc-menu__status--error) {
  color: var(--qc-text);
}

/* While joining (the ships fieldset is disabled), the status line carries the
   connection progress, so it breathes gently to show something is happening. */
.qc-menu__form:has(.qc-menu__ships:disabled) .qc-menu__status:not(.qc-menu__status--error) {
  animation: qc-menu-status-pulse 1.3s ease-in-out infinite alternate;
}

@keyframes qc-menu-status-pulse {
  to { opacity: 0.5; }
}

/* Play modes: one row of pills. The first is the primary call to action; the
   rest are ghost buttons padded to the primary's height. Wraps when narrow. */
.qc-menu__modes {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: center;
  gap: 14px 18px;
}

.qc-menu__modes .qc-button--ghost {
  justify-content: center;
  min-width: 170px;
  padding: 16px 30px;
}

.qc-menu__modes .qc-button--ghost:disabled {
  color: var(--qc-text-faint);
  border-color: var(--qc-line);
}

@media (max-width: 640px) {
  .qc-menu__modes {
    flex-direction: column;
    align-items: stretch;
    width: min(280px, 100%);
  }

  .qc-menu__modes .qc-button--primary {
    min-width: 0;
  }
}

/* ------------------------------------------------------ short screens --- */

/* Narrow: the page's own gutter is most of what a 520px-wide phone loses to
   chrome, so it goes first — the carousel's height is already fixed. */
@media (max-width: 640px) {
  .qc-menu {
    padding: 20px 12px;
  }

  /* ui/Settings puts its gear in this corner, so the wordmark stops short of it. */
  .qc-menu__title {
    font-size: clamp(21px, 5.2vw, 34px);
    letter-spacing: 0.3em;
    text-indent: 0.3em;
  }

  .qc-menu__inner {
    gap: 16px;
  }

  .qc-menu__form {
    gap: 16px;
  }

  .qc-stage__glyph,
  .qc-stage__preview {
    width: 132px;
    height: 132px;
  }

  .qc-stage__glyph {
    --glyph: 1.65;
  }

  .qc-stage__name {
    font-size: 22px;
  }
}

/* Laptop and portal heights: the band and its button have to clear the fold at
   1280×720 and 1024×640 with the strip already in view, so the header, the
   stage and the strip each tighten a notch. Narrow screens keep the rules
   above, which is why this one starts at 641px. */
@media (max-height: 1000px) and (min-width: 641px) {
  .qc-menu {
    padding: 14px 20px;
  }

  .qc-menu__inner {
    gap: 12px;
  }

  .qc-menu__header {
    gap: 8px;
  }

  .qc-menu__title {
    font-size: clamp(24px, 3vw, 38px);
  }

  .qc-menu__tagline::before,
  .qc-menu__tagline::after {
    width: 48px;
  }

  .qc-menu__form {
    gap: 12px;
  }

  .qc-carousel {
    gap: 10px;
    padding: 12px 14px 11px;
  }

  .qc-launch {
    gap: 10px;
  }

  .qc-stage {
    gap: 6px 22px;
    min-height: 132px;
  }

  .qc-stage__glyph,
  .qc-stage__preview {
    width: 124px;
    height: 124px;
  }

  .qc-stage__glyph {
    --glyph: 1.55;
  }

  .qc-stage__id {
    gap: 8px 14px;
  }

  .qc-stage__name {
    font-size: 21px;
  }

  .qc-stage__slot-name {
    font-size: 13.5px;
  }

  .qc-stage__slot-summary {
    font-size: 11px;
  }

  .qc-stage__stats {
    gap: 10px;
    padding-top: 8px;
  }

  .qc-stage__lock {
    padding: 3px 10px 3px 25px;
    font-size: 10px;
  }

  .qc-menu__ships {
    gap: 6px;
  }

  .qc-ship {
    gap: 5px;
    padding: 7px 4px 6px;
  }

  .qc-ship__glyph {
    --glyph: 0.56;
    height: 46px;
  }

  .qc-ship__preview {
    width: min(54px, 100%);
  }

  .qc-paint {
    grid-template-columns: 116px minmax(0, 1fr);
    gap: 18px;
    padding: 10px 16px 12px;
  }

  .qc-paint__canvas {
    width: 96px;
    height: 96px;
  }

  .qc-paint__preview {
    gap: 6px;
  }

  .qc-paint__legend {
    padding-bottom: 8px;
  }

  /* Narrower tiles so six paint jobs sit on one row beside the preview. */
  .qc-paint__grid {
    grid-template-columns: repeat(auto-fill, minmax(min(150px, 100%), 1fr));
    gap: 8px;
  }

  .qc-paint__option {
    min-height: 44px;
    gap: 9px;
    padding: 6px 10px 6px 9px;
  }

  .qc-paint__swatch {
    width: 24px;
    height: 24px;
  }

  .qc-menu__actions {
    gap: 8px;
  }
}

/* A landscape phone. Everything above the strip shrinks hard and the stage
   drops its prose: the weapon's and the special's names are what you choose on,
   and the sentence explaining them is one tap away in the arena. Last in the
   file so it beats the equally specific height and width cases above. */
@media (max-height: 520px) and (min-width: 561px) {
  .qc-menu { padding: 8px 14px; }
  .qc-menu__inner { gap: 8px; }
  .qc-menu__header { gap: 4px; }
  .qc-menu__title { font-size: clamp(18px, 3.2vw, 26px); letter-spacing: 0.26em; text-indent: 0.26em; }
  .qc-menu__tagline { display: none; }
  .qc-menu__pilot { gap: 4px 10px; font-size: 10px; }
  .qc-menu__form { gap: 8px; }

  .qc-carousel { gap: 8px; padding: 8px 10px; }
  .qc-launch { gap: 8px; }

  .qc-stage { gap: 4px 16px; min-height: 104px; padding: 0; }
  .qc-stage__glyph,
  .qc-stage__preview { width: 96px; height: 96px; }
  .qc-stage__glyph { --glyph: 1.2; }
  .qc-stage__id { flex-basis: 280px; gap: 6px 12px; }
  .qc-stage__head { gap: 3px; }
  .qc-stage__name { font-size: 17px; }
  .qc-stage__loadout { gap: 4px; }
  .qc-stage__slot { grid-template-columns: 50px minmax(0, 1fr); }
  .qc-stage__slot-name { font-size: 12px; }
  /* The prose is what makes the stage tall. */
  .qc-stage__slot-summary { display: none; }
  .qc-stage__stats { gap: 8px; padding-top: 6px; }
  .qc-stage__lock { padding: 2px 9px 2px 23px; font-size: 9px; }
  .qc-stage__lock::before { top: 4px; }
  .qc-stage__lock::after { top: 10px; }
  .qc-stage__mastery-bar { width: 56px; }

  .qc-menu__ships { gap: 5px; }
  .qc-ship { gap: 3px; padding: 5px 3px; }
  .qc-ship__glyph { --glyph: 0.45; height: 36px; }
  .qc-ship__preview { width: min(42px, 100%); }
  .qc-ship__name,
  .qc-ship__mastery-label { display: none; }
  .qc-ship__lock { padding: 1px 4px 1px 16px; font-size: 8px; }
  .qc-ship__lock::before,
  .qc-ship__lock::after { left: 5px; }

  .qc-paint { padding: 8px 12px; gap: 8px; }
  .qc-paint__canvas { width: 72px; height: 72px; }
}

/* Progression, sitting with the pilot readout rather than with the play
   actions. Deliberately small: the header is above the carousel, so every
   pixel here pushes the play button towards the fold. */
/* One row for every header button that is not a way to start a match. It is
   the only header furniture that grows, so it grows sideways: two buttons cost
   the same height as one, and the launch band below never moves down. */
.qc-menu__header-actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: center;
  gap: 10px;
}

.qc-menu__header-action {
  align-self: center;
  min-height: 32px;
  padding: 5px 16px;
  font-size: 11px;
  letter-spacing: 0.14em;
}

/* An unread note: a dot on the corner, the only thing on the row that moves. */
.qc-menu__whats-new {
  position: relative;
}

.qc-menu__whats-new-dot {
  position: absolute;
  top: -3px;
  right: -3px;
  width: 9px;
  height: 9px;
  border-radius: 50%;
  background: var(--qc-accent-2);
  box-shadow: 0 0 0 2px var(--qc-space-0), 0 0 10px var(--qc-accent-2);
  animation: qc-menu-whats-new-pulse 2.4s var(--qc-ease-out) infinite;
}

@keyframes qc-menu-whats-new-pulse {
  0%, 100% { opacity: 1; }
  50% { opacity: 0.45; }
}

@media (prefers-reduced-motion: reduce) {
  .qc-menu__whats-new-dot { animation: none; }
}

@media (max-height: 760px) {
  .qc-menu__header-actions {
    gap: 8px;
  }

  .qc-menu__header-action {
    min-height: 28px;
    padding: 3px 13px;
    font-size: 10px;
  }
}

/* A thumb needs 44px; a mouse keeps the slim pills above. The type and the
   tracking come down a step so the row still packs tight: on a 360px phone
   three pills share a line and five take two, never a sideways scroll. */
@media (pointer: coarse) {
  .qc-menu__header-actions {
    gap: 6px 8px;
  }

  .qc-menu__header-action {
    min-height: 44px;
    padding: 0 10px;
    font-size: 12px;
    letter-spacing: 0.04em;
  }
}

/* The narrowest phones (360px) need one more step for three pills a line. */
@media (pointer: coarse) and (max-width: 380px) {
  .qc-menu__header-actions {
    gap: 6px;
  }

  .qc-menu__header-action {
    padding: 0 9px;
    font-size: 11px;
  }
}

/* Publisher and legal links (claims 115-118). Quiet: it is a standing
   obligation, not a thing to read. It sits outside the form so it never greys
   out with it, and its own row so nothing above has to make space per state. */
.qc-menu__footer {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: center;
  gap: 8px 18px;
  margin: 0;
  color: var(--qc-text-dim);
  font-size: 12px;
  letter-spacing: 0.04em;
}

.qc-menu__legal {
  display: flex;
  align-items: center;
  gap: 18px;
}

.qc-menu__legal-link {
  color: inherit;
  text-decoration: none;
  border-bottom: 1px solid var(--qc-line-strong);
  /* A 34px target on a phone without a 34px box on the desktop layout: the
     padding is vertical only, so the underline still hugs the word. */
  padding: 10px 0;
}

.qc-menu__legal-link:hover,
.qc-menu__legal-link:focus-visible {
  color: var(--qc-text);
  border-bottom-color: var(--qc-accent);
}

/* ——— The command deck (docs/premium-pass.md §1.4): the selected ship lights the
   launch action, and four corner brackets frame it like a reticle that closes
   on what you are about to press. Pure CSS: eight gradient strokes. ——— */
.qc-carousel .qc-button--primary { --qc-action: var(--ship); }
.qc-menu__actions .qc-button--primary::before {
  --qc-bracket: color-mix(in srgb, var(--qc-action) 60%, transparent);
  content: "";
  position: absolute;
  inset: -9px;
  pointer-events: none;
  background:
    linear-gradient(var(--qc-bracket), var(--qc-bracket)) left top / 8px 1px no-repeat,
    linear-gradient(var(--qc-bracket), var(--qc-bracket)) left top / 1px 8px no-repeat,
    linear-gradient(var(--qc-bracket), var(--qc-bracket)) right top / 8px 1px no-repeat,
    linear-gradient(var(--qc-bracket), var(--qc-bracket)) right top / 1px 8px no-repeat,
    linear-gradient(var(--qc-bracket), var(--qc-bracket)) left bottom / 8px 1px no-repeat,
    linear-gradient(var(--qc-bracket), var(--qc-bracket)) left bottom / 1px 8px no-repeat,
    linear-gradient(var(--qc-bracket), var(--qc-bracket)) right bottom / 8px 1px no-repeat,
    linear-gradient(var(--qc-bracket), var(--qc-bracket)) right bottom / 1px 8px no-repeat;
  transition: inset var(--qc-dur-fast) var(--qc-ease-out);
}
.qc-menu__actions .qc-button--primary:not(:disabled):hover::before { inset: -12px; }
.qc-menu__actions .qc-button--primary:not(:disabled):active::before { inset: -5px; }
.qc-menu__actions .qc-button--primary:disabled::before { display: none; }

/* The way to a locked ship, on the stage itself. */
.qc-stage__unlock {
  grid-column: 1 / -1;
  justify-self: start;
  display: inline-flex;
  align-items: center;
  gap: 6px;
  min-width: 0;
  min-height: 44px;
  padding: 10px 18px;
  font-size: 13px;
}
.qc-stage__unlock .qc-quanta__glyph, .qc-stage__lock .qc-quanta__glyph, .qc-ship__lock .qc-quanta__glyph { vertical-align: -1px; margin-right: 3px; }

/* Inside ui/CommandDeck the deck's top bar carries the title; the menu starts
   straight at its actions and the carousel. */
.qc-menu[data-embedded="true"] { min-height: 0; }
.qc-menu[data-embedded="true"] .qc-menu__header { padding-top: 8px; }
