/* ============================================================
   base.css — reset, typography, form defaults.
   No component styling lives here.
   ============================================================ */

*, *::before, *::after { box-sizing: border-box; }

html, body { height: 100%; }

body {
  margin: 0;
  background: var(--bg);
  color: var(--ink);
  font-family: var(--font);
  font-size: 14px;
  line-height: 1.5;
  -webkit-font-smoothing: antialiased;
  text-wrap: pretty;
}

h1, h2, h3, h4 { margin: 0; font-weight: 800; letter-spacing: -.03em; line-height: 1.1; }
h1 { font-size: clamp(26px, 3.6vw, 38px); }
h2 { font-size: 16px; }
p  { margin: 0; }

a { color: #6D34E8; text-decoration: none; }
a:hover { color: var(--brand-teal); }

img { max-width: 100%; display: block; }

button, input, select, textarea { font: inherit; color: inherit; outline: none; }
button { cursor: pointer; border: none; background: none; padding: 0; }
input::placeholder, textarea::placeholder { color: var(--faint); }

::selection { background: #E4D9FF; color: var(--ink); }

/* Smooth anchor-link scrolling (landing page section nav) — skipped
   entirely for anyone who has asked the OS for reduced motion. */
@media (prefers-reduced-motion: no-preference) {
  html { scroll-behavior: smooth; }
}

::-webkit-scrollbar { width: 10px; height: 10px; }
::-webkit-scrollbar-thumb { background: #DCDFEA; border-radius: 8px; }
::-webkit-scrollbar-track { background: transparent; }

/* Utilities used across pages */
.grad-text {
  background-image: var(--grad-text);
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
}
.mono { font-family: var(--mono); }
.serif { font-family: var(--serif); font-style: italic; font-weight: 400; }
.muted { color: var(--mut); }
.faint { color: var(--faint); }
.eyebrow { font-size: 11px; font-weight: 700; letter-spacing: .12em; color: var(--faint); text-transform: uppercase; }
.lead { font-size: 14.5px; color: var(--mut); line-height: 1.6; }
.row { display: flex; align-items: center; gap: 10px; }
.row-wrap { display: flex; flex-wrap: wrap; align-items: center; gap: 10px; }
.spread { display: flex; align-items: center; justify-content: space-between; gap: 12px; }
.stack { display: flex; flex-direction: column; gap: 12px; }
.grow { flex: 1; min-width: 0; }
.hidden { display: none !important; }

/* ---- Signed-out flash guard -------------------------------------------
   App pages are static HTML, so their markup paints the moment it parses
   — a signed-out visitor would see the whole studio for a beat before the
   redirect fired. An inline <script> in each gated page's <head> sets
   data-auth-pending before first paint; js/shell.js clears it once a real
   user is confirmed, and the redirect replaces the page otherwise. The
   spinner is inert markup-free CSS so it needs nothing in the body. */
html[data-auth-pending] body > * { visibility: hidden; }
html[data-auth-pending] body {
  background: var(--bg);
  min-height: 100vh;
  min-height: 100dvh;   /* dvh excludes the mobile address bar; vh does not */
}
html[data-auth-pending] body::after {
  content: '';
  position: fixed; top: 50%; left: 50%;
  width: 26px; height: 26px; margin: -13px 0 0 -13px;
  border: 2px solid var(--line, rgba(255,255,255,.18));
  border-top-color: var(--acc, #7C4DFF);
  border-radius: 50%;
  animation: authSpin .7s linear infinite;
}
@keyframes authSpin { to { transform: rotate(360deg); } }
@media (prefers-reduced-motion: reduce) {
  html[data-auth-pending] body::after { animation-duration: 2.4s; }
}

/* ---- Skip to content --------------------------------------------------
   Keyboard users land on the nav on every page load; without this they
   tab through the whole header before reaching the content. Off-screen
   until focused, then pinned top-left. */
.skip-link {
  position: absolute; left: 8px; top: -60px; z-index: 200;
  padding: 10px 16px; border-radius: 0 0 10px 10px;
  background: var(--purple, #7C4DFF); color: #fff;
  font-size: 13px; font-weight: 700; text-decoration: none;
  transition: top .15s ease;
}
.skip-link:focus { top: 0; }
@media (prefers-reduced-motion: reduce) { .skip-link { transition: none; } }

/* Keyboard focus has to be visible on everything interactive. Buttons here
   are styled <button>/<a>, which lose the UA outline as soon as a custom
   background lands on them. */
a:focus-visible,
button:focus-visible,
input:focus-visible,
select:focus-visible,
textarea:focus-visible,
summary:focus-visible,
[tabindex]:focus-visible {
  outline: 2px solid var(--purple, #7C4DFF);
  outline-offset: 2px;
  border-radius: 4px;
}

/* Every logo now declares its intrinsic 1312x300 so the browser reserves the
   right box and nothing shifts on first paint. Each place that draws it sets
   a height and lets the width follow — but a couple (the drawer head, the
   footer lockup) only set height, and with a width attribute present that
   would render a 1312px-wide, 22px-tall logo. Pinned by source so no context
   can miss it. */
img { max-width: 100%; }
img[src$="uniqueness-logo.png"] { width: auto; }

/* Visible to screen readers and crawlers, not on screen. Used where a page
   needs a heading for document structure that the visual design puts
   somewhere else (the editor's title lives in the JS-rendered topbar). */
.sr-only {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}

/* ---- No sideways scroll --------------------------------------------------
   One over-wide element anywhere drags the whole page sideways, and on a
   phone that shows as a permanently offset layout the reader has to fight.
   Belt and braces: clip at the root, and stop long unbroken strings (a URL,
   a file name, a Hinglish word) from forcing the width in the first place. */
html, body { overflow-x: hidden; max-width: 100%; }
body { overflow-wrap: break-word; }
pre, code, .mono { overflow-wrap: anywhere; }
