/* CODE QUEST — css/responsive.css
 * ---------------------------------------------------------------------------
 * Loaded LAST, so everything here wins. This file only ever does three
 * things:
 *
 *   1. collapse multi-column layouts to one column
 *   2. re-tune the design tokens (type scale, rhythm, HUD height) per width
 *   3. swap a view for a better-suited one (the map becomes a card list)
 *
 * It never introduces a horizontal scrollbar: every grid falls back to
 * `minmax(0, 1fr)` and every wide element is allowed to shrink. The 320px
 * floor is a hard requirement — a Thai choice string is long, and `min-width`
 * on a flex child is the usual culprit when it breaks.
 *
 * Breakpoints, and what each one is actually for:
 *   1100px  laptop       — side rails (lesson, split) fold under
 *    900px  tablet       — the test palette leaves its column
 *    720px  large phone  — the map becomes cards; the HUD becomes two rows
 *    520px  phone        — action rows become stacked full-width buttons
 *    360px  narrow phone — last-resort single-column grids
 * ========================================================================= */

/* 1280px had a breakpoint of its own once; everything it held is now handled
   by the fluid type scale and by the 1100px rules below, so it is gone rather
   than left as an empty block for someone to wonder about. */

/* =========================================================================
 * 1. LAPTOP — 1100px
 * ========================================================================= */

@media (max-width: 1100px) {
  .cq-learn,
  .cq-split {
    grid-template-columns: minmax(0, 1fr);
  }

  .cq-grid--4 {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}

/* =========================================================================
 * 2. TABLET — 900px
 * ========================================================================= */

@media (max-width: 900px) {
  :root {
    --fs-3xl: 2rem;
    --fs-2xl: 1.6rem;
    --hud-h: 52px;
    --hud-height: 52px;
  }

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

  /* The palette moves above the question and stops being sticky so it never
     covers the answer area on a short viewport. */
  .cq-test__palette-slot {
    order: -1;
  }

  .cq-palette {
    position: static;
    max-height: none;
  }

  .cq-palette__grid {
    grid-template-columns: repeat(auto-fill, minmax(40px, 1fr));
  }

  .cq-grid--3 {
    grid-template-columns: repeat(auto-fit, minmax(min(220px, 100%), 1fr));
  }

  .cq-stage {
    max-height: 60vh;
  }

  .cq-chapter__hero-body {
    padding: var(--sp-4);
  }

  /* The phase rail becomes a single swipeable row instead of wrapping into
     an uneven block — a horizontal scroll inside its own container is fine,
     the page itself still never scrolls sideways. */
  .cq-phases {
    flex-wrap: nowrap;
    overflow-x: auto;
    scrollbar-width: none;
    padding-bottom: 2px;
    scroll-snap-type: x proximity;
  }

  .cq-phases::-webkit-scrollbar {
    display: none;
  }

  .cq-phase {
    scroll-snap-align: start;
  }

  .cq-section-head {
    flex-direction: column;
    align-items: flex-start;
    gap: var(--sp-3);
  }
}

/* =========================================================================
 * 3. LARGE PHONE / SMALL TABLET — 720px
 * ========================================================================= */

@media (max-width: 720px) {
  :root {
    --fs-3xl: 1.75rem;
    --fs-2xl: 1.45rem;
    --fs-xl: 1.25rem;
    --sp-7: 2.25rem;
    --sp-8: 3rem;
  }

  .cq-grid--2,
  .cq-grid--3,
  .cq-grid--4 {
    grid-template-columns: minmax(0, 1fr);
  }

  /* The map's absolutely positioned nodes cannot stay legible at this width,
     so the card list replaces it entirely. */
  .cq-map-wrap {
    display: none;
  }

  .cq-chapter-cards-wrap {
    display: block;
  }

  .cq-dialogue {
    flex-direction: column;
    gap: var(--sp-3);
  }

  .cq-dialogue__portrait {
    width: 56px;
    height: 56px;
  }

  /* Below this width the bar becomes two rows: identity on the first, the
     live values on the second. Nothing is clipped and nothing overflows. */
  .cq-hud {
    gap: var(--sp-2) var(--sp-3);
    padding-block: var(--sp-2);
  }

  .cq-hud__brand {
    font-size: var(--fs-xs);
    letter-spacing: 0.1em;
  }

  .cq-hud__items {
    gap: var(--sp-2) var(--sp-3);
    flex-basis: 100%;
    margin-left: 0;
    justify-content: space-between;
  }

  .cq-hud__item--optional {
    display: none;
  }

  /* The sound popover would hang off the right edge of a narrow screen, so
     it becomes a near-full-width sheet pinned inside the gutter. */
  .cq-sound__panel {
    position: fixed;
    top: calc(var(--hud-h) + var(--sp-2));
    right: var(--page-gutter);
    left: var(--page-gutter);
    width: auto;
  }

  .cq-test__nav {
    flex-direction: column-reverse;
    align-items: stretch;
  }

  .cq-test__nav-group {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }

  .cq-test__nav .cq-btn {
    width: 100%;
  }

  .cq-mission__actions {
    flex-direction: column-reverse;
  }

  .cq-mission__actions .cq-btn {
    width: 100%;
  }

  /* Mission briefing: the attempt pips drop under the title instead of
     fighting it for the same row. */
  .cq-mission__head {
    flex-direction: column;
    align-items: flex-start;
  }

  .cq-mission__attempts {
    align-self: flex-start;
  }

  .cq-workbench {
    padding: var(--sp-4) var(--sp-3);
  }

  .cq-compare,
  .cq-reward-grid,
  .cq-result__student {
    grid-template-columns: minmax(0, 1fr);
  }

  .cq-cert {
    aspect-ratio: auto;
    min-height: 60vh;
  }

  .cq-cert__name {
    min-width: 92%;
  }

  .cq-cert__body {
    max-width: 92%;
  }

  .cq-cert__foot {
    flex-direction: column;
    align-items: center;
    gap: var(--sp-3);
    text-align: center;
  }

  .cq-cert__sign {
    max-width: 100%;
    width: 80%;
  }

  /* A 21:7 banner is a 60px-tall sliver on a phone; give the chapter hero a
     usable shape instead. The image still fills it without cropping oddly
     because it is object-fit: cover on a wide source. */
  .cq-chapter__hero-img {
    aspect-ratio: 16 / 10;
  }

  .cq-chapter-done__core {
    width: 92px;
  }

  .cq-steps {
    gap: var(--sp-1);
  }

  .cq-steps__line {
    width: 14px;
  }
}

/* =========================================================================
 * 4. PHONE — 520px
 * ========================================================================= */

@media (max-width: 520px) {
  :root {
    --page-gutter: 0.875rem;
    --fs-3xl: 1.55rem;
    --fs-2xl: 1.3rem;
  }

  .cq-actions-row,
  .cq-victory__actions,
  .cq-result__actions,
  .cq-chapter-done__actions,
  .cq-cert__actions,
  .cq-modal__actions {
    flex-direction: column;
    align-items: stretch;
  }

  .cq-actions-row .cq-btn,
  .cq-victory__actions .cq-btn,
  .cq-result__actions .cq-btn,
  .cq-chapter-done__actions .cq-btn,
  .cq-cert__actions .cq-btn,
  .cq-modal__actions .cq-btn {
    width: 100%;
  }

  /* The hero button wrapper carries the float animation, so it — not the
     button — is what has to go full width. */
  .cq-btn-hero-wrap {
    width: 100%;
  }

  .cq-btn-hero-wrap .cq-btn {
    width: 100%;
  }

  .cq-panel {
    padding: var(--sp-4);
  }

  .cq-question {
    padding: var(--sp-4);
  }

  .cq-question__img {
    max-height: 38vh;
  }

  .cq-ops {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }

  .cq-op {
    min-width: 0;
    width: 100%;
  }

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

  .cq-expr {
    font-size: var(--fs-base);
    padding: var(--sp-3);
  }

  .cq-codeblock {
    font-size: var(--fs-sm);
  }

  /* The trace table is the one element allowed to scroll sideways, inside
     its own container. */
  .cq-trace {
    font-size: var(--fs-xs);
  }

  .cq-table-scroll {
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
  }

  .cq-stage {
    border-radius: var(--r-md);
    max-height: 52vh;
  }

  .cq-profile__intro {
    flex-direction: column;
    text-align: center;
    align-items: center;
  }

  /* The map's summary strip: two columns of figures instead of five. */
  .cq-map__stats {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }

  .cq-palette__grid {
    grid-template-columns: repeat(auto-fill, minmax(38px, 1fr));
  }

  .cq-feedback {
    flex-direction: column;
    align-items: flex-start;
    text-align: left;
  }

  .cq-modal__box {
    width: 100%;
  }
}

/* =========================================================================
 * 5. NARROW PHONE — 360px (the 320px floor lives here)
 * ========================================================================= */

@media (max-width: 360px) {
  :root {
    --page-gutter: 0.75rem;
  }

  .cq-hud__brand span {
    display: none;
  }

  .cq-test__nav-group,
  .cq-ops {
    grid-template-columns: minmax(0, 1fr);
  }

  /* Bloom/topic mini-breakdowns are the last thing to give up two columns. */
  .cq-test-done__topics {
    grid-template-columns: minmax(0, 1fr);
  }
}

/* =========================================================================
 * 6. SHORT VIEWPORTS
 *
 * A laptop in a small window, or a tablet in landscape, has width to spare
 * and no height. Sticky elements and tall media are what break there.
 * ========================================================================= */

@media (max-height: 620px) and (min-width: 901px) {
  .cq-palette {
    position: static;
  }

  .cq-stage {
    max-height: 54vh;
  }
}

@media (max-height: 560px) {
  /* The mission scene must never push the activity below the fold — this is
     the whole reason it is capped at all. */
  .cq-mission > .cq-stage {
    max-height: min(30vh, 180px);
  }
}

/* =========================================================================
 * 7. MAP / CARD VISIBILITY
 *
 * Above 720px the map is the primary view and the card list is hidden; the
 * 720px block above flips it. Both halves of the rule live here so they
 * cannot drift apart.
 * ========================================================================= */

.cq-chapter-cards-wrap {
  display: none;
}

@media (min-width: 721px) {
  .cq-map-wrap {
    display: block;
  }
}

/* =========================================================================
 * 8. INPUT CAPABILITY
 *
 * On a touch screen a :hover transform sticks after the tap and leaves the
 * element visibly displaced, so every lift is disabled. The press state
 * (:active) stays — that is the feedback a finger actually needs.
 * ========================================================================= */

@media (hover: none) {
  .cq-btn:hover,
  .cq-option:hover,
  .cq-choice:hover,
  .cq-op:hover,
  .cq-binary__card:hover,
  .cq-mission-item:hover,
  .cq-chapter-card:hover,
  .cq-map__node:hover,
  .cq-score-card:hover,
  .cq-reward-list__item:hover,
  .cq-breakdown__row:hover,
  .cq-learn__objective:hover,
  .cq-stat:hover,
  .cq-panel--lift:hover,
  .cq-core-list__row:hover,
  .cq-palette__cell:hover {
    transform: none;
  }

  /* Touch targets: 44px is the accepted minimum, and these are the controls
     a learner taps repeatedly. */
  .cq-palette__cell,
  .cq-op,
  .cq-choice,
  .cq-option {
    min-height: 44px;
  }
}

/* Fine-pointer devices get the full hover treatment; nothing to add here,
   but the query is kept as the documented counterpart to the block above. */

/* =========================================================================
 * 9. PRINT
 *
 * result.css owns the certificate's paper styles. This is only the layout
 * flattening that applies to every page.
 * ========================================================================= */

@media print {
  .cq-fx,
  .cq-sound,
  .cq-hud,
  .cq-palette {
    display: none !important;
  }

  .cq-test,
  .cq-learn,
  .cq-split {
    grid-template-columns: minmax(0, 1fr) !important;
  }
}
