/* ── AskStein shared page chrome (about / corpus / documentation / contact) ── */
:root{
  --paper:#F6F1E7; --paper-sunk:#EFE8D9; --paper-raise:#FDFBF6;
  --ink:#16181A; --ink-2:#4A4E52; --ink-3:#696E72; --rule:#E2DFD9;
  --accent:#1B4D3E; --accent-soft:#E8EFEB;
  --evidence:#80591C; --evidence-tint:#F7EFDD;
  --boundary:#9A5B3F; --boundary-tint:#F6EDE7;
  --sans:"IBM Plex Sans",-apple-system,BlinkMacSystemFont,"Segoe UI",sans-serif;
  /* unified on the wordmark's typeface: serif and mono now point at
     the same sans stack rather than a separate font, so every text
     style on the page reads in the one typeface used for "AskStein". */
  --serif:var(--sans);
  --mono:var(--sans);
  /* centralized motion tokens — one language, reused everywhere rather
     than one-off durations/easings per component */
  --ease-out:cubic-bezier(.16,1,.3,1);
  --ease-in-out:cubic-bezier(.65,0,.35,1);
  --dur-micro:.25s;
  --dur-fast:.4s;
  --dur-reveal:.8s;
  --reveal-rise:28px;
  --reveal-stagger:.08s;
}
*{box-sizing:border-box}
html,body{margin:0;padding:0}
body{background:var(--paper);color:var(--ink);font-family:var(--sans);font-size:15px;line-height:1.6;
  -webkit-font-smoothing:antialiased}

/* ── page-load preloader ─────────────────────────────────────
   Shown on every load/refresh, on top of everything else, until
   the page fades in behind it. */
#loader{position:fixed;inset:0;z-index:9999;background:var(--paper);
  display:flex;align-items:center;justify-content:center;
  transition:opacity .5s cubic-bezier(.4,0,.2,1),visibility 0s linear .5s}
#loader.done{opacity:0;visibility:hidden;pointer-events:none}
.loader-inner{display:flex;flex-direction:column;align-items:center;gap:24px}
.loader-word{display:flex;perspective:700px}
.loader-word span{display:inline-block;font-family:var(--sans);font-weight:600;
  font-size:clamp(30px,6.4vw,56px);letter-spacing:.13em;text-transform:uppercase;
  color:var(--ink);transform-origin:50% 55%;will-change:transform;
  transition:transform .5s cubic-bezier(.34,1.56,.64,1),color .5s ease}
.loader-word span.spin{transform:rotateY(360deg);color:var(--accent)}
.loader-bar{width:200px;height:2px;border-radius:2px;background:var(--rule);overflow:hidden}
.loader-bar-fill{height:100%;width:0%;background:var(--accent);transition:width .1s linear}
@media (prefers-reduced-motion:reduce){
  #loader,.loader-word span,.loader-bar-fill{transition:none}
}

/* ── ambient field: the same reconstruction from the home screen,
   run ambient-only, so these pages read as part of the same product
   rather than a separate static site. Masked so it thins out behind
   the centered reading column and stays out of the way of text. ── */
#field{position:fixed;inset:0;z-index:0;pointer-events:none;display:block;
  /* thins only directly behind the reading column — the same
     treatment the home screen uses to keep the reconstruction
     genuinely visible in the margins rather than a barely-there
     trace. */
  mask-image:radial-gradient(ellipse 30% 46% at 50% 34%,
    transparent 0%,transparent 22%,rgba(0,0,0,.55) 48%,rgba(0,0,0,.92) 72%,#000 100%);
  -webkit-mask-image:radial-gradient(ellipse 30% 46% at 50% 34%,
    transparent 0%,transparent 22%,rgba(0,0,0,.55) 48%,rgba(0,0,0,.92) 72%,#000 100%)}
@media (max-width:760px){
  #field{mask-image:radial-gradient(ellipse 20% 34% at 50% 30%,
      transparent 0%,transparent 18%,rgba(0,0,0,.6) 46%,rgba(0,0,0,.94) 70%,#000 100%);
    -webkit-mask-image:radial-gradient(ellipse 20% 34% at 50% 30%,
      transparent 0%,transparent 18%,rgba(0,0,0,.6) 46%,rgba(0,0,0,.94) 70%,#000 100%)}
}
/* on narrow phones the reading column is nearly the full viewport width,
   so the masked-in edges of the illustration sit closer to body text —
   drop overall opacity a bit further here as an extra contrast margin,
   on top of the mask thinning above */
@media (max-width:480px){
  #field{opacity:.6}
}
/* faint scientific grid — reads as graph paper, not as a dashboard */
#ground{position:fixed;inset:0;z-index:1;pointer-events:none;
  background-image:
    linear-gradient(rgba(22,24,26,.05) 1px,transparent 1px),
    linear-gradient(90deg,rgba(22,24,26,.05) 1px,transparent 1px);
  background-size:88px 88px;
  mask-image:radial-gradient(ellipse 120% 90% at 50% 0%,#000 20%,transparent 78%);
  -webkit-mask-image:radial-gradient(ellipse 120% 90% at 50% 0%,#000 20%,transparent 78%)}
#atmos{position:fixed;inset:0;z-index:2;pointer-events:none;
  background:radial-gradient(ellipse 78% 58% at 50% 22%,rgba(255,255,255,.4),transparent 66%),
    radial-gradient(ellipse 130% 110% at 50% 50%,transparent 42%,rgba(22,24,26,.05) 100%)}
.page{position:relative;z-index:3}
@media (max-width:768px){ #ground{opacity:.5} }
@media (prefers-reduced-motion:reduce){ #field{opacity:.6} }
button{font-family:inherit;font-size:inherit;color:inherit;cursor:pointer}
a{color:var(--accent)}
:focus-visible{outline:2px solid var(--accent);outline-offset:2px;border-radius:2px}

/* ── skip link: hidden until focused, so keyboard users can bypass
   the header/sidebar controls and land straight on the page content ── */
.skip-link{position:absolute;left:12px;top:-48px;z-index:500;
  background:var(--ink);color:var(--paper);font-family:var(--sans);font-size:13px;
  font-weight:500;padding:10px 16px;border-radius:4px;text-decoration:none;
  transition:top .15s var(--ease-out)}
.skip-link:focus{top:12px}

/* ── header ─────────────────────────────────── */
header{display:flex;align-items:center;gap:20px;padding:20px 36px;position:sticky;top:0;z-index:50;
  background:rgba(251,250,248,.55);backdrop-filter:saturate(140%) blur(14px);
  -webkit-backdrop-filter:saturate(140%) blur(14px);
  border-bottom:1px solid rgba(22,24,26,.07);
  box-shadow:0 1px 0 rgba(255,255,255,.35) inset, 0 6px 20px -14px rgba(22,24,26,.22)}
header .brand{display:flex;flex-direction:column;align-items:flex-start;gap:8px}
.wordmark{font-family:var(--sans);font-weight:600;letter-spacing:.14em;font-size:18px;
  text-transform:uppercase;text-decoration:none;color:var(--ink)}
header nav{margin-left:auto;display:flex;gap:22px;font-size:13px;color:var(--ink-2)}
header nav a{background:none;border:0;padding:0;color:inherit;text-decoration:none}
header nav a:hover{color:var(--ink)}

/* ── hamburger + sidebar ────────────────────── */
/* Fold & tumble: the panel is hinged at the left edge and opens by
   rotating in from edge-on (like a door swinging open) with a slight
   diagonal rotateZ tilt that untwists as it settles, plus a small
   overshoot on the easing curve so it reads as tumbling into place
   rather than just tilting flat. Same choreography in reverse on
   close. The page content still shifts over on its own quick,
   non-bouncy timing so only the panel itself performs the fold. */
:root{
  --menu-ease:cubic-bezier(.34,1.56,.64,1);
  --menu-dur:.52s;
  --menu-ease-page:cubic-bezier(.4,0,.2,1);
  --menu-dur-page:.28s;
}

/* hit box is 44×44 (WCAG 2.5.5) even though the visible icon stays
   small — padding does the work, the icon glyph itself doesn't grow */
.hamburger{background:none;border:0;display:flex;flex-direction:column;
  justify-content:center;align-items:center;gap:4px;cursor:pointer;
  width:44px;height:44px;padding:0;margin:-11px -11px -11px 0}
.hamburger span{display:block;height:1.5px;width:22px;background:var(--ink-2);border-radius:2px;
  transition:background .15s}
.hamburger:hover span{background:var(--ink)}

/* click-outside-to-close catcher only — no visual dimming, since
   the sidebar pushes content rather than sitting modally above it */
#sidebar-overlay{position:fixed;top:0;left:270px;right:0;bottom:0;background:transparent;
  opacity:0;pointer-events:none;z-index:200}
#sidebar-overlay.on{opacity:1;pointer-events:auto}

#sidebar{position:fixed;top:0;left:0;bottom:0;width:270px;z-index:201;
  background:var(--paper);
  border-right:1px solid var(--rule);
  transform-origin:0% 50%;
  transform:perspective(900px) rotateY(-92deg) rotateZ(-5deg) scale(.92);
  opacity:0;
  backface-visibility:hidden;
  transition:transform var(--menu-dur) var(--menu-ease),
             opacity calc(var(--menu-dur) * .6) linear;
  padding:22px 26px;display:flex;flex-direction:column;gap:24px}
#sidebar.on{transform:perspective(900px) rotateY(0deg) rotateZ(0deg) scale(1);opacity:1}
.sidebar-close{align-self:flex-end;background:none;border:0;font-size:16px;line-height:1;
  color:var(--ink-2);cursor:pointer;
  width:44px;height:44px;display:flex;align-items:center;justify-content:center;
  margin:-11px -11px 0 0}
.sidebar-close:hover{color:var(--ink)}
.sidebar-nav{display:flex;flex-direction:column;gap:18px;margin-top:8px}
.sidebar-nav a{font-family:var(--sans);font-size:13.5px;letter-spacing:.02em;color:var(--ink);
  text-decoration:none;transition:color .15s}
.sidebar-nav a:hover{color:var(--accent)}
.sidebar-nav a.current{color:var(--accent);font-weight:500}

body.sidebar-open{overflow-x:hidden}
body.sidebar-open .page-shift{margin-left:270px}
body.sidebar-open header{margin-left:270px}
@media (max-width:900px){
  body.sidebar-open .page-shift,body.sidebar-open header{margin-left:0}
  #sidebar-overlay{left:0}
}
header{transition:margin-left var(--menu-dur-page) var(--menu-ease-page)}

/* ── page-entrance fade: the destination page fades and rises in on
   arrival (tap a nav link → new page loads → this plays), rather than
   just appearing. Same duration/ease as the scroll-reveal system, so
   it reads as one motion language, not a separate effect. Progressive
   enhancement: opacity:1 by default, only hidden-then-revealed once
   nav.js has added "js" and is actually running the reveal. */
.page-shift{
  transition:margin-left var(--menu-dur-page) var(--menu-ease-page),
             opacity var(--dur-reveal) var(--ease-out),
             transform var(--dur-reveal) var(--ease-out);
}
.js .page-shift{opacity:0;transform:translateY(var(--reveal-rise))}
.js .page-shift.in{opacity:1;transform:translateY(0)}

/* ── page-exit fade ("fade away"): clicking any internal link fades
   the current page out before the browser actually navigates, so
   leaving a page feels like the mirror image of arriving on one —
   same easing, a quicker duration since this one's blocking the
   click. .leaving has two classes so it outranks the plain
   .page-shift transition above and safely overrides its duration. */
.page-shift.leaving{
  transition:opacity var(--dur-fast) var(--ease-out),
             transform var(--dur-fast) var(--ease-out);
  opacity:0;
  transform:translateY(calc(var(--reveal-rise) * -0.4));
}

@media (prefers-reduced-motion:reduce){
  .hamburger span,#sidebar-overlay,#sidebar,.sidebar-nav a,.page-shift,header{transition:none}
  .js .page-shift,.js .page-shift.in,.page-shift.leaving{opacity:1;transform:none}
  #sidebar{transform:none;opacity:1}
  #sidebar:not(.on){display:none}
}

/* ── typography / content blocks ───────────── */
.page{max-width:760px;margin:0 auto;padding:56px 36px 110px}
.back-link{display:inline-flex;align-items:center;gap:7px;background:none;border:0;padding:0;
  font-family:var(--sans);font-size:11px;letter-spacing:.1em;text-transform:uppercase;
  color:var(--ink-3);margin-bottom:26px;text-decoration:none}
.back-link:hover{color:var(--accent)}
.eyebrow{font-family:var(--sans);font-size:11px;letter-spacing:.16em;text-transform:uppercase;
  color:var(--ink-3);margin:0 0 22px;display:flex;align-items:center;gap:10px}
.eyebrow::before{content:"";width:22px;height:1px;background:var(--ink-3)}
.qhead{font-family:var(--serif);font-size:clamp(32px,6vw,56px);line-height:1.08;font-weight:400;
  letter-spacing:-.015em;margin:0 0 24px;max-width:16ch}
.direct{font-family:var(--serif);font-size:16px;line-height:1.6;margin:0 0 40px;max-width:58ch;
  color:var(--ink-2)}
.label{font-size:10px;letter-spacing:.12em;text-transform:uppercase;color:var(--ink-3);
  font-weight:500;margin:48px 0 20px}
.label:first-of-type{margin-top:0}
p.body{font-size:14.5px;line-height:1.7;color:var(--ink-2);max-width:64ch;margin:0 0 16px}
.brow{display:grid;grid-template-columns:110px 1fr;gap:14px;font-size:13px;margin-bottom:16px}
.brow dt{color:var(--ink-3);font-size:11px;letter-spacing:.07em;text-transform:uppercase;
  padding-top:2px;margin:0}
.brow dd{margin:0;color:var(--ink-2)}
.brow dd.bd{color:var(--boundary)}
.bdrule{display:flex;align-items:center;gap:14px;margin:40px 0 24px;max-width:64ch;
  font-size:10.5px;letter-spacing:.1em;text-transform:uppercase;color:var(--ink-3);font-weight:500}
.bdrule::after{content:"";flex:1;height:1px;background:var(--rule)}
.stepline{display:grid;grid-template-columns:26px 1fr;gap:14px;margin-bottom:18px;max-width:64ch}
.stepline .n{font-family:var(--mono);font-size:11.5px;color:var(--accent);padding-top:2px}
.stepline .h{font-size:14px;font-weight:500;color:var(--ink);margin-bottom:3px;
  display:flex;align-items:center;gap:8px}
.stepline .icon{display:inline-flex;flex:none;width:17px;height:17px;color:var(--accent)}
.stepline .icon svg{width:100%;height:100%;fill:none;stroke:currentColor;stroke-width:1.4;
  stroke-linecap:round;stroke-linejoin:round}
.stepline .d{font-size:13.5px;line-height:1.6;color:var(--ink-2)}
.lims{list-style:none;padding:0;margin:0 0 16px;max-width:64ch}
.lims li{position:relative;padding-left:18px;margin-bottom:9px;font-size:14.5px;color:var(--ink-2);
  line-height:1.55}
.lims li::before{content:"";position:absolute;left:2px;top:10px;width:5px;height:1px;
  background:var(--ink-3)}
.team-grid{display:grid;gap:22px 32px;max-width:none}
@media (min-width:760px){.team-grid{grid-template-columns:1fr 1fr}}
.team-card{border-top:1px solid var(--rule);padding-top:16px}
/* a monogram stands in for a photo — no stock headshots, no fake
   imagery. Deterministic per name, so it reads as an identity mark
   rather than decoration. */
.avatar{width:44px;height:44px;border-radius:50%;border:1px solid var(--rule);
  display:flex;align-items:center;justify-content:center;margin-bottom:14px;
  font-family:var(--serif);font-size:15px;color:var(--accent);background:var(--accent-soft)}
.team-card .who{font-family:var(--serif);font-size:17px;color:var(--ink);margin-bottom:2px}
.team-card .role{font-size:11px;letter-spacing:.07em;text-transform:uppercase;color:var(--accent);
  margin-bottom:8px}
.team-card .focus{font-size:13.5px;line-height:1.6;color:var(--ink-2);max-width:60ch}
/* above-the-fold hero CTA on Contact: a real button rather than a
   buried footnote link, plus a short helper note with the plain-text
   address for anyone who'd rather copy it than click */
.contact-cta{margin:0 0 56px;max-width:64ch}
.btn-primary{display:inline-flex;align-items:center;min-height:44px;
  font-family:var(--sans);font-size:14px;font-weight:600;letter-spacing:.01em;
  color:var(--paper);background:var(--accent);text-decoration:none;
  padding:12px 22px;border-radius:4px;
  transition:background var(--dur-micro) var(--ease-out),
             box-shadow var(--dur-micro) var(--ease-out)}
.btn-primary:hover{background:#153f33;box-shadow:0 8px 20px -12px rgba(27,77,62,.55)}
.cta-note{font-size:13.5px;line-height:1.6;color:var(--ink-2);max-width:56ch;margin:14px 0 0}
.cta-note a{font-family:var(--sans);color:var(--accent);text-decoration:none}
.cta-note a:hover{text-decoration:underline}
/* the closing line on every page — restyled as a genuine pull-quote
   (was a small caption-sized footnote) so each page ends on a
   deliberate statement rather than trailing off quietly */
.philosophy{margin-top:64px;padding:4px 0 4px 26px;border-left:2px solid var(--accent);
  font-family:var(--serif);font-size:clamp(19px,2.6vw,26px);color:var(--ink);line-height:1.45;
  letter-spacing:-.005em;max-width:50ch}

/* ── numbered index grids: reused for "the three places trust
   lives" and "the four wedges" on About, and the build-steps row
   on Corpus. Desktop: side-by-side columns with a rule and a mono
   index number, echoing the editorial numbered-section pattern.
   Mobile: stacks like everything else. ───────────────────────── */
.trio,.wedges{display:grid;gap:28px;margin:0 0 40px;max-width:100%}
.trio{grid-template-columns:repeat(3,1fr)}
.wedges{grid-template-columns:1fr 1fr;gap:28px 32px}
.trio-item,.wedge-item{border-top:1px solid var(--rule);padding-top:16px}
.trio-n{font-family:var(--mono);font-size:11px;color:var(--accent);letter-spacing:.05em}
.trio-icon{display:block;width:26px;height:26px;margin:14px 0 12px;color:var(--accent)}
.trio-icon svg{width:100%;height:100%;fill:none;stroke:currentColor;stroke-width:1.3;
  stroke-linecap:round;stroke-linejoin:round}
.trio-h{font-family:var(--serif);font-size:19px;font-weight:400;margin:0 0 8px;color:var(--ink)}
.trio-d{font-size:13.5px;line-height:1.6;color:var(--ink-2);margin:0}
@media (max-width:760px){
  .trio{grid-template-columns:1fr;gap:24px}
}
@media (max-width:640px){
  .wedges{grid-template-columns:1fr;gap:24px}
}

/* ── timeline: the roadmap on Documentation gets a connecting
   line so the steps read as one continuous path rather than a
   loose list — a single, restrained signature moment. ────────── */
.timeline{position:relative;padding-left:2px;max-width:64ch;margin:0;list-style:none}
.timeline::before{content:"";position:absolute;left:11px;top:6px;bottom:6px;width:1px;
  background:var(--rule)}
.timeline .stepline{display:block;position:relative;padding-left:36px;margin-bottom:22px;
  max-width:none}
.timeline .stepline .n{position:absolute;left:0;top:-1px;width:23px;height:23px;
  display:flex;align-items:center;justify-content:center;border-radius:50%;
  background:var(--paper);border:1px solid var(--rule);font-size:10px;color:var(--accent)}

/* ── a row of build-steps side by side at desktop width, instead
   of stacking straight down — gives the page some horizontal rhythm
   instead of one unbroken vertical list. ─────────────────────── */
.steps-row{display:grid;gap:28px;margin-bottom:8px}
@media (min-width:760px){
  .steps-row{grid-template-columns:repeat(3,1fr)}
  .steps-row .stepline{margin-bottom:0}
}
.stat-strip{display:grid;grid-template-columns:repeat(3,1fr);gap:22px;margin:0 0 44px;max-width:64ch}
.mobile-stat,.stat{border-top:1px solid var(--rule);padding-top:12px}
.stat .n{font-family:var(--mono);font-size:clamp(22px,3.6vw,34px);color:var(--ink);letter-spacing:-.02em}
.stat .l{font-size:10.5px;letter-spacing:.08em;text-transform:uppercase;color:var(--ink-3);
  margin-top:4px}
@media (max-width:640px){
  .page{padding:40px 20px 80px}
  .stat-strip{grid-template-columns:1fr 1fr}
  .qhead{font-size:30px;max-width:none}
  /* mobile body-copy floor: nothing readers actually read should sit
     below 16px, and role labels get a touch bigger too */
  p.body{font-size:16px}
  .team-card .focus{font-size:16px}
  .team-card .role{font-size:12px}
}

/* ── site footer (Contact page) ──────────────────────────────
   Plain, low-key close to the page — identity, contact address,
   and the two placeholder legal links required before a real launch. */
.site-footer{position:relative;z-index:3;border-top:1px solid var(--rule);
  margin-top:24px;padding:28px 36px 40px}
.site-footer-inner{max-width:760px;margin:0 auto;display:flex;flex-wrap:wrap;
  align-items:baseline;gap:10px;font-size:12.5px;color:var(--ink-3)}
.site-footer-inner .wordmark{font-size:13px;letter-spacing:.12em;margin-right:4px}
.site-footer-inner a{color:var(--ink-2);text-decoration:none}
.site-footer-inner a:hover{color:var(--accent);text-decoration:underline}
.footer-sep{color:var(--rule)}
.footer-copy{flex-basis:100%;margin-top:6px;font-size:11.5px;color:var(--ink-3)}

/* ── micro-interactions ───────────────────────────────────────
   Small, fast (0.2–0.3s), consistent responses on everything
   touchable — inline links draw an underline, team cards lift.
   Nothing here is decorative; each response acknowledges the
   element was touched. */
p.body a,p.direct a,p.philosophy a,.cta-note a,.brow dd a{
  text-decoration:none;
  background-image:linear-gradient(currentColor,currentColor);
  background-position:0 100%;
  background-repeat:no-repeat;
  background-size:0% 1px;
  padding-bottom:1px;
  transition:background-size var(--dur-micro) var(--ease-out),color var(--dur-micro) var(--ease-out);
}
p.body a:hover,p.direct a:hover,p.philosophy a:hover,.cta-note a:hover,.brow dd a:hover{
  background-size:100% 1px;
}
/* Hover lift uses box-shadow + border-color rather than transform, since
   transform is already owned by the reveal system above (fade + rise) —
   sharing one transition on the same property would force both effects
   onto a single duration/easing. Keeping them on separate properties lets
   each stay on its own motion timing without one silently overriding
   the other. */
.team-grid .team-card{
  transition:border-color var(--dur-fast) var(--ease-out),
             box-shadow var(--dur-fast) var(--ease-out);
}
.team-grid .team-card:hover{
  border-color:var(--accent);
  box-shadow:0 10px 24px -18px rgba(22,24,26,.45);
}
@media (prefers-reduced-motion:reduce){
  .team-grid .team-card{transition:none}
}

/* ── scroll reveal: fade + rise, staggered, once ─────────────
   Progressively enhanced: [data-reveal] content is visible by default
   so it can never be stuck invisible if JavaScript fails to load or
   run. Only once nav.js has added the "js" class to <html> — meaning
   the IntersectionObserver reveal logic is actually wired up — does
   this content start hidden, to be revealed on scroll. Respects
   prefers-reduced-motion below regardless of the "js" class. */
[data-reveal]{opacity:1;transform:none}
.js [data-reveal]{
  opacity:0;
  transform:translateY(var(--reveal-rise));
  transition:opacity var(--dur-reveal) var(--ease-out),
             transform var(--dur-reveal) var(--ease-out);
  transition-delay:calc(var(--reveal-i, 0) * var(--reveal-stagger));
}
.js [data-reveal].in{opacity:1;transform:translateY(0)}
@media (prefers-reduced-motion:reduce){
  [data-reveal],.js [data-reveal],.js [data-reveal].in{
    opacity:1;transform:none;transition:none}
}
