/* 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="plasma"] { --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="arc"] { --ship: var(--qc-ship-arc); }
.qc-menu [data-ship="graviton"] { --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); }

/* 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%);
}

/* ------------------------------------------------------------ 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-level::before {
  content: "Lv ";
}

.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;
  }

  .qc-ship__lock {
    padding: 1px 4px 1px 16px;
    font-size: 8px;
  }

  .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="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="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 --- */

.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);
}

.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. */
.qc-menu__leaderboard {
  align-self: center;
  min-height: 32px;
  padding: 5px 16px;
  font-size: 11px;
  letter-spacing: 0.14em;
}

@media (max-height: 760px) {
  .qc-menu__leaderboard {
    min-height: 28px;
    padding: 3px 13px;
    font-size: 10px;
  }
}
