/* layout-b.css
   Variant B: fixed left sidebar (brand + nav + CTA) alongside a scrolling
   content column that itself splits into a two-column area lower down
   (games + article on the left, bonus rail on the right). On narrow
   viewports the sidebar becomes a single off-canvas drawer — same nav list,
   just repositioned, never a duplicate. */

.qv-shell { display: flex; min-height: 100vh; }

.qv-scrim {
  display: none;
  position: fixed;
  inset: 0;
  background: var(--overlay);
  z-index: var(--z-dialog);
}
.qv-scrim.show { display: block; }

.qv-side {
  position: fixed;
  top: 0;
  bottom: 0;
  left: 0;
  width: 260px;
  padding: var(--sp-6) var(--sp-5);
  display: flex;
  flex-direction: column;
  gap: var(--sp-8);
  background: var(--surface);
  border-right: 1px solid var(--line);
  transform: translateX(-100%);
  transition: transform var(--dur) var(--ease-out);
  z-index: var(--z-dialog);
  overflow-y: auto;
}
.qv-side.open { transform: translateX(0); }
@media (min-width: 1024px) {
  /* Sticky rail pinned to the viewport instead of the container edges it
     used for the mobile off-canvas drawer — keeps `bottom: 0` from fighting
     `top: 0` (the jitter Правка 1 also touches) and, more importantly,
     makes the rail's own box span the full viewport height so its
     background covers the left column all the way down even when the nav
     list itself is short (Правка 2: no empty void below a short sidebar). */
  .qv-side {
    position: sticky;
    top: 0;
    bottom: auto;
    left: auto;
    height: 100vh;
    align-self: flex-start;
    transform: none;
    z-index: auto;
  }
  .qv-scrim { display: none !important; }
}

.qv-side__nav { display: flex; flex-direction: column; gap: var(--sp-4); }
.qv-side__nav a { color: var(--text-2); font-size: var(--fs-sm); font-weight: var(--fw-medium); }
.qv-side__nav a:hover { color: var(--accent); }
.qv-side__cta { margin-top: auto; }

.qv-content { flex: 1; min-width: 0; }
/* No margin-left reservation at desktop: `.side` is already an in-flow flex
   sibling (position: sticky, not fixed) inside `.shell`, so `.content`
   naturally starts after it. The old fixed 260px margin doubled the offset
   from the sticky rail's own 260px width, producing an empty second column
   the full height of the page (Правка 2). */

.qv-content > .qv-topbar {
  display: flex;
  align-items: center;
  gap: var(--sp-4);
  padding: var(--sp-4) var(--gutter-mobile);
  border-bottom: 1px solid var(--line);
}
@media (min-width: 1024px) { .qv-content > .qv-topbar .qv-navtoggle { display: none; } }

/* Full content width — matches `.columns`/`.games`/`.bonuses` below it, no
   artificial narrow cap that used to leave dead space beside a short hero
   (Правка 2). */
.qv-hero { padding: var(--sp-10) var(--gutter-mobile) var(--sp-8); }
@media (min-width: 768px) { .qv-hero { padding-inline: var(--gutter-desktop); } }
.qv-hero__title { font-size: var(--fs-display); margin-block: var(--sp-3); white-space: pre-line; }
.qv-hero__sub { color: var(--text-2); font-size: var(--fs-lg); line-height: var(--lh-body); margin-bottom: var(--sp-5); max-width: 65ch; }

.qv-columns { padding-inline: var(--gutter-mobile); display: flex; flex-direction: column; gap: var(--sp-10); }
@media (min-width: 768px) { .qv-columns { padding-inline: var(--gutter-desktop); } }
@media (min-width: 1024px) { .qv-columns { flex-direction: row; align-items: flex-start; } }

.qv-col-main { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: var(--sp-10); }
.qv-col-side { width: 100%; }
@media (min-width: 1024px) { .qv-col-side { width: 320px; flex-shrink: 0; position: sticky; top: var(--sp-6); } }

.qv-games h2, .qv-bonuses h2 { font-size: var(--fs-h2); margin-bottom: var(--sp-5); }
.qv-bonuses { display: flex; flex-direction: column; gap: var(--sp-4); }
.qv-bonus-card--stacked { padding: var(--sp-5); }

.qv-content > .qv-footer { margin-top: var(--sp-12); }
