/* ------------------------------------------------------------------
   base.css — shared by the home page and every markdown page.

   Everything in here is common ground: design tokens, the reset, the
   ambient background layer, the two fixed controls, and scroll-entry
   motion. Page-specific layout lives in home.css / reader.css.
   ------------------------------------------------------------------ */

:root{
  color-scheme:light;
  --canvas:#F7F6F3;
  --surface:#FFFFFF;
  --border:#EAEAEA;
  --border-strong:#DCDCDA;
  --ink:#111111;
  --ink-soft:#2F3437;
  --muted:#787774;
  --code-bg:#F1F0EC;
  --rule-line:rgba(0,0,0,.055);
  --link-underline:#C9C9C6;
  --pale-green:#EDF3EC;     --pale-green-ink:#346538;
  --pale-yellow:#FBF3DB;    --pale-yellow-ink:#956400;
  --pale-blue:#E1F3FE;      --pale-blue-ink:#1F6C9F;
  --pale-red:#FDEBEC;       --pale-red-ink:#9F2F2D;
  --blob-a:#C9A227;
  --blob-b:#6B7F9E;
  --blob-opacity:.035;
  --card-shadow:0 2px 8px rgba(0,0,0,.04);
  --sans:'SF Pro Display','Geist Sans','Helvetica Neue',Helvetica,Arial,sans-serif;
  --serif:'Lyon Text','Newsreader','Instrument Serif','Playfair Display',Georgia,'Times New Roman',serif;
  --mono:'Geist Mono','SF Mono','JetBrains Mono',ui-monospace,Menlo,Consolas,monospace;
  --ease:cubic-bezier(0.16,1,0.3,1);
}

/* dark: warm charcoal rather than black, off-white rather than white,
   and the same pastels pulled down to low-chroma equivalents */
:root[data-theme="dark"]{
  color-scheme:dark;
  --canvas:#171715;
  --surface:#1E1D1B;
  --border:#2C2A27;
  --border-strong:#3A3835;
  --ink:#F2F1EE;
  --ink-soft:#D2D0CA;
  --muted:#8A8781;
  --code-bg:#232220;
  --rule-line:rgba(255,255,255,.05);
  --link-underline:#514E49;
  --pale-green:#1D2A1F;     --pale-green-ink:#93BE97;
  --pale-yellow:#2B2517;    --pale-yellow-ink:#D3B26C;
  --pale-blue:#17262F;      --pale-blue-ink:#8FBEDB;
  --pale-red:#2D1D1E;       --pale-red-ink:#D69B99;
  --blob-opacity:.07;
  /* a diffuse black shadow is invisible on charcoal — deepen it so the
     hover lift still reads, and let the border carry most of the change */
  --card-shadow:0 2px 12px rgba(0,0,0,.42);
}

*,*::before,*::after{box-sizing:border-box}
html{
  -webkit-text-size-adjust:100%;
  overflow-x:clip;
}
body{
  margin:0;
  /* stop scroll anchoring from yanking position when the ambient layer
     repaints, and stop chaining / pull-to-refresh at either end */
  overflow-x:clip;
  overflow-anchor:none;
  overscroll-behavior-y:none;
  background:var(--canvas);
  color:var(--ink-soft);
  font-family:var(--sans);
  font-size:16px;
  line-height:1.6;
  -webkit-font-smoothing:antialiased;
}

/* ---------- ambient depth ---------- */
/* fixed, never on a scrolling container. sized from vw only: vh/vmax
   change every time a mobile URL bar hides or shows, which resizes
   these mid-scroll and flickers. */
.ambient{
  --blob:min(72vw,640px);
  position:fixed;
  inset:0;
  pointer-events:none;
  z-index:0;
  overflow:hidden;
  clip-path:inset(0);      /* iOS does not reliably clip transformed
                              children with overflow alone */
  contain:layout paint;
}
.ambient span{
  position:absolute;
  width:var(--blob);height:var(--blob);
  border-radius:50%;
  background:radial-gradient(circle at 50% 50%, var(--blob-a) 0%, transparent 62%);
  opacity:var(--blob-opacity);
  will-change:transform;
  animation:drift 34s var(--ease) infinite alternate;
}
.ambient span:nth-child(1){
  top:calc(var(--blob) * -.34);
  left:calc(var(--blob) * -.22);
}
.ambient span:nth-child(2){
  bottom:calc(var(--blob) * -.40);
  right:calc(var(--blob) * -.28);
  background:radial-gradient(circle at 50% 50%, var(--blob-b) 0%, transparent 62%);
  animation-duration:46s;animation-delay:-12s;
}
/* percentages resolve against the element's own box, not the viewport */
@keyframes drift{
  from{transform:translate3d(0,0,0) scale(1)}
  to{transform:translate3d(9%,7%,0) scale(1.12)}
}

/* touch devices: keep the depth, drop the continuous repaint */
@media (hover:none),(pointer:coarse),(max-width:760px){
  .ambient span{animation:none;will-change:auto}
}

/* ---------- theme control ---------- */
.theme{
  position:fixed;top:20px;right:20px;z-index:6;
  display:inline-flex;align-items:center;justify-content:center;
  width:32px;height:32px;padding:0;
  background:none;border:0;border-radius:6px;
  color:var(--muted);cursor:pointer;
  transition:color 200ms var(--ease),background-color 200ms var(--ease);
}
.theme:hover{color:var(--ink);background:var(--surface)}
.theme:focus-visible{outline:2px solid var(--ink);outline-offset:2px}
.theme svg{transition:transform 400ms var(--ease)}
:root[data-theme="dark"] .theme svg{transform:rotate(180deg)}

/* ---------- back to top ---------- */
/* deliberately faint: present once you have scrolled, but never competing
   with the content. visibility (not just opacity) so it also leaves the
   tab order while hidden. */
.to-top{
  position:fixed;bottom:20px;right:20px;z-index:6;
  display:inline-flex;align-items:center;justify-content:center;
  width:36px;height:36px;padding:0;
  background:none;border:0;border-radius:8px;
  color:var(--muted);cursor:pointer;
  opacity:0;visibility:hidden;transform:translateY(6px);
  transition:opacity 300ms var(--ease),transform 300ms var(--ease),
             color 200ms var(--ease),background-color 200ms var(--ease),
             visibility 0s linear 300ms;
}
.to-top.on{opacity:.28;visibility:visible;transform:none;transition-delay:0s}
.to-top.on:hover{opacity:1;color:var(--ink);background:var(--surface)}
.to-top:focus-visible{opacity:1;outline:2px solid var(--ink);outline-offset:2px}
.to-top:active{transform:scale(.94)}
@media (pointer:coarse){ .to-top{width:44px;height:44px;bottom:16px;right:16px} }

/* ---------- motion ---------- */
.reveal{
  opacity:0;
  transform:translateY(12px);
}
.reveal.in{
  opacity:1;
  transform:none;
  transition:opacity 600ms var(--ease), transform 600ms var(--ease);
  transition-delay:calc(var(--index,0) * 80ms);
}

/* stagger steps as classes rather than style="" attributes — the CSP
   forbids inline styles, and these are the only values ever used */
.d1{--index:1}
.d2{--index:2}
.d3{--index:3}
.d4{--index:4}
.d5{--index:5}

@media (prefers-reduced-motion:reduce){
  .reveal,.reveal.in{opacity:1;transform:none;transition:none}
  .ambient span{animation:none}
  .to-top{transition:none}
}
