/* uxlicious — shared chrome.
   Single source of truth for design tokens, the page gutter, and the top nav.
   Linked by EVERY page (homepage + every brief). Change alignment/nav here only. */

:root{
  --paper:#FAFAF8; --ink:#16160F; --ink-soft:rgba(22,22,15,.55);
  --acc:#2230FF; --acc-dim:rgba(34,48,255,.08); --hair:rgba(22,22,15,.13);
  --mono:'IBM Plex Mono',monospace; --sans:'Geist',-apple-system,sans-serif;
  --maxw:none; --pad:clamp(20px,3.6vw,64px); --h1:clamp(28px,4.4vw,56px);
}

/* page gutter — every full-width row uses this, so all content lines up */
.wrap{width:100%;padding-left:var(--pad);padding-right:var(--pad)}

/* top nav — identical on every page. (Homepage overrides .nav to position:absolute
   so it floats over the hero; the inset + padding stay the same either way.) */
.nav{position:relative;z-index:20}
.nav-in{display:flex;align-items:center;justify-content:space-between;padding-top:20px;padding-bottom:20px}
.logo img{display:block;height:26px;width:auto;filter:brightness(0)}
.nav-right{display:flex;align-items:center;gap:clamp(14px,2vw,26px)}
.nav-link{font-family:var(--mono);font-size:11px;letter-spacing:.12em;text-transform:uppercase;color:var(--ink);transition:.2s}
.nav-link:hover{color:var(--acc)}
.nav-cta{font-family:var(--mono);font-size:11px;letter-spacing:.12em;text-transform:uppercase;border:1px solid var(--ink);padding:9px 18px;border-radius:999px;transition:.2s}
.nav-cta:hover{background:var(--acc);border-color:var(--acc);color:#fff}

/* mobile gutter — single source so every page narrows identically */
@media (max-width:760px){ :root{--pad:18px} }

/* page transition — solid black panel.
   Default: a vertical WIPE (panel slides up to reveal the page). Blog-detail pages opt into
   a SIMPLE opacity fade via <body data-trans="simple"> — lighter/faster, better for reading.
   Reveal is pure CSS so a missing/failed site.js can never leave the page covered;
   site.js adds the matching cover-on-exit before internal navigations. */
.pgt{position:fixed;inset:0;z-index:3000;background:var(--ink);pointer-events:none;opacity:1;transform:translateY(0);animation:pgt-wipe .72s cubic-bezier(.76,0,.24,1) both}
@keyframes pgt-wipe{from{transform:translateY(0)}to{transform:translateY(-100%)}}
body[data-trans="simple"] .pgt{transform:none;opacity:0;animation:pgt-fade .34s ease both}
@keyframes pgt-fade{from{opacity:1}to{opacity:0}}
@media (prefers-reduced-motion:reduce){ .pgt{display:none;animation:none} }

/* custom cursor — dot + lagged ring, fine-pointer only.
   The native cursor is ONLY hidden once site.js confirms it's running (html.cursor-on),
   so no-JS / reduced-motion / touch users always keep a real cursor. */
@media (hover:hover) and (pointer:fine){
  html.cursor-on, html.cursor-on *{cursor:none}
  .cursor{position:fixed;left:0;top:0;width:0;height:0;z-index:9999;pointer-events:none;mix-blend-mode:difference;opacity:0;transition:opacity .25s ease}
  .cursor.vis{opacity:1}
  .cursor .ring,.cursor .dot{position:absolute;top:0;left:0;border-radius:50%;will-change:transform}
  /* eye: ring = eye outline, dot = pupil (site.js drives position + the occasional blink via scaleY) */
  .cursor .ring{width:36px;height:36px;border:1.5px solid #fff;transition:width .26s cubic-bezier(.2,.7,.2,1),height .26s cubic-bezier(.2,.7,.2,1),opacity .2s ease}
  .cursor .dot{width:8px;height:8px;background:#fff;transition:width .2s ease,height .2s ease,opacity .2s ease}
  .cursor.hot .ring{width:54px;height:54px}
  .cursor.hot .dot{width:11px;height:11px}
  .cursor.down .ring{width:30px;height:30px}
  .cursor.down .dot{width:12px;height:12px}
}

/* scroll reveals — elements stay VISIBLE by default; site.js adds html.reveal-ready
   (only when JS runs and motion is allowed) before hiding them, so no-JS / reduced-motion
   / a failed site.js can never leave content invisible. */
.reveal-ready .reveal{opacity:0;transform:translateY(20px);transition:opacity .7s cubic-bezier(.2,.7,.2,1),transform .7s cubic-bezier(.2,.7,.2,1)}
.reveal-ready .reveal.in{opacity:1;transform:none}
