/* =================================================================
   RESPONSIVE — every media query in the site, consolidated
   -----------------------------------------------------------------
   Loaded last, deliberately: these rules exist to override base
   styles defined in the other four files (regardless of which one a
   given base rule lives in), which only works reliably if this file
   comes after all of them in the cascade. Extracted from what was
   previously ~20 @media blocks scattered throughout one large file;
   consolidating them here is what "media query wise CSS" means in
   this codebase's organization.
================================================================= */
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    --color-primary:        var(--indigo-400-dark);
    --color-primary-hover:  #A5B4FC;
    --color-primary-subtle: var(--indigo-50-dark);
    --color-text:            var(--gray-50-dark);
    --color-text-muted:      var(--gray-400-dark);
    --color-bg:              var(--gray-950-dark);
    --color-surface:         var(--gray-900-dark);
    --color-surface-rgb: 32, 33, 36;
    --color-border:          var(--gray-700-dark);
    --color-error-text:     var(--red-text-dark);
    --color-error-bg:       var(--red-bg-dark);
    --color-error-border:   var(--red-border-dark);
    --color-success-text:   var(--green-text-dark);
    --color-success-bg:     var(--green-bg-dark);
    --color-success-border: var(--green-border-dark);
    --color-warning-text:   var(--amber-text-dark);
    --color-warning-bg:     var(--amber-bg-dark);
    --color-warning-border: var(--amber-border-dark);
    --color-shimmer-1: var(--shimmer-1-dark);
    --color-shimmer-2: var(--shimmer-2-dark);
  }
  /* Same reasoning as the explicit data-theme="dark" body override
     in tokens.css — body's own background is deliberately white
     (--color-surface) as its light-theme default, so device-default
     dark visitors need it pointed back at --bg here too, not left to
     inherit --color-surface's own (lighter "card") dark value. */
  html:not([data-theme="light"]) body { background: var(--color-bg); }
  html:not([data-theme="light"]) { background: var(--color-bg); }
  /* Same icon-swap as the explicit data-theme="dark" rule (see
     tokens.css) — device-default visitors whose OS is set to dark
     get the moon icon too, not just people who explicitly chose it
     through the toggle. */
  html:not([data-theme="light"]) .themeswitch__icon-light { display: none; }
  html:not([data-theme="light"]) .themeswitch__icon-dark { display: inline-flex; }
}

@media (prefers-reduced-motion: reduce) {
  .sidebar__progress.is-loading .sidebar__progress-count::before,
  .sidebar__progress.is-loading .sidebar__progress-bar::before { animation: none; background-position: 50% 0; }
}

@media (prefers-reduced-motion: reduce) {
  .ad-slot.is-loading .ad-slot__skeleton { animation: none; background-position: 50% 0; }
}

@media (max-width: 480px) {
  .quizapp__results-row { flex-direction: column; align-items: flex-start; }
  .quizapp__stat { width: 100%; }
  /* The Interview Q&A level-tabs row (All / Top Questions / Fresher /
     Experienced) is a plain flex row with no wrap — fine down through
     tablet, but its four labels no longer fit a 375px-class phone
     width and were overflowing the page horizontally. A horizontally
     scrolling tab strip (the standard mobile pattern for this) fixes
     it without touching the tablet/desktop layout above 480px. */
  .level-tabs {
    flex-wrap: nowrap;
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
    scrollbar-width: none;
  }
  .level-tabs::-webkit-scrollbar { display: none; }
  .level-tab { flex: 0 0 auto; white-space: nowrap; }

  /* Character Count's five-item stats bar (Characters/Words/
     Sentences/Paragraphs/Spaces) is a single flex row — fine down
     through tablet, but five columns is too tight for a phone width:
     each .charcount-stat is flex: 1 with the flexbox default
     min-width: auto, so a cell can never shrink narrower than its
     label's own min-content width, and a single unbroken word like
     "Paragraphs" is wider than a fifth of a phone screen. The parent's
     overflow: hidden then just silently clipped/overlapped the
     labels instead of wrapping them. A 2-column grid (5 items as
     2+2+1, the lone 5th spanning both columns on its own row) gives
     each label enough width to sit on one line without crowding.
     Borders are rebuilt by hand here since the flex row's own
     border-right-on-every-item-but-the-last no longer matches a
     2-column grid's actual last-in-row items. */
  .charcount-stats { display: grid; grid-template-columns: repeat(2, 1fr); }
  .charcount-stat { border-right: 1px solid var(--border); border-bottom: 1px solid var(--border); }
  .charcount-stat:nth-child(2n) { border-right: none; }
  .charcount-stat:nth-child(5) { grid-column: 1 / -1; border-right: none; border-bottom: none; }

  /* Style guide (internal reference page, page=styleguide): its
     .sg-icons (icon samples) and .sg-row (button/CTA/search-form
     demos) rows are both plain flex rows with no wrap, sized for
     desktop — several fixed-width demo items in a row don't fit a
     phone width and were pushing the whole page into horizontal
     scroll. Wrapping is enough; each demo item keeps its own size. */
  .sg-icons { flex-wrap: wrap; gap: 20px; }
  .sg-row { flex-wrap: wrap; }
}

@media (max-width: 1280px) {
  .toc-rail { display: none; }
  .layout { grid-template-columns: 240px minmax(0, 1fr); }
  .tool-ads-rail { display: none; }
  /* .lesson-layout (layout.css) is a flex row hardcoded to a fixed
     1280px width — correct at its own reference size, but with no
     responsive rule of its own it just forced horizontal scrolling
     on every narrower viewport instead of shrinking. Its toc-rail
     child is already hidden by the rule above at this same
     breakpoint, so the only children left in the flex row are the
     sidebar (handled separately below/further down as an off-canvas
     drawer once it goes fixed-position) and #docs-main (flex: 1 1
     auto, so it happily fills whatever width the row actually has) —
     letting the row itself go fluid here is all that's needed. */
  .lesson-layout { width: 100%; }
}

@media (max-width: 1024px) {
  .layout {
    grid-template-columns: 1fr;
    gap: 24px;
    padding: 24px 24px 0;
  }
  /* .sidebar and .sidebar__scroll's actual mobile/tablet treatment
     (the off-canvas drawer) is defined further down, in the
     "hamburger-triggered sidebar drawer" block — not here, since a
     fixed-position, slide-in drawer needs different values for
     these same properties than a plain static rule would give it. */
  .article { max-width: none; }

  .topbar__inner { flex-wrap: wrap; gap: 12px 20px; padding: 12px 16px; }
  .topbar__right { margin-left: auto; }

  .topbar-hamburger { display: inline-flex; }
  /* Try It Editor now lives in the always-visible .topbar__right
     (alongside the language switcher), rather than inside the
     hamburger drawer — hidden throughout this same ≤1024px range
     (not just phone widths) to avoid crowding that area at tablet
     widths too, where the brand logo, hamburger, Try It Editor, and
     language switcher together were sometimes just wide enough to
     wrap onto a second line, making the whole header visibly taller
     than it needed to be. Still reachable via lesson pages' own Edit
     buttons. */
  .topbar__right .toplinks__tool-link { display: none; }
  .topbar-nav-backdrop {
    display: none;
    position: fixed;
    inset: 0;
    background: rgba(15, 16, 19, 0.45);
    z-index: 90;
  }
  .topbar-nav-backdrop.is-open { display: block; }
  .toplinks {
    position: fixed;
    top: 0;
    right: 0;
    bottom: 0;
    width: min(320px, 84vw);
    background: var(--surface);
    z-index: 91;
    padding: 56px 20px 0;
    transform: translateX(100%);
    transition: transform 0.22s ease;
    box-shadow: -2px 0 18px rgba(15, 16, 19, 0.15);
    display: flex;
    flex-direction: column;
    min-height: 0;
  }
  /* A separate inner scroll container, same reasoning as the chapter
     sidebar's own .sidebar__scroll: the close button is positioned
     absolute against .toplinks itself, so if .toplinks scrolled
     directly, a long enough nav list (several dropdowns' worth of
     items, all expanded inline on mobile) could scroll the close
     button out of view along with everything else. Scrolling only
     this inner wrapper keeps the close button reliably fixed in
     place, exactly like the sidebar drawer.
     flex: 1 1 auto + min-height: 0 (rather than height: 100%) is
     what makes this size naturally to its actual content — a short
     nav list stays short instead of being stretched to fill the
     drawer's full height and leaving visible empty space below it,
     while still scrolling correctly if the content ever does exceed
     the available space. */
  .toplinks__scroll { flex: 1 1 auto; min-height: 0; overflow-y: auto; padding-bottom: 50px; }
  .toplinks__list {
    display: flex;
    flex-direction: column;
    align-items: stretch;
    gap: 4px;
  }
  .toplinks.is-open { transform: translateX(0); }
  .toplinks .nav-dropdown { width: 100%; }
  .toplinks .nav-dropdown__trigger { width: 100%; justify-content: space-between; }
  .toplinks .nav-dropdown__menu {
    position: static;
    box-shadow: none;
    border: none;
    width: 100%;
    /* The base rule hides a closed menu with opacity/visibility
       alone (so it can float, absolutely positioned, without
       affecting layout while hidden). On mobile this becomes
       position: static instead — part of normal document flow — so
       opacity/visibility alone is no longer enough: an invisible
       menu would still reserve its full height, leaving a large
       dead gap under every closed dropdown. display: none actually
       removes it from flow until it's opened. */
    display: none;
    opacity: 1;
    visibility: visible;
    transform: none;
  }
  .toplinks .nav-dropdown.is-open .nav-dropdown__menu { display: block; }
  /* Mega menu collapses to a single-column stacked list on mobile —
     the wide grid, colored icons, and side panel are a desktop-space
     luxury a 320px drawer doesn't have room for. Same display:none
     reasoning as the plain dropdown above: position:static here
     needs the menu actually removed from flow while closed, not
     just made invisible, or every closed dropdown would leave a
     large dead gap in the drawer. */
  .toplinks .mega-menu {
    display: none;
    position: static;
    box-shadow: none;
    border: none;
    width: 100%;
    padding: 8px 0 0;
    flex-direction: column;
    gap: 0;
    opacity: 1;
    visibility: visible;
    transform: none;
  }
  .toplinks .nav-dropdown.is-open .mega-menu { display: flex; }
  .toplinks .mega-menu__columns { flex-direction: column; gap: 4px; }
  .toplinks__close {
    display: flex;
    align-items: center;
    justify-content: center;
    position: absolute;
    top: 12px;
    right: 12px;
    width: 32px;
    height: 32px;
    border-radius: 50%;
    border: 1px solid var(--border);
    background: var(--surface);
    font-size: 1.1rem;
    line-height: 1;
    cursor: pointer;
    color: var(--ink);
  }

  /* The language switcher lives in .topbar__right, outside .toplinks,
     so it never picked up the accordion treatment above — it still
     opened as a floating absolute-positioned overlay on mobile/tablet
     while its sibling dropdowns correctly expanded inline. Same fix
     (position: static, matching the pattern above), applied here for
     the one dropdown left out — and, just like that fix needed a
     second pass, position: static alone isn't enough on its own: it
     puts the menu into normal document flow, but without also
     overriding the base rule's opacity/visibility hiding with an
     actual display: none when closed, the closed menu still silently
     reserves its full expanded height in the layout while invisible,
     which is what was inflating the whole topbar's height on mobile
     and tablet. */
  /* Language and theme switcher triggers, unlike the hamburger and
     chapters-toggle buttons above, stay visible on desktop too —
     their base padding (6px 8px, ~26px tall) is fine for a mouse
     there, but falls short of a comfortable touch target on mobile.
     Widened only within this mobile/tablet breakpoint rather than
     changing the shared base rule, so desktop's denser nav bar is
     untouched. */
  .topbar__right .nav-dropdown__trigger { padding: 14px 10px; }
  /* position: fixed, anchored to the viewport itself, rather than
     trying to make this menu "full width of its own parent" — two
     earlier attempts at that (flex-wrap + flex-basis: 100% on the
     dropdown itself, then the same trick one level up on
     .topbar__right too) both ran into the same root problem:
     .topbar__right has no explicit width of its own on mobile, so
     every "100%" in that chain was 100% of an ancestor that was
     itself only ever as wide as its icon buttons — never the actual
     screen. Anchoring to the viewport directly sidesteps that whole
     chain: this menu's width is no longer computed relative to any
     ancestor at all. top is set inline by the same JS that toggles
     .is-open (see app.js), reading the header's actual rendered
     height at that moment — needed because the mobile header can
     wrap across a different number of rows depending on content, so
     a single fixed top value here couldn't stay correct across every
     case the way a JS-measured one can. */
  .topbar__right .nav-dropdown__menu {
    position: fixed;
    left: 16px;
    right: 16px;
    width: auto;
    max-height: calc(100vh - 80px);
    overflow-y: auto;
    box-shadow: 0 8px 24px rgba(15, 16, 19, 0.18);
    border: 1px solid var(--border);
    display: none;
    opacity: 1;
    visibility: visible;
    transform: none;
  }
  .topbar__right .nav-dropdown.is-open .nav-dropdown__menu { display: block; }
}

@media (min-width: 768px) and (max-width: 992px) {
  .layout { padding-left: 28px; padding-right: 28px; }
  /* Tutorial (lesson) page only, reduced further per explicit
     request — .lesson-layout's own left/right gutter (28px, inherited
     from the shared .layout rule above) plus #docs-main's own
     32px/40px left/right padding (layout.css, unconditional at every
     width) compound into a lot of dead space on a tablet screen.
     Scoped to .lesson-layout specifically so every other .layout
     page (quiz, interview prep, the tools) keeps its own padding. */
  .lesson-layout { padding-left: 20px; padding-right: 20px; }
  .lesson-layout #docs-main { padding-left: 24px; padding-right: 24px; }
}

@media (max-width: 767px) {
  .layout { padding-left: 16px; padding-right: 16px; }
  /* Same reasoning as the tablet block above, tighter still for
     phone width. */
  .lesson-layout { padding-left: 12px; padding-right: 12px; }
  .lesson-layout #docs-main { padding-left: 16px; padding-right: 16px; }

  .article__head, .article h1 { font-size: 1.55rem; }
  /* Previous/Next stay side by side even on mobile — just more
     compact, and the title text under each label truncates instead
     of wrapping, so two narrow buttons never force a stacked layout. */
  .pager { gap: 8px; }
  .pager__link { max-width: 48%; padding: 8px 10px; }
  .pager__link--next { text-align: right; margin-left: auto; }

  /* Icon-only prev/next at the top of the article (distinct from the
     text-based .pager buttons above, which already have plenty of
     touch area from their own padding + label text) — 34x34 is fine
     for a mouse but short of a comfortable tap target, and unlike
     the hamburger/close buttons this one stays visible on desktop
     too, so it's widened here rather than in its own base rule. */
  .article__head-nav-btn { width: 44px; height: 44px; }
  /* Same reasoning for the ad popup's close button — visible on both
     desktop and mobile (JS-controlled via the hidden attribute, not
     a mobile-only drawer), so widened only within this breakpoint. */
  .ad-popup__close { width: 44px; height: 44px; }

  /* The code toolbar (Copy/Preview/Edit, each with a running count)
     can wrap onto a second row on narrow screens — give the code
     panel extra top clearance so a wrapped toolbar never overlaps
     the first line of actual code. */
  .article pre { padding-top: 64px; }
}

@media (hover: none) {
  .code-copy { opacity: 1; }
}

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  * { transition-duration: 0.001ms !important; }
}

@media (max-width: 900px) {
  .home__courses { grid-template-columns: repeat(2, 1fr); }
}

@media (max-width: 640px) {
  .home__courses { grid-template-columns: 1fr; }
  .home__hero h1 { font-size: 1.7rem; }
}

@media (max-width: 860px) {
  .editor-body { grid-template-columns: 1fr; grid-template-rows: 1fr 1fr; }
  .editor-pane--code { border-right: none; border-bottom: 1px solid var(--border); }
  .editor-resize-handle { display: none; }
  .ad-slot--leaderboard { display: none; }
  /* The topbar's label + language select + Copy/Download/Run buttons
     no longer all fit one row once the language dropdown was added —
     wrapping keeps every control reachable instead of the row
     overflowing the page horizontally. */
  .editor-topbar { flex-wrap: wrap; row-gap: 10px; }
  .editor-topbar__actions { flex-wrap: wrap; row-gap: 10px; }
}

@media (max-width: 860px) {
  .diff-results__panes { grid-template-columns: 1fr; grid-auto-rows: minmax(200px, auto); overflow-y: auto; }
  .diff-pane[data-diff-pane="a"] { border-right: none; border-bottom: 1px solid var(--border); }
}

@media (max-width: 860px) {
  /* .charcount-body's align-items: flex-start (desktop's two-column
     row needs it so the shorter side column doesn't stretch to match
     the taller textarea's height) becomes a problem once this stacks
     into a single column: flex-start also switches each stacked
     child (.charcount-main, in turn its textarea and stats bar) from
     filling the row's full width to sizing off its own intrinsic
     content width instead, which for a <textarea> is wider than a
     phone viewport — the actual cause of this page's mobile overflow.
     Stretch restores full-width children for the stacked layout;
     .charcount-side already gets its own explicit width: 100% below,
     independent of this. */
  .charcount-body { flex-direction: column; align-items: stretch; }
  .charcount-side { flex-basis: auto; width: 100%; }
}

@media (max-width: 860px) {
  .compare-checker { grid-template-columns: 1fr; grid-auto-rows: minmax(320px, auto); overflow-y: auto; }
  .compare-checker__panel:first-child { border-right: none; border-bottom: 1px solid var(--border); }
}

@media (max-width: 1024px) {
  .topbar-content-toggle { display: inline-flex; }

  .sidebar {
    position: fixed;
    top: 0;
    left: 0;
    bottom: 0;
    width: min(320px, 84vw);
    max-height: none;
    background: var(--surface);
    z-index: 80;
    padding: 56px 20px 0;
    transform: translateX(-100%);
    transition: transform 0.22s ease;
    box-shadow: 2px 0 18px rgba(15, 16, 19, 0.15);
  }
  /* Unlike the tablet case above (where the sidebar collapses into
     normal page flow and the whole page scrolls), this drawer has a
     fixed height of its own and genuinely needs its lesson list to
     scroll internally — restoring what the broader ≤1024px rule
     turned off. */
  .sidebar__scroll { overflow-y: auto; padding-bottom: 50px; }
  .sidebar.is-open { transform: translateX(0); }
  .sidebar__close { display: block; }

  body.topbar-nav-open { overflow: hidden; }
}

@media (max-width: 640px) {
  .quiz-levels { grid-template-columns: 1fr; }
}

@media (max-width: 640px) { .quiz-levels--stage { grid-template-columns: repeat(2, 1fr); } }

@media (prefers-reduced-motion: reduce) {
  .quiz-lvl__loading-bar, .quiz-lvl__loading-line { animation: none; background-position: 50% 0; }
}