/* ============================================================
   Reset & base
   ============================================================ */
*, *::before, *::after{ box-sizing: border-box; }
* { margin:0; }
html{
  -webkit-text-size-adjust:100%;
  scroll-behavior:smooth;
}
@media (prefers-reduced-motion: reduce){
  html{ scroll-behavior:auto; }
  *, *::before, *::after{
    animation-duration:.001ms !important;
    animation-iteration-count:1 !important;
    transition-duration:.001ms !important;
    scroll-behavior:auto !important;
  }
}
body{
  background-color:var(--paper);
  color:var(--ink);
  font-family:var(--font-body);
  font-size:var(--fs-body);
  line-height:1.6;
  font-weight:400;
  -webkit-font-smoothing:antialiased;
  overflow-x:clip;
  position:relative;
}
/* Sitewide grain — a fine noise tile screen-blended over the whole
   viewport at low opacity, reads as brushed stone/basalt. Fixed +
   pointer-events:none so it never intercepts clicks or scrolling. */
body::after{
  content:"";
  position:fixed;
  inset:0;
  z-index:2000;
  pointer-events:none;
  background-image:var(--grain);
  background-size:128px 128px;
  background-repeat:repeat;
  mix-blend-mode:screen;
  opacity:.025;
}
/* Cursor-following glow — a soft Jodhpur-blue spotlight tracking the
   pointer across the whole page. JS updates --cx/--cy (rAF-throttled);
   pure CSS otherwise, screen-blended so it lifts light without ever
   washing out or blocking the content underneath. */
#cursorGlow{
  position:fixed; inset:0;
  z-index:1;
  pointer-events:none;
  opacity:0;
  transition:opacity .4s var(--ease);
  background: radial-gradient(168px circle at var(--cx,50%) var(--cy,35%), rgba(var(--jodhpur-rgb),.08), transparent 68%);
  mix-blend-mode:screen;
}
#cursorGlow.is-active{ opacity:1; }
@media (prefers-reduced-motion: reduce){
  #cursorGlow{ display:none; }
}
@media (max-width: 1179px), (hover: none), (pointer: coarse){
  #cursorGlow{ display:none; }
}
/* Custom cursor — swaps the OS pointer for the Ximex mark, gated to the
   same desktop/real-mouse condition as the glow above. `*` + !important
   is needed because several elements set their own `cursor:pointer`
   (button, .icon-btn, etc.), which would otherwise win over a value
   inherited from html/body. */
@media (hover: hover) and (pointer: fine) and (min-width: 1180px){
  *{ cursor: url('/assets/icons/cursor.png') 0 0, auto !important; }
}
/* Scroll performance guard — glass blur is expensive to recompute
   every frame while the page is actually moving (the content behind
   each blurred card changes on every scroll tick). Dropping it for
   the ~150ms a scroll gesture is active is invisible in motion and
   removes the single biggest cause of scroll jank; see js_12. The
   header is excluded on purpose — it's a single small element (not
   dozens of cards), cheap enough to keep blurred permanently so it
   never visibly loses its glass while scrolling. */
html.is-scrolling *:not(.site-header):not(.site-header *){
  backdrop-filter:none !important;
  -webkit-backdrop-filter:none !important;
}
img, svg, canvas, video{ display:block; max-width:100%; }
img{ height:auto; }
/* Icon-sprite default: outline style unless a shape sets its own fill/stroke
   (logo mark, favicon and solid glyph dots all declare their own explicitly,
   and those presentation attributes still win over this inherited default). */
svg{ fill:none; stroke:currentColor; stroke-width:1.6; stroke-linecap:round; stroke-linejoin:round; }
a{ color:inherit; text-decoration:none; }
button, input, select, textarea{ font:inherit; color:inherit; background:none; border:none; }
button{ cursor:pointer; }
ul, ol{ list-style:none; padding:0; }
table{ border-collapse:collapse; }
:focus-visible{
  outline: 2.5px solid var(--jodhpur-500);
  outline-offset: 3px;
  border-radius: 1px;
}
::selection{ background: var(--jodhpur-300); color: var(--black-950); }

h1,h2,h3,h4{
  font-family:var(--font-display);
  font-weight:700;
  color:var(--ink);
  line-height:1.1;
  text-wrap:balance;
  letter-spacing:-0.02em;
}
h1{ font-size:var(--fs-h1); line-height:1.02; }
h2{ font-size:var(--fs-h2); line-height:1.08; }
h3{ font-size:var(--fs-h3); }
h4{ font-size:var(--fs-h4); letter-spacing:-0.01em; }

p{ text-wrap:pretty; }
.on-dark h1, .on-dark h2, .on-dark h3, .on-dark h4{ color:var(--on-black); }

em, .accent-word{
  font-family:var(--font-display);
  font-style:normal;
  font-weight:700;
  color:var(--jodhpur-300);
}
.on-dark em, .on-dark .accent-word{ color:var(--jodhpur-300); }

.mono{ font-family:var(--font-mono); font-variant-numeric:tabular-nums; letter-spacing:0; }

/* ============================================================
   Layout primitives
   ============================================================ */
.container{
  width:100%;
  max-width:var(--container-w);
  margin-inline:auto;
  padding-inline:var(--container-pad);
}
.section{
  padding-block:var(--section-pad);
  position:relative;
}
.section-head{
  display:flex;
  flex-direction:column;
  gap:var(--sp-4);
  max-width:56rem;
  margin-bottom:var(--sp-8);
}
.section-head.center{ margin-inline:auto; text-align:center; align-items:center; }
.section-head p:not(.eyebrow){ color:var(--slate); font-size:var(--fs-lead); max-width:42em; }

.eyebrow{
  display:inline-flex;
  align-items:center;
  gap:var(--sp-3);
  font-family:var(--font-body);
  font-size:var(--fs-xs);
  font-weight:700;
  letter-spacing:.14em;
  text-transform:uppercase;
  color:var(--jodhpur-300);
}
.eyebrow::before{
  content:"";
  width:28px; height:1px;
  background:var(--jodhpur-500);
  flex:none;
}

.visually-hidden{
  position:absolute !important;
  width:1px;height:1px;
  padding:0;margin:-1px;
  overflow:hidden;
  clip:rect(0,0,0,0);
  white-space:nowrap;
  border:0;
}

.skip-link{
  position:fixed;
  top:-100px; left:var(--sp-4);
  z-index:999;
  background:var(--black-950);
  color:var(--on-black);
  padding:var(--sp-3) var(--sp-5);
  transition: top var(--dur-fast) var(--ease);
  font-weight:700;
}
.skip-link:focus{ top:var(--sp-4); }

/* Grids */
.grid{ display:grid; gap:var(--sp-6); }
.grid-2{ grid-template-columns:repeat(2,1fr); }
.grid-3{ grid-template-columns:repeat(3,1fr); }
.grid-4{ grid-template-columns:repeat(4,1fr); }

/* Divider rule */
.rule{
  height:1px;
  background:var(--line);
  border:0;
}
.on-dark .rule{ background:var(--line-on-black); }

/* Corner-bracket motif — cargo-crate / stamped-document corners */
.bracket{
  position:relative;
}
.bracket::before,
.bracket::after{
  content:"";
  position:absolute;
  width:14px; height:14px;
  pointer-events:none;
  transition: width var(--dur-med) var(--ease), height var(--dur-med) var(--ease), opacity var(--dur-med) var(--ease);
  opacity:.55;
  z-index:2;
}
.bracket::before{
  top:0; left:0;
  border-top:2px solid var(--jodhpur-500);
  border-left:2px solid var(--jodhpur-500);
}
.bracket::after{
  bottom:0; right:0;
  border-bottom:2px solid var(--jodhpur-500);
  border-right:2px solid var(--jodhpur-500);
}
.bracket:hover::before, .bracket:hover::after,
.bracket:focus-within::before, .bracket:focus-within::after{
  width:20px; height:20px; opacity:1;
}
.on-dark .bracket::before, .on-dark .bracket::after{ border-color: var(--jodhpur-400); }

/* Reveal-on-scroll — scoped to html.js (set by an inline script in
   <head>) so content stays fully visible by default when JS never
   runs at all: no-JS visitors and simple crawlers never see a
   permanently-blank section. */
html.js [data-reveal]{
  opacity:0;
  transform:translateY(22px);
  transition: opacity .7s var(--ease), transform .7s var(--ease);
}
html.js [data-reveal].is-visible{ opacity:1; transform:none; }
@media (prefers-reduced-motion: reduce){
  html.js [data-reveal]{ opacity:1; transform:none; transition:none; }
}

