/* ============================================================================
   PALARID LAYOUT — one container, zero horizontal overflow
   ----------------------------------------------------------------------------
   Loaded LAST, after every other stylesheet, so it wins without any file
   having to be rewritten. Same cascade-last approach as palarid-ui.css (D-001).

   The problem this solves
   -----------------------
   Palarid had three competing content widths: 1500px in the original inline
   block, 1200px in palarid-ui.css, and 100% in the mobile layer. On top of
   that, several categories of element could push wider than their container
   and produce a horizontal scrollbar — which on a phone means the whole page
   drifts sideways when you scroll, and on desktop means a stray bar along the
   bottom of a page that has nothing to scroll to.

   ONE NUMBER TO CHANGE
   --------------------
   `--maxw-app` below is the content cap. Everything else derives from it.
   ============================================================================ */

:root {
  /* Content cap. 1280px is the standard wide-content width: at 1440 and 1536
     laptop widths it leaves a comfortable margin rather than running edge to
     edge, and on a 1920 monitor it stops lines becoming unreadably long.
     The previous 1500px was wider than most laptop viewports, so it never
     actually applied — the layout was gutter-bound, not cap-bound. */
  --maxw-app: 1280px;

  /* Fluid gutters. Scale smoothly with the viewport instead of stepping at
     breakpoints, which is what caused content to jump width mid-resize.
     16px on a small phone → 32px from about 1100px up. */
  --gutter: clamp(16px, 3vw, 32px);

  /* Reading measure for prose panes (legal, about, changelog). */
  --maxw-prose: 68ch;
}

/* ---------------------------------------------------------------- 1. CONTAINER
   Every top-level content region uses the same cap and the same gutters, so
   the left edge of the nav, the topbar and the page body all line up. That
   alignment is most of what makes a layout feel deliberate. */
.main,
.topbar-inner,
.tabs-inner,
.footer-inner {
  max-width: var(--maxw-app) !important;
  margin-left: auto !important;
  margin-right: auto !important;
  padding-left: var(--gutter) !important;
  padding-right: var(--gutter) !important;
  width: 100%;
}

.main {
  padding-top: var(--s-6, 24px) !important;
  padding-bottom: var(--s-16, 64px) !important;
}
@media (max-width: 600px) {
  .main { padding-top: var(--s-4, 16px) !important; }
}

/* Bottom nav on mobile sits over the last ~72px of the page. */
@media (max-width: 680px) {
  .main { padding-bottom: 96px !important; }
}

.panel-pane[data-pane="privacy"]   .main-inner,
.panel-pane[data-pane="terms"]     .main-inner,
.panel-pane[data-pane="cookies"]   .main-inner,
.panel-pane[data-pane="gdpr"]      .main-inner,
.panel-pane[data-pane="about"]     .main-inner,
.panel-pane[data-pane="changelog"] .main-inner { max-width: var(--maxw-prose); }

/* ------------------------------------------------------- 2. OVERFLOW CONTAINMENT
   `overflow-x: clip` rather than `hidden`. `hidden` silently turns the element
   into a scroll container, which breaks every `position: sticky` descendant —
   that would kill the sticky tab bar. `clip` does not. The `hidden` line is a
   fallback for browsers without `clip`, where the sticky bar degrades to
   static rather than the page scrolling sideways. */
html, body {
  overflow-x: hidden;
  overflow-x: clip;
  max-width: 100%;
}

/* The single most common cause of overflow in flex and grid layouts.
   A flex/grid item defaults to `min-width: auto`, meaning it refuses to shrink
   below its content's intrinsic width. One long word, one wide table, one
   unbreakable URL, and the item pushes the whole row wider than the screen.
   Setting `min-width: 0` lets it shrink and wrap instead. */
.grid > *,
.row > *,
.flex > *,
.card > *,
.panel-pane > * { min-width: 0; }

/* Auto-fill grids written as minmax(280px, 1fr) create a 280px track even when
   only 250px is available — the classic mobile overflow. `min(Xpx, 100%)` caps
   the floor at the container width, so the track collapses gracefully instead.
   Declared for the shared grid utilities; inline grid styles are handled by the
   `min-width: 0` rule above plus the wrapping rules below. */
.tile-grid  { grid-template-columns: repeat(auto-fill, minmax(min(120px, 100%), 1fr)); }
.thumb-grid { grid-template-columns: repeat(auto-fill, minmax(min(160px, 100%), 1fr)); }

/* --------------------------------------------------------- 3. WIDE CONTENT
   Media and embeds must never exceed their box. Canvases in particular are
   sized with width/height *attributes* in the games and visualisers, which CSS
   has to override or a 900px game board breaks a 390px phone. */
img, svg, video, canvas, iframe, embed, object, table, pre, textarea {
  max-width: 100%;
}
img, video { height: auto; }
canvas { height: auto; }

/* Unbreakable strings — base64 output, JSON blobs, hashes, JWTs, long URLs.
   These live all over the developer tools and are a guaranteed overflow
   without a wrap rule. `anywhere` (not `break-word`) also lets the browser
   shrink the box, which `break-word` alone does not. */
pre, code, samp, kbd,
td, th,
.mono, .out, .output, .result {
  overflow-wrap: anywhere;
  word-break: break-word;
}
pre { white-space: pre-wrap; }

/* Tables: let them scroll inside their own box rather than widening the page.
   Kept as `table` display so the accessibility tree is preserved — only the
   horizontal scroll behaviour changes. */
.table-scroll { overflow-x: auto; -webkit-overflow-scrolling: touch; }
table { width: 100%; }

/* Inputs commonly carry a `size` attribute or a fixed inline width. */
input, select, textarea, button { max-width: 100%; }

/* ------------------------------------------------------------- 4. VIEWPORT UNITS
   `100vw` is the viewport width INCLUDING the scrollbar, so `width: 100vw` on
   a desktop page with a vertical scrollbar is roughly 15px wider than the
   space available — a horizontal scrollbar appears to show 15px of nothing.
   `100%` is the correct value in every place Palarid used `100vw`. */
#cp-drawer { max-width: 100%; }
@media (max-width: 680px) {
  #cp-drawer { width: 100%; right: -100%; }
  #cp-drawer.open { right: 0; }
}

/* ------------------------------------------------------------- 5. SAFE AREAS
   Notched phones and devices with a home indicator. Without this the bottom
   nav sits under the indicator and the left gutter disappears in landscape. */
@supports (padding: max(0px)) {
  .main, .topbar-inner, .tabs-inner, .footer-inner {
    padding-left:  max(var(--gutter), env(safe-area-inset-left))  !important;
    padding-right: max(var(--gutter), env(safe-area-inset-right)) !important;
  }
  .os-bottom-nav { padding-bottom: env(safe-area-inset-bottom); }
}

/* --------------------------------------------------------- 6. HORIZONTAL SCROLLERS
   The tab bar is *meant* to scroll sideways — it already did, this just makes
   the behaviour explicit alongside the new container so the two stay in step.
   `overscroll-behavior-x: contain` stops a sideways flick on the tab strip
   from triggering the browser's back-navigation gesture, which on iOS was
   easy to do by accident. */
.tabs-inner {
  overflow-x: auto;
  overflow-y: hidden;
  scrollbar-width: none;
  -webkit-overflow-scrolling: touch;
  overscroll-behavior-x: contain;
}
.tabs-inner::-webkit-scrollbar { display: none; }

/* The category bar deliberately WRAPS rather than scrolls (fixed in v3.x after
   chips were being cut off). It is left wrapping — only its horizontal padding
   is brought onto the shared gutter so its left edge lines up with the page
   heading below it. Vertical padding is untouched. */
#cat-bar {
  padding-left:  var(--gutter) !important;
  padding-right: var(--gutter) !important;
  max-width: var(--maxw-app);
  margin-left: auto;
  margin-right: auto;
}

/* ------------------------------------------------- 6b. AFFILIATE REMOVAL
   Every rel="sponsored" link on the site pointed at an account that does not
   exist — Wise, Interactive Brokers, Coinbase, eToro, Booking, Skyscanner,
   iVisa, NordVPN. They earned nothing, carried no disclosure, and several sat
   next to financial content where an unlabelled promotion is a regulatory
   problem as well as a trust one.

   Hidden here in CSS so they disappear even if scripting fails, and removed
   from the DOM by palarid-home.js so they are not in the served markup that
   crawlers read. Bring them back only when the accounts exist, the context is
   genuinely relevant, and the disclosure is visible. */
.spon,
.spon-btn,
a[rel~="sponsored"] { display: none !important; }

/* ----------------------------------------------------------------- 7. DEBUG
   Add class `debug-overflow` to <html> in devtools to outline every element
   wider than the viewport. Leave it out of normal rendering. */
html.debug-overflow * { outline: 1px solid rgba(255, 0, 0, .35); }
