/* StudyPass — Base layer
   Reset, element defaults, layout primitives.
   Depends on tokens.css. Load order: fonts → tokens → base → components → shell.
*/

/* ==============================================================
   1. RESET
   ============================================================== */
*,
*::before,
*::after { box-sizing: border-box; }

* { margin: 0; }

/* The browser hides [hidden] with display:none, but that comes from the
   user-agent sheet, so ANY class of ours that sets display beats it and the
   element stays on screen — empty, but there. .badge and .locked-note both
   did exactly that. Stating it once here means no component has to remember. */
[hidden] { display: none !important; }

html {
  -webkit-text-size-adjust: 100%;
  scroll-behavior: smooth;
}
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
}

body {
  min-height: 100svh;
  background: var(--bg-canvas);
  color: var(--fg-default);
  font-family: var(--font-body);
  font-size: var(--text-md);
  line-height: var(--leading-body);
  font-weight: var(--weight-regular);
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-rendering: optimizeLegibility;
  font-variant-numeric: tabular-nums;
}

img, svg, video, canvas, picture {
  display: block;
  max-width: 100%;
  height: auto;
}

input, button, textarea, select {
  font: inherit;
  color: inherit;
  letter-spacing: inherit;
}

button { background: none; border: 0; padding: 0; cursor: pointer; }

p, li, figcaption { text-wrap: pretty; }
h1, h2, h3, h4, h5, h6 { text-wrap: balance; }

/* ==============================================================
   2. ELEMENT DEFAULTS
   ============================================================== */
h1, h2, h3, h4, h5, h6 {
  font-family: var(--font-display);
  font-weight: var(--weight-semibold);
  color: var(--fg-strong);
  line-height: var(--leading-snug);
  letter-spacing: var(--tracking-tight);
}

h1 { font-size: var(--text-h1); }
h2 { font-size: var(--text-h2); }
h3 { font-size: var(--text-h3); }
h4 { font-size: var(--text-h4); }
h5, h6 { font-size: var(--text-sm); letter-spacing: var(--tracking-normal); }

p { max-width: var(--measure-body); }

a {
  color: var(--fg-brand);
  text-decoration: none;
  text-underline-offset: 0.2em;
  text-decoration-thickness: 1px;
  transition: color var(--duration-base) var(--ease-default);
}
a:hover { text-decoration: underline; }

strong, b { font-weight: var(--weight-semibold); color: var(--fg-strong); }
small { font-size: var(--text-sm); }

ul, ol { padding-left: 1.25em; }
li + li { margin-top: var(--space-2); }
ul.u-plain, ol.u-plain { list-style: none; padding-left: 0; }
ul.u-plain > li + li, ol.u-plain > li + li { margin-top: 0; }

hr {
  border: 0;
  border-top: var(--border-hair) solid var(--edge-hair);
  margin: var(--space-7) 0;
}

blockquote {
  border-left: var(--border-heavy) solid var(--edge-brand);
  padding-left: var(--space-5);
  color: var(--fg-strong);
  font-size: var(--text-lg);
  line-height: var(--leading-heading);
}

code, kbd, samp, pre {
  font-family: var(--font-mono);
  font-size: 0.9em;
}
code { background: var(--bg-subtle); padding: 0.15em 0.35em; }

table { border-collapse: collapse; width: 100%; }

::selection { background: var(--brand-sky); color: var(--brand-navy); }
[data-theme='dark'] ::selection { background: var(--brand-blue); color: #fff; }

/* Focus — one ring everywhere, never removed */
:focus-visible {
  outline: var(--focus-ring-width) solid var(--focus-ring);
  outline-offset: var(--focus-ring-offset);
}
:focus:not(:focus-visible) { outline: none; }

/* ==============================================================
   3. TYPE CLASSES
   ============================================================== */
.t-display-1,
.t-display-2,
.t-display-3 {
  font-family: var(--font-display);
  font-weight: var(--weight-semibold);
  color: var(--fg-strong);
  line-height: var(--leading-tight);
  letter-spacing: var(--tracking-mega);
}
.t-display-1 { font-size: var(--text-display-1); }
.t-display-2 { font-size: var(--text-display-2); }
.t-display-3 { font-size: var(--text-display-3); letter-spacing: var(--tracking-tight); line-height: var(--leading-snug); }

.t-h1 { font-family: var(--font-display); font-size: var(--text-h1); font-weight: var(--weight-semibold); line-height: var(--leading-snug); letter-spacing: var(--tracking-tight); color: var(--fg-strong); }
.t-h2 { font-family: var(--font-display); font-size: var(--text-h2); font-weight: var(--weight-semibold); line-height: var(--leading-heading); letter-spacing: var(--tracking-tight); color: var(--fg-strong); }
.t-h3 { font-family: var(--font-display); font-size: var(--text-h3); font-weight: var(--weight-semibold); line-height: var(--leading-heading); color: var(--fg-strong); }

.t-lead   { font-size: var(--text-lg); line-height: var(--leading-body); color: var(--fg-muted); }
.t-body   { font-size: var(--text-md); }
.t-small  { font-size: var(--text-sm); }
.t-caption{ font-size: var(--text-xs); color: var(--fg-muted); }

/* The micro-label. Used above every section and panel. */
.t-label {
  font-family: var(--font-body);
  font-size: var(--text-2xs);
  font-weight: var(--weight-semibold);
  letter-spacing: var(--tracking-label);
  text-transform: uppercase;
  color: var(--fg-subtle);
  line-height: var(--leading-heading);
}

/* Band numbers, prices, scores — display face, tabular */
.t-figure {
  font-family: var(--font-display);
  font-weight: var(--weight-bold);
  letter-spacing: var(--tracking-tight);
  font-variant-numeric: tabular-nums;
  line-height: 1;
  color: var(--fg-strong);
}

.t-muted  { color: var(--fg-muted); }
.t-strong { color: var(--fg-strong); }
.t-brand  { color: var(--fg-brand); }

/* ==============================================================
   4. LAYOUT PRIMITIVES
   ============================================================== */
.container {
  width: 100%;
  max-width: var(--container-max);
  margin-inline: auto;
  padding-inline: var(--gutter);
}
.container--wide { max-width: var(--container-wide); }
.container--text { max-width: var(--container-text); }
.container--flush { padding-inline: 0; }

.section { padding-block: var(--section-y); }
.section--tight { padding-block: var(--section-y-tight); }
.section--ruled { border-top: var(--border-hair) solid var(--edge-hair); }
.section--subtle { background: var(--bg-subtle); }
.section--inverse { background: var(--bg-inverse); color: var(--fg-on-dark); }
.section--inverse h1, .section--inverse h2,
.section--inverse h3, .section--inverse h4 { color: var(--fg-on-dark); }
.section--inverse .t-label { color: var(--fg-on-dark-muted); }
.section--inverse .t-muted { color: var(--fg-on-dark-muted); }

/* Vertical rhythm between siblings */
.stack > * + * { margin-top: var(--space-4); }
.stack-2 > * + * { margin-top: var(--space-2); }
.stack-3 > * + * { margin-top: var(--space-3); }
.stack-5 > * + * { margin-top: var(--space-5); }
.stack-6 > * + * { margin-top: var(--space-6); }
.stack-7 > * + * { margin-top: var(--space-7); }

/* Horizontal group that wraps */
.cluster {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-4);
  align-items: center;
}
.cluster--tight { gap: var(--space-2); }
.cluster--between { justify-content: space-between; }
.cluster--end { justify-content: flex-end; }

/* Auto-fitting grid */
.grid { display: grid; gap: var(--space-6); }
.grid--2 { grid-template-columns: repeat(auto-fit, minmax(min(100%, 300px), 1fr)); }
.grid--3 { grid-template-columns: repeat(auto-fit, minmax(min(100%, 260px), 1fr)); }
.grid--4 { grid-template-columns: repeat(auto-fit, minmax(min(100%, 200px), 1fr)); }
.grid--tight { gap: var(--space-4); }
.grid--flush { gap: 0; }

/* Asymmetric split: content + rail */
.split {
  display: grid;
  gap: var(--space-7);
  grid-template-columns: 1fr;
}
@media (min-width: 760px) {
  .split { grid-template-columns: minmax(0, 1.6fr) minmax(0, 1fr); }
  .split--even { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .split--rail-left { grid-template-columns: minmax(0, 1fr) minmax(0, 1.6fr); }
}

/* Grid children default to min-width:auto, which lets wide content (tables,
   pre blocks) blow the whole layout out horizontally on narrow screens.
   min-width:0 lets them shrink and scroll inside their own box instead. */
.split > *,
.grid > *,
.cards > *,
.panel-set > * { min-width: 0; }

.measure { max-width: var(--measure-body); }
.measure--read { max-width: var(--measure-read); }

/* ==============================================================
   5. UTILITIES — deliberately few
   ============================================================== */
.u-hidden { display: none !important; }
.u-hair-top { border-top: var(--border-hair) solid var(--edge-hair); }
.u-hair-bottom { border-bottom: var(--border-hair) solid var(--edge-hair); }
.u-center { text-align: center; margin-inline: auto; }
.u-nowrap { white-space: nowrap; }
.u-full { width: 100%; }

.u-sr-only {
  position: absolute;
  width: 1px; height: 1px;
  padding: 0; margin: -1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}

.skip-link {
  position: absolute;
  left: var(--space-4);
  top: calc(-1 * var(--space-10));
  z-index: var(--z-modal);
  background: var(--bg-brand);
  color: var(--fg-on-brand);
  padding: var(--space-3) var(--space-5);
  font-size: var(--text-sm);
  font-weight: var(--weight-semibold);
  transition: top var(--duration-base) var(--ease-default);
}
.skip-link:focus { top: var(--space-4); text-decoration: none; }

/* Pre-hydration flicker guard for the bilingual switcher.
   boot.js sets this only when the stored locale differs from the markup's
   base language, so English visitors never wait on it. */
html[data-i18n-pending] body { visibility: hidden; }

/* Route guard. A protected page carries data-guard in its markup, so the
   body is hidden from the very first paint — guard.js removes the attribute
   once the session check passes. Without this the contents of an admin
   screen flash before the redirect fires. */
html[data-guard] body { visibility: hidden; }

/* Auth-aware chrome.
   boot.js sets data-signed-in on <html> before first paint by reading the
   stored session — no network, no library — so the header is correct on the
   very first frame even on marketing pages that never load supabase-js.
   guard.js corrects it later if the session turns out to be stale.

   Hiding the wrong ones (rather than showing the right ones) keeps each
   element's own display value intact: a .btn stays inline-flex, a <li> stays
   list-item. With JavaScript off, only the signed-out chrome shows. */
html:not([data-signed-in="true"]) [data-auth="in"],
html:not([data-admin="true"])     [data-auth="admin"],
html[data-signed-in="true"]       [data-auth="out"] { display: none !important; }
