/* ============================================================
   THE LOADER — the reference's mechanism, on this site's paper.

   WHAT THE REFERENCE ACTUALLY SHOWS. Its loader is one container holding
   sixteen identically-classed images, a separate element carrying the
   percentage, and a 56px spinner. Sixteen images stacked in one box with a
   progress readout beside them is a flipbook: one is up at a time and the
   count advances with the load. Every one of those images also carries the
   same data-flip-id as a single grid item, so when the count reaches the
   end the loader hands off into the grid rather than simply vanishing.

   WHAT A STATIC DUMP CANNOT SAY: the per-frame timing, and whether the
   frames cut or cross-fade. They cut here. A cross-fade between two cut-out
   objects on white would read as a smear, and at a frame every eightieth of
   the load there is no time for one to resolve anyway.

   WHITE, ON A BLACK PAGE, BECAUSE IT WAS ASKED FOR. The plane behind it is
   pinned black, so this sets its own paper and ink rather than reading the
   world — and the hand-off is a fade, which crosses the two grounds in one
   move instead of flashing between them.

   IT RUNS ON EVERY ARRIVAL, not once a session. The reference is a single
   document with its content swapped underneath it, so its loader sits
   inside every page change; this site is separate files, and loader.js
   catches a link before it navigates so the join is covered from both
   sides. A rule that hid it on a repeat visit would break exactly the
   moment it is most wanted — going back to the main page.
   ============================================================ */
.cg-load{
  /* the visitor's own light or dark, not a white flash in front of a black
     page (22 September 2026) */
  --paper:var(--ground);
  --mark:var(--ink);
  --quiet:var(--soft);

  position:fixed; inset:0; z-index:300;
  background:var(--paper); color:var(--mark);
  display:flex; flex-direction:column; align-items:center; justify-content:center;
  gap:var(--s4);
  /* it is furniture in front of the page, and nothing in it is reachable */
  cursor:default; user-select:none;
  transition:opacity var(--speed-slow) var(--power3-out),
             visibility var(--speed-slow) var(--power3-out);
}
/* GONE, NOT JUST TRANSPARENT. visibility follows opacity so the finished
   loader stops taking the pointer, and display:none once it has faded means
   twelve decoded PNGs stop costing anything. */
.cg-load.is-done{opacity:0; visibility:hidden}
.cg-load.is-gone{display:none}

/* --- the wordmark, where the reference puts its title --- */
.cg-load_mark{
  position:absolute; left:50%; top:var(--s3); translate:-50% 0;
  margin:0; font-family:var(--face); font-weight:700;
  
  font-size:1.7rem; letter-spacing:-0.01em; line-height:1;
  text-transform:uppercase;
}

/* --- the flipbook ---
   One box, twelve images stacked in it, one visible at a time. The box is
   sized once and holds its size, so a tall object following a wide one does
   not make the whole screen jump. */
.cg-load_stack{
  position:relative; flex:none;
  width:min(38vw, 34vh); height:min(38vw, 34vh);
}
.cg-load_item{
  position:absolute; inset:0; margin:auto;
  max-width:100%; max-height:100%;
  width:auto; height:auto; object-fit:contain;
  opacity:0;
}
.cg-load_item.is-on{opacity:1}
/* --- the count, and the ring beside it --- */
.cg-load_foot{
  position:absolute; left:50%; bottom:var(--s4); translate:-50% 0;
  display:flex; align-items:center; gap:1.2rem;
}
.cg-load_pct{
  margin:0; font-family:var(--face-ui); font-variant-numeric:tabular-nums;
  font-size:1.3rem; letter-spacing:.16em; color:var(--spark);
  min-width:5ch; text-align:right;   /* the only number on the site that is counting — see --spark */
}
/* the reference keeps a small spinner beside its count; this is a ring with
   a quarter cut out of it, turning once a second */
.cg-load_ring{
  width:1.6rem; height:1.6rem; flex:none; border-radius:50%;
  border:1px solid color-mix(in srgb, var(--mark) 22%, var(--paper));
  /* the turning quarter, beside the counting figure — both alive, both spark */
  border-top-color:var(--spark);
  animation:cg-spin 1s linear infinite;
}
@keyframes cg-spin{to{transform:rotate(360deg)}}

@media (max-width:768px){
  .cg-load_stack{width:min(58vw, 34vh); height:min(58vw, 34vh)}
  .cg-load_mark{font-size:1.4rem}
}

/* Motion reduced: no spin, no flicker through twelve objects. One object
   stands still, the count still counts, and the hand-off is instant. */
@media (prefers-reduced-motion:reduce){
  .cg-load{transition:none}
  .cg-load_ring{animation:none}
}

/* THE TWO LINES, in the space either side of the drawing: the first above
   it, the second below, so the loader says what the site is while it counts
   (client, 22 September 2026). */
/* the two lines take the same place, one at a time */
.cg-load_says{display:grid; place-items:center}
.cg-load_says > .cg-load_line{
  grid-area:1/1; opacity:0; transform:translateY(.6rem);
  transition:opacity .5s var(--easing), transform .5s var(--power3-out);
}
.cg-load_says > .cg-load_line.is-on{opacity:1; transform:none}
.cg-load_line{
  margin:0; max-width:34rem; text-align:center;
  font-family:var(--face-ui); font-weight:600; line-height:1.15;
  font-size:clamp(1.8rem, 2.6vw, 2.8rem); letter-spacing:-0.02em;
  color:var(--mark);
}
@media (max-width:768px){
  .cg-load{gap:var(--s3)}
  .cg-load_line{font-size:clamp(1.7rem, 5.6vw, 2.4rem); max-width:30rem}
  .cg-load_stack{width:min(46vw, 26vh); height:min(46vw, 26vh)}
}
