/* ===========================================================================
   app.css - QRauz shared responsive foundation
   ---------------------------------------------------------------------------
   Linked by every page (before its inline <style>) and copied verbatim to
   public/ by build.js. It is intentionally LOW-RISK:

   - The --q-* design tokens are OPT-IN. Linking this file changes nothing
     until a rule actually uses var(--q-*). The 23 pages are individually
     inline-styled with no shared reset, so anything that touched bare element
     selectors globally (e.g. box-sizing) would shift tuned layouts. We avoid
     that. Pages adopt the tokens incrementally (Phase 3).
   - Only two genuinely-safe global rules ship: iOS text-size-adjust and a
     media overflow guard.
   - Utility classes (.q-*) are unused by current markup, so they're inert
     until applied.

   BOUNDED-FLUID approach (the project's chosen method): sizes scale with the
   viewport via clamp(min, base + vw, max) so they grow/shrink with the screen
   but never below a readable/tappable floor or above an oversized ceiling.
   This is the safe version of "percentage-based UI that depends on resolution".

   Colour note: CSS-variable names are inconsistent across pages (index.html
   uses --accent/--hd/--white; other pages use --primary-accent/--header-dark/
   --highlight). Any rule here that needs a colour must use a fallback chain,
   e.g. var(--primary-accent, var(--accent, #7289da)).
   =========================================================================== */

:root {
  /* Fluid type scale: clamp(min, preferred, max). Base ~1rem. */
  --q-text-xs:   clamp(0.72rem, 0.69rem + 0.15vw, 0.80rem);
  --q-text-sm:   clamp(0.82rem, 0.78rem + 0.20vw, 0.92rem);
  --q-text-base: clamp(0.95rem, 0.90rem + 0.25vw, 1.05rem);
  --q-text-md:   clamp(1.05rem, 0.98rem + 0.40vw, 1.25rem);
  --q-text-lg:   clamp(1.25rem, 1.10rem + 0.70vw, 1.60rem);
  --q-text-xl:   clamp(1.50rem, 1.25rem + 1.20vw, 2.20rem);
  --q-text-2xl:  clamp(1.90rem, 1.50rem + 2.00vw, 3.00rem);

  /* Fluid spacing scale. */
  --q-space-1: clamp(0.40rem, 0.35rem + 0.20vw, 0.60rem);
  --q-space-2: clamp(0.60rem, 0.50rem + 0.40vw, 1.00rem);
  --q-space-3: clamp(0.90rem, 0.70rem + 0.80vw, 1.60rem);
  --q-space-4: clamp(1.30rem, 1.00rem + 1.40vw, 2.40rem);
  --q-space-5: clamp(1.80rem, 1.30rem + 2.40vw, 3.50rem);

  /* Layout primitives. */
  --q-maxw:        1200px;  /* default content cap */
  --q-maxw-narrow:  640px;  /* forms / auth / article column */
  --q-radius:        12px;
  --q-gutter: clamp(1rem, 4vw, 2.5rem);  /* fluid page side padding */
}

/* ---- Safe global rules (the only non-opt-in part) ---------------------- */

/* Stop iOS Safari from auto-inflating text in landscape / after orientation. */
html { -webkit-text-size-adjust: 100%; text-size-adjust: 100%; }

/* Media never forces horizontal scroll on a narrow screen. Only constrains
   when an element would otherwise overflow its container, so fixed-size
   avatars/icons in wider containers are unaffected. */
img, video { max-width: 100%; }

/* Form controls that are width:100% should include their padding in that
   width. Without this, on the pages that have no global box-sizing reset, a
   width:100% input overflows its card by the padding amount (a common cause
   of inputs spilling past the card edge on mobile). Scoped to form controls
   only - it can't shift container/box layouts tuned for content-box. */
input, textarea, select { box-sizing: border-box; }

/* Footer link rows wrap as whole items: a multi-word link like "Terms of
   Service" must never split across two lines on a narrow screen (the messy
   wrap seen on ~430px phones). The row still wraps between items. */
footer a { white-space: nowrap; }

/* ---- Brand lockup outline (header) -------------------------------------- */

/* The emblem + QRAUZ wordmark sit in a subtle accent-tinted pill so the
   top-left corner reads as a deliberate badge rather than floating text.
   Lives here (one shared place) instead of in 23 inline <style> blocks.
   The negative block margin cancels the padding growth so the header height
   (and everything tuned to it, e.g. index's sticky sidebar top) is unchanged. */
header .logo {
  border: 1px solid rgba(114, 137, 218, 0.45);
  background: rgba(114, 137, 218, 0.08);
  border-radius: 16px;
  padding: 0.4rem 1rem 0.4rem 0.55rem;
  margin: -0.45rem 0;
  transition: border-color 0.18s, background 0.18s;
}
header .logo:hover {
  border-color: var(--primary-accent, var(--accent, #7289da));
  background: rgba(114, 137, 218, 0.14);
}

/* ---- Opt-in utilities (apply a class to use; inert otherwise) ----------- */

/* Centred content column with fluid side gutters + a max width. */
.q-container { width: 100%; max-width: var(--q-maxw); margin-inline: auto; padding-inline: var(--q-gutter); }
.q-container.q-narrow { max-width: var(--q-maxw-narrow); }

/* Fluid headings / body text. */
.q-h1   { font-size: var(--q-text-2xl); line-height: 1.15; }
.q-h2   { font-size: var(--q-text-xl);  line-height: 1.20; }
.q-h3   { font-size: var(--q-text-lg);  line-height: 1.25; }
.q-text { font-size: var(--q-text-base); }

/* Responsive auto-fit grid: columns collapse to one on small screens with NO
   media query. Tune the wrap point per use with --q-card-min. */
.q-grid {
  display: grid;
  gap: var(--q-space-3);
  grid-template-columns: repeat(auto-fill, minmax(min(var(--q-card-min, 280px), 100%), 1fr));
}

/* Stack on small screens: a flex row that wraps to a column under the given
   width (default 640px). Use .q-stack and set --q-stack-at to override. */
.q-stack { display: flex; flex-wrap: wrap; gap: var(--q-space-2); }
@media (max-width: 640px) {
  .q-stack.q-stack-tight { flex-direction: column; align-items: stretch; }
}

/* Hide/show by viewport - handy for swapping a desktop control for a mobile
   one without per-page media queries. */
@media (max-width: 768px) { .q-desktop-only { display: none !important; } }
@media (min-width: 769px) { .q-mobile-only  { display: none !important; } }
