/* ══════════════════════════════════════════════════════════════════════════
   bwb-fit.css — universal screen-fit layer for BitWithBite
   ──────────────────────────────────────────────────────────────────────────
   Loaded on every page, alongside whatever CSS that page already has.

   Why this file exists, and why it looks different from bwb-responsive.css:
   bwb-responsive.css targets the home page's own class names (.wrap, .bento,
   .tgrid, .ao1 …). Those classes do not exist on course lessons, cheatsheets,
   games, admin screens or the Memories pages, so hundreds of pages got nothing
   from it. Everything here is CLASS-AGNOSTIC: it keys off element semantics and
   real measured overflow, so it works on a page it has never seen.

   Two rules this file never breaks:
     1. Reflow content to fit. Never hide it to make a layout "work".
     2. Only change what is actually too wide — pages that already fit are
        left alone (bwb-fit.js measures before it touches anything).
   ══════════════════════════════════════════════════════════════════════════ */

/* ── 1. Box model ──────────────────────────────────────────────────────────
   Padding and borders must count inside an element's width, or a 100%-wide box
   with padding becomes wider than its parent and pushes the page sideways. */
*, *::before, *::after { box-sizing: border-box; }

/* ── 2. Replaced elements never exceed their container ──────────────────── */
img, video, canvas, svg, iframe, embed, object {
  max-width: 100%;
}
img, video, canvas { height: auto; }
/* SVG icons with explicit width/height attributes must keep them */
svg[width][height] { max-width: 100%; height: auto; }

/* ── 3. Long unbreakable strings ───────────────────────────────────────────
   A pasted URL, an API key, a long hash or a German compound noun cannot wrap
   at a space, so it forces the page wider than the phone. `anywhere` lets the
   browser break it as a last resort, and unlike `word-break: break-all` it does
   not chop ordinary words mid-letter while there is still a sane break point. */
@media (max-width: 1024px) {
  p, li, dd, dt, td, th, blockquote, figcaption, label, summary,
  h1, h2, h3, h4, h5, h6, address, cite, q {
    overflow-wrap: anywhere;
  }
  /* Code keeps its own formatting — it scrolls instead (see .bwb-scroll-x). */
  pre, pre *, code, kbd, samp, var { overflow-wrap: normal; }
}

/* ── 4. Horizontal scroll container ────────────────────────────────────────
   bwb-fit.js wraps anything that genuinely cannot narrow — wide tables, code
   blocks, diagrams — in one of these. The element keeps its full width and
   scrolls inside its own box, so nothing is clipped and nothing is lost. */
.bwb-scroll-x {
  max-width: 100%;
  overflow-x: auto;
  overflow-y: hidden;
  -webkit-overflow-scrolling: touch;
  overscroll-behavior-x: contain;
}
.bwb-scroll-x > table,
.bwb-scroll-x > pre { margin-top: 0; margin-bottom: 0; }
/* A table inside a scroller should size to its content, not be squashed. */
.bwb-scroll-x > table { min-width: max-content; }

/* Keep the scrollbar visible but discreet on desktop; phones overlay it. */
.bwb-scroll-x::-webkit-scrollbar { height: 6px; }
.bwb-scroll-x::-webkit-scrollbar-thumb {
  background: rgba(127, 127, 127, .45);
  border-radius: 3px;
}

/* ── 5. Classes bwb-fit.js applies to the specific elements that overflow ──
   Each is the least invasive change that can make that element fit. */

/* A hard pixel width (or min-width) wider than the screen. */
.bwb-fit-w {
  width: auto !important;
  max-width: 100% !important;
  min-width: 0 !important;
}

/* Flex and grid children default to min-width:auto, which refuses to shrink
   below their content. This is the single most common cause of a layout being
   a few hundred pixels too wide on a phone. */
.bwb-fit-shrink,
.bwb-fit-shrink > * { min-width: 0 !important; }

/* A fixed multi-column grid that no longer fits. */
.bwb-fit-col1 { grid-template-columns: minmax(0, 1fr) !important; }
.bwb-fit-col2 { grid-template-columns: repeat(2, minmax(0, 1fr)) !important; }
.bwb-fit-col3 { grid-template-columns: repeat(3, minmax(0, 1fr)) !important; }

/* A single-line flex row that has run out of room. */
.bwb-fit-flexwrap { flex-wrap: wrap !important; }

/* …except a bar that cannot grow taller. Wrapping a sticky header does fix the
   horizontal overflow, but the extra rows spill out of the bar's fixed-height
   background and land on top of the page content — measurably "fitting" and
   visibly broken. Such rows keep one line and scroll sideways instead, so every
   item stays reachable and nothing overlaps. */
.bwb-fit-scrollrow {
  flex-wrap: nowrap !important;
  overflow-x: auto !important;
  overflow-y: hidden !important;
  -webkit-overflow-scrolling: touch;
  overscroll-behavior-x: contain;
  scrollbar-width: none;            /* the bar is swiped, not scrolled by mouse */
}
.bwb-fit-scrollrow::-webkit-scrollbar { display: none; }
/* Items in a scrolling bar must not be squeezed to nothing. */
.bwb-fit-scrollrow > * { flex-shrink: 0; }

/* Text held on one line by white-space:nowrap where there is no room for it. */
.bwb-fit-nowrap { white-space: normal !important; }

/* ── 6. Last-resort clip, applied by JS only if something still overflows ──
   `clip` rather than `hidden` on purpose: `overflow-x: hidden` turns the element
   into a scroll container, which silently breaks every `position: sticky` header
   on the site. `clip` does not, so sticky navs keep working. */
html.bwb-fit-clip, html.bwb-fit-clip > body { overflow-x: clip; }
@supports not (overflow-x: clip) {
  html.bwb-fit-clip, html.bwb-fit-clip > body { overflow-x: hidden; }
}

/* ── 7. Touch ergonomics ───────────────────────────────────────────────────*/
@media (pointer: coarse) {
  /* Buttons and standalone controls need a reliable finger target. Inline text
     links are deliberately excluded — growing them would wreck line spacing. */
  button, .btn, [role="button"], input[type="submit"],
  input[type="button"], input[type="reset"], select {
    min-height: 40px;
  }
  /* iOS zooms the whole page when a focused field has text under 16px, which
     leaves the layout mid-zoom and looking broken. Never go below 16px. */
  input:not([type="checkbox"]):not([type="radio"]):not([type="range"]),
  select, textarea {
    font-size: max(16px, 1em);
  }
}

/* ── 8. Notch and rounded-corner safe areas ────────────────────────────────
   Bars pinned to the top or bottom edge get JS-applied padding; this covers the
   left/right insets in landscape, where a notch can eat a fixed bar's content.
   env() is 0 on every device without insets, so this is a no-op elsewhere. */
.bwb-fit-safe-x {
  padding-left: max(var(--bwb-pad-l, 0px), env(safe-area-inset-left, 0px)) !important;
  padding-right: max(var(--bwb-pad-r, 0px), env(safe-area-inset-right, 0px)) !important;
}

/* ── 9. Tiny-screen typography floor ───────────────────────────────────────
   Nothing below 11px on a phone — it is unreadable, and the page counts as
   "not screen friendly" even when it technically fits. */
@media (max-width: 480px) {
  body { text-size-adjust: 100%; -webkit-text-size-adjust: 100%; }
}

/* ── 10. Print ─────────────────────────────────────────────────────────────
   Worksheets and cheatsheets get printed; make sure scrollers show everything
   on paper instead of cutting at the scroll edge. */
@media print {
  .bwb-scroll-x { overflow: visible !important; }
  .bwb-scroll-x > table { min-width: 0 !important; }
}
