/*
 * CertaRounds — layout primitives and the responsive app shell.
 *
 *   < 768      .shell__topbar + .shell__tabbar (bottom), single column
 *   768–1023   .shell__rail (72px icons) + .shell__topbar, content max 720 centred
 *   ≥ 1024     .shell__sidebar (--sidebar-w 224px) + desktop top bar across the content, .page grid
 *   ≥ 1200     .page__aside becomes a sticky right rail
 *   ≥ 1280     .reader__panel (question explanation) moves beside the reading column
 *
 * Markup contract (the app shell, M2):
 *   <div class="shell">
 *     <a class="skip-link" href="#main">Skip to content</a>
 *     <header class="shell__topbar">…TopBar()…</header>
 *     <nav class="shell__rail">…NavRail()…</nav>
 *     <aside class="shell__sidebar">…Sidebar()…</aside>
 *     <main id="main" class="shell__main" tabindex="-1"> <div class="page">…</div> </main>
 *     <nav class="shell__tabbar">…TabBar()…</nav>
 *   </div>
 *   .shell[data-mode="focus"] hides all navigation (question / mock exam screens).
 */

/* ============ Shell ============ */
.shell {
  position: relative;
  min-height: 100vh;
  min-height: 100dvh;
  background: var(--bg);
}

.shell__topbar {
  position: sticky;
  top: 0;
  z-index: var(--z-sticky);
  height: calc(var(--topbar-h) + var(--safe-top));
  padding-top: var(--safe-top);
  padding-left: max(var(--sp-2), var(--safe-left));
  padding-right: max(var(--sp-2), var(--safe-right));
  background: var(--surface);
  transition: box-shadow var(--dur-2) var(--ease-out);
}
.shell__topbar.is-scrolled { box-shadow: 0 1px 0 var(--hairline); }

.shell__main {
  display: block;
  min-width: 0;
  padding-bottom: calc(var(--tabbar-h) + var(--safe-bottom) + var(--sp-6));
}
.shell__main:focus { outline: none; }

.shell__tabbar {
  position: fixed;
  left: 0; right: 0; bottom: 0;
  z-index: var(--z-nav);
  padding-bottom: var(--safe-bottom);
  padding-left: var(--safe-left);
  padding-right: var(--safe-right);
  background: var(--surface);
  box-shadow: var(--shadow-bar);
}

.shell__rail, .shell__sidebar { display: none; }

/* Focus mode — immersive screens (Question, Mock exam) */
.shell[data-mode="focus"] .shell__tabbar,
.shell[data-mode="focus"] .shell__rail { display: none; }
/* F2: focus mode reserves nothing of its own. Pages bring their own bottom space (.page, the auth frame with
   its safe area), and on phones the fixed action bar's measured height is reserved only while one exists
   (html.has-action-bar, below). The old 24px + safe-area here added a phantom scroll to one-screen pages. */
.shell[data-mode="focus"] .shell__main { padding-bottom: 0; }

/* Bottom action bar for focus screens on phones ("Teach Me · Next").
   R0 #4: inside .page the strip bleeds to the screen edges (negative margins) while its CONTENT box
   stays on the page column, so button edges line up with the options above (x = 16 → 374 at 390).
   DS17: a solid strip with a soft top edge, so content scrolling beneath reads as "under" it rather
   than cropped; html gets scroll-padding so keyboard focus is never hidden behind it (WCAG 2.4.11). */
.action-bar {
  --action-bar-h: 72px;
  position: sticky;
  bottom: 0;
  z-index: var(--z-sticky);
  display: flex;
  gap: var(--sp-3);
  padding: var(--sp-3) var(--gutter) calc(var(--sp-3) + var(--safe-bottom));
  background: var(--bg);
  box-shadow: 0 -1px 0 var(--border), 0 -12px 20px -16px rgba(16, 27, 77, .22);
}
.page .action-bar { margin-left: calc(-1 * var(--gutter)); margin-right: calc(-1 * var(--gutter)); }
.action-bar > * { flex: 1 1 0; }
html:has(.action-bar) { scroll-padding-bottom: calc(var(--action-bar-h, 72px) + var(--safe-bottom) + 16px); }
/* Q-F1: on phones the bar is fixed to the bottom and the page reserves its MEASURED height
   (components.js writes --action-bar-h on <html> and adds .has-action-bar), so the last content always
   scrolls fully clear. The top shadow appears only while content is actually underneath (.is-covering),
   so at the end of the page it no longer reads as "scroll for more". Mock, HQ, onboarding get it too. */
@media (max-width: 767px) {
  .action-bar { position: fixed; left: 0; right: 0; bottom: 0; margin-left: 0 !important; margin-right: 0 !important; box-shadow: 0 -1px 0 var(--border); }
  .action-bar.is-covering { box-shadow: 0 -1px 0 var(--border), 0 -12px 20px -16px rgba(16, 27, 77, .22); }
  .shell:not([data-mode="focus"]) .action-bar { bottom: calc(var(--tabbar-h) + var(--safe-bottom)); padding-bottom: var(--sp-3); }
  /* the [data-mode="focus"] selector matches the specificity of the focus-mode rule (line 66) so the
     reserve wins in every layout mode (Mock exam, Question session, any layout:'focus' screen) */
  html.has-action-bar .shell__main,
  html.has-action-bar .shell[data-mode="focus"] .shell__main { padding-bottom: calc(var(--action-bar-h, 72px) + var(--sp-4)); }
  html.has-action-bar .shell:not([data-mode="focus"]) .shell__main { padding-bottom: calc(var(--action-bar-h, 72px) + var(--tabbar-h) + var(--safe-bottom) + var(--sp-4)); }
  html.has-action-bar:not(:has(.shell__main)) body { padding-bottom: calc(var(--action-bar-h, 72px) + var(--sp-4)); }
}

@media (min-width: 768px) {
  .shell { padding-left: var(--rail-w); }
  .shell__tabbar { display: none; }
  .shell__rail {
    display: flex;
    position: fixed;
    top: 0; bottom: 0; left: 0;
    width: var(--rail-w);
    z-index: var(--z-nav);
    background: var(--surface);
    border-right: 1px solid var(--border);
  }
  .shell__main { padding-bottom: var(--sp-9); }
  .shell[data-mode="focus"] { padding-left: 0; }
  .action-bar { position: static; background: none; box-shadow: none; padding: var(--sp-5) 0 0; }
  .page .action-bar:not(.bleed) { margin-left: 0; margin-right: 0; }
  .action-bar > * { flex: 0 1 auto; }
  html:has(.action-bar) { scroll-padding-bottom: 0; }
  /* In the ≥1280 explanation panel the bar spans the panel: two equal buttons, 12px apart. */
  .reader__panel .action-bar > .btn { flex: 1 1 0; }
}
/* F2 (R2 Mock P1, 1024×768): on tablets and laptops a focus-mode screen (Mock exam, Question session, any
   layout:'focus' screen) keeps its action bar in reach, as a sticky strip at the bottom of the reading
   column, like phones. The soft top shadow shows only while content is underneath (.is-covering, measured by
   components.js). Zero-specificity :where() so a screen's own bar styling (.session-actions,
   .mock-actions) still wins; the ≥1280 explanation-panel bar is left alone. */
@media (min-width: 768px) and (max-width: 1279px) {
  :where(.shell[data-mode="focus"]) .action-bar:where(:not(.reader__panel .action-bar)) {
    position: sticky;
    bottom: 0;
    z-index: var(--z-sticky);
    padding: var(--sp-3) 0 calc(var(--sp-3) + var(--safe-bottom));
    background: var(--bg);
    box-shadow: 0 -1px 0 var(--border);
  }
  :where(.shell[data-mode="focus"]) .action-bar:where(.is-covering):where(:not(.reader__panel .action-bar)) {
    box-shadow: 0 -1px 0 var(--border), 0 -12px 20px -16px rgba(16, 27, 77, .22);
  }
  html:has(.shell[data-mode="focus"] .action-bar) { scroll-padding-bottom: calc(var(--action-bar-h, 72px) + 16px); }
}

@media (min-width: 1024px) {
  .shell { padding-left: var(--sidebar-w); }
  .shell__rail { display: none; }
  /* v2 (BUILD_BRIEF §13.4): the top bar stays across the content on desktop (search · bell · user chip). */
  .shell__sidebar {
    display: flex;
    position: fixed;
    top: 0; bottom: 0; left: 0;
    width: var(--sidebar-w);
    z-index: var(--z-nav);
    background: var(--surface);
    border-right: 1px solid var(--border);
  }
  .shell[data-mode="focus"] { padding-left: 0; }
  .shell[data-mode="focus"] .shell__sidebar { display: none; }
  .shell[data-mode="focus"] .shell__topbar { display: block; }
}

/* ============ Page containers ============ */
.page {
  width: 100%;
  max-width: var(--page-max);
  margin: 0 auto;
  padding: var(--sp-2) var(--gutter) var(--sp-6);
}
.page--narrow { max-width: calc(var(--content-max) + 2 * var(--gutter)); }
.page--reading { max-width: calc(var(--reading-max) + 2 * var(--gutter)); }

@media (min-width: 768px) {
  .page { max-width: calc(var(--content-max) + 2 * var(--gutter)); padding-top: var(--sp-5); }
}
@media (min-width: 1024px) {
  .page { max-width: calc(var(--page-max) + 2 * var(--gutter)); padding-top: var(--sp-7); padding-bottom: var(--sp-9); }
  .page--narrow { max-width: calc(var(--content-max) + 2 * var(--gutter)); }
  .page--reading { max-width: calc(var(--reading-max) + 2 * var(--gutter)); }
}

/* Page header (desktop screen titles; phones use the top bar) */
.page-header {
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  gap: var(--sp-4);
  margin-bottom: var(--sp-5);
}
.page-header__title { font-size: var(--fs-24); }
.page-header__sub { margin-top: var(--sp-1); color: var(--text-2); font-size: var(--fs-15); }
@media (min-width: 1024px) {
  .page-header { margin-bottom: var(--sp-6); }
  .page-header__title { font-size: var(--fs-30); }
}

/* Main + right rail. Rail stacks below main until 1200px. */
.page__grid {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: var(--sp-4);
  align-items: start;
}
.page__main, .page__aside { display: flex; flex-direction: column; gap: var(--sp-4); min-width: 0; }
@media (min-width: 768px) {
  .page__grid, .page__main, .page__aside { gap: var(--sp-5); }
}
@media (min-width: 1200px) {
  .page__grid { grid-template-columns: minmax(0, 1fr) clamp(288px, 24vw + 16px, var(--aside-w)); gap: var(--sp-6); }
  .page__main, .page__aside { gap: var(--sp-6); }
  .page__aside { position: sticky; top: calc(var(--shell-sticky-top, 0px) + var(--sp-5)); }
}

/* DS4 (R0): 1024–1199 has no room for a rail beside the content, so the rail's cards form a row
   ABOVE the main column instead of trailing below it (the shell mirrors this in app.css). */
@media (min-width: 1024px) and (max-width: 1199px) {
  .page__grid > .page__aside { order: -1; display: grid; grid-template-columns: repeat(auto-fit, minmax(240px, 1fr)); align-items: start; }
}

/* Reader: question stem column + explanation panel (≥1280 side by side) */
.reader {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: var(--sp-5);
  max-width: var(--reading-max);
  margin: 0 auto;
}
.reader__main { min-width: 0; }
.reader__panel { min-width: 0; }
/* DS13 + R0 #5: ONE width for the split layout. --split-w (720 + 32 + 420 = 1172) is used by
   .reader--split, .page--split, TopBar({wide}) and .topbar-progress--wide, so the back button,
   the progress bar, the stem and the panel share the same left and right edges. */
:root { --split-w: calc(var(--reading-max) + 420px + var(--sp-7)); --focus-head: 0px; }
@media (min-width: 1024px) { .shell[data-mode="focus"] { --focus-head: 72px; } }  /* sticky focus header (bar + progress) */
/* F3: opt-in early split from 1100 (iPad landscape 1180 and small laptops). Add `.reader--split-1100` next to
   `.reader--split`: over 1100–1279 the reader becomes a fluid column + a 360px sticky panel, and --split-w
   becomes that band's width, so TopBar({wide}) and .topbar-progress--wide (components.css) line up with it
   automatically while such a reader is on the page. ≥1280 is the standard split below. */
@media (min-width: 1100px) and (max-width: 1279px) {
  :root:has(.reader--split-1100) { --split-w: min(var(--page-max), calc(100vw - 2 * var(--gutter))); }
  .reader--split.reader--split-1100 {
    max-width: var(--split-w);
    grid-template-columns: minmax(0, 1fr) 360px;
    gap: var(--sp-6);
  }
  .reader--split.reader--split-1100 .reader__panel {
    position: sticky;
    top: calc(var(--focus-head) + var(--sp-5));
    max-height: calc(100vh - var(--focus-head) - var(--sp-5) * 2);
    max-height: calc(100dvh - var(--focus-head) - var(--sp-5) * 2);
    overflow: auto;
  }
}
@media (min-width: 1280px) {
  .page--split, .page:has(> .reader--split) { max-width: calc(var(--split-w) + 2 * var(--gutter)); }
  .reader--split {
    max-width: var(--split-w);
    grid-template-columns: minmax(0, var(--reading-max)) 420px;
    gap: var(--sp-7);
  }
  .reader--split .reader__panel {
    position: sticky;
    top: calc(var(--focus-head) + var(--sp-5));
    max-height: calc(100vh - var(--focus-head) - var(--sp-5) * 2);
    max-height: calc(100dvh - var(--focus-head) - var(--sp-5) * 2);
    overflow: auto;
  }
}

/* ============ Primitives ============ */
.stack { display: flex; flex-direction: column; gap: var(--stack, var(--sp-4)); min-width: 0; }
.stack-1 { --stack: var(--sp-1); } .stack-2 { --stack: var(--sp-2); } .stack-3 { --stack: var(--sp-3); }
.stack-4 { --stack: var(--sp-4); } .stack-5 { --stack: var(--sp-5); } .stack-6 { --stack: var(--sp-6); }
.stack-7 { --stack: var(--sp-7); } .stack-8 { --stack: var(--sp-8); }

.cluster { display: flex; flex-wrap: wrap; align-items: center; gap: var(--cluster, var(--sp-2)); min-width: 0; }
.cluster-1 { --cluster: var(--sp-1); } .cluster-3 { --cluster: var(--sp-3); } .cluster-4 { --cluster: var(--sp-4); }
.cluster--nowrap { flex-wrap: nowrap; }

.row { display: flex; align-items: center; gap: var(--row, var(--sp-3)); min-width: 0; }
.split { display: flex; align-items: center; justify-content: space-between; gap: var(--sp-3); min-width: 0; }
.grow { flex: 1 1 auto; min-width: 0; }
.shrink-0 { flex-shrink: 0; }
.center { display: grid; place-items: center; }

.grid { display: grid; gap: var(--grid-gap, var(--sp-4)); grid-template-columns: repeat(auto-fill, minmax(min(100%, var(--grid-min, 240px)), 1fr)); }
.grid-2 { display: grid; gap: var(--grid-gap, var(--sp-3)); grid-template-columns: repeat(2, minmax(0, 1fr)); }
.grid-3 { display: grid; gap: var(--grid-gap, var(--sp-3)); grid-template-columns: repeat(3, minmax(0, 1fr)); }
.grid-4 { display: grid; gap: var(--grid-gap, var(--sp-3)); grid-template-columns: repeat(4, minmax(0, 1fr)); }
@media (max-width: 479px) {
  .grid-4--collapse { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .grid-3--collapse { grid-template-columns: minmax(0, 1fr); }
}

/* Readable column (~68ch) for stems and long prose */
.readable { max-width: var(--measure); }
.measure { max-width: var(--reading-max); }

/* Full-bleed horizontal strip that lines up with page gutters */
.bleed {
  margin-left: calc(-1 * var(--gutter));
  margin-right: calc(-1 * var(--gutter));
  padding-left: var(--gutter);
  padding-right: var(--gutter);
  scroll-padding-left: var(--gutter);
}

/* Section spacing on a page */
.section { display: flex; flex-direction: column; gap: var(--sp-3); }
.section + .section { margin-top: var(--sp-2); }

/* Visibility by breakpoint */
@media (max-width: 767px) { .hide-phone { display: none !important; } }
@media (min-width: 768px) { .show-phone { display: none !important; } }
@media (min-width: 768px) and (max-width: 1023px) { .hide-tablet { display: none !important; } }
@media (max-width: 1023px) { .show-desktop { display: none !important; } }
@media (min-width: 1024px) { .hide-desktop { display: none !important; } }
@media (hover: none) { .hide-touch { display: none !important; } }
