/* ==========================================================================
   Plek loader — the official loading indicator. Design System v6.
   Carried over UNCHANGED from v5.2 at the owner's request (2026-09-19): same
   geometry, same 2.6s cycle, same class names, same window.plekLoader API.
   Only the colors and the label's type moved to v6.

   THE ONE SANCTIONED LOOP. v6 bans looping animation everywhere else; this is
   the single exception, because a loader that does not repeat cannot say
   "still working". Nothing else in the system may loop, and nothing else may
   be used as a busy indicator (no spinners, no pulsing skeletons).
   --------------------------------------------------------------------------
   The Weave Mark builds itself thread by thread, each new thread cutting the
   one beneath; hold, fast fade, rebuild. 2.6s, pure CSS, no spinner.

   The geometry is the shipped mark, not a redraw: every rect below is the
   stroked path of assets/logo/plek-mark-v6.svg expressed as a
   percentage of the 64-unit viewBox (stroke-width 10, butt caps), so the
   final frame is pixel-identical to the SVG at any --plek-loader-size.

       H1  y 22, x  4→14 and 30→60   (gap 14–30, V1 crosses OVER)
       H2  y 42, x  4→34 and 50→60   (gap 34–50, V2 crosses OVER)
       V1  x 22, y  4→34 and 50→60   (gap 34–50, H2 crosses OVER)
       V2  x 42, y  4→14 and 30→60   (the blue signal strand; passes UNDER H1, so it ships as
                                      two segments and never crosses it)

   Every gap is 16 units for a 10-unit stroke, so the crossing thread clears
   the cut by 3 units on each side and no two threads ever overlap. The cuts
   are REAL — `clip-path` removes the notch, it is not painted over — so the
   loader sits on any ground, including a gradient.

   SELF-CONTAINED. This file is loaded by surfaces that may NOT load
   css/tokens.css (the sign-in page), so every value reads its v6 token with a
   literal fallback: it is on-system where the tokens exist and still correct
   where they do not.

   --------------------------------------------------------------------------
   USAGE

     <span class="plek-loader" role="status" aria-label="Loading">
       <span class="plek-loader__mark" aria-hidden="true">
         <i></i><i></i><i></i><i></i><i></i>
       </span>
     </span>

   With a visible eyebrow label — drop aria-label, the label IS the text:

     <span class="plek-loader" role="status">
       <span class="plek-loader__mark" aria-hidden="true">
         <i></i><i></i><i></i><i></i><i></i>
       </span>
       <span class="plek-loader__label">Verifying</span>
     </span>

   The five <i> are, in order: H1, V1, H2, V2-top segment, V2-bottom segment.

   CUSTOM PROPERTIES (set on .plek-loader)

     --plek-loader-size      mark box, default 32px
     --plek-loader-ink       --pk-charcoal  #27282A
     --plek-loader-signal    --pk-blue      #3C7EB3

   MODIFIERS

     .plek-loader--xs        16px mark — inside a busy button or a table cell
     .plek-loader--sm        24px mark
     .plek-loader--lg        48px mark
     .plek-loader--on-dark   dark-ground colors
     .plek-loader--block     centered column for a panel or an area being
                             loaded; holds a min-height so the panel does not
                             reflow when the loader is swapped for content

   MOTION

     One 2.6s infinite cycle. Threads draw in with `transform: scale` from
     their start edge; each cut opens with a `clip-path` polygon whose notch
     sweeps in the crossing thread's own direction. All elements share the
     duration and `linear` timing and bake their own schedule into their
     keyframes, so `animation-delay: -Xs` scrubs the whole composition.
     prefers-reduced-motion: reduce → no animation, the finished mark.
     Decorative motion is aria-hidden.

     0.00→1.40s  build   H1, V1, H2, V2 in sequence, each 0.35s
     1.40→2.10s  hold
     2.10→2.30s  fade
     2.30→2.60s  blank, then rebuild
   ========================================================================== */

.plek-loader {
  --plek-loader-size: 32px;
  --plek-loader-ink: var(--pk-charcoal, #27282A);
  --plek-loader-signal: var(--pk-blue, #3C7EB3);
  --plek-loader-duration: 2.6s;

  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 12px;
}

.plek-loader--xs { --plek-loader-size: 16px; gap: 8px; }
.plek-loader--sm { --plek-loader-size: 24px; }
.plek-loader--lg { --plek-loader-size: 48px; }

.plek-loader--on-dark {
  --plek-loader-ink: var(--pk-on-dark, #FFFFFF);
  --plek-loader-signal: var(--pk-sky, #ACC9E8);
}

.plek-loader--block {
  display: flex;
  flex-direction: column;
  gap: 16px;
  min-height: 160px;
  padding: 32px 24px;
  text-align: center;
}

/* ── The mark box: the 64-unit grid ───────────────────────────────────── */

.plek-loader__mark {
  position: relative;
  display: block;
  flex: none;
  width: var(--plek-loader-size, 32px);
  height: var(--plek-loader-size, 32px);
  animation: plek-loader-cycle var(--plek-loader-duration, 2.6s) linear infinite;
}

.plek-loader__mark > i {
  position: absolute;
  display: block;
  background: var(--plek-loader-ink, #27282A);
  animation-duration: var(--plek-loader-duration, 2.6s);
  animation-timing-function: linear;
  animation-iteration-count: infinite;
}

/* The cut polygons below trace: along the start edge to the notch, into the
   notch and back out, then on around the box. The notch depth is the only
   thing that animates; at depth 0 its four vertices lie flat on the start
   edge and the shape is the plain rectangle. */

/* H1 — box x 4→60, y 17→27. Notch x 14→30, swept downward by V1. */
.plek-loader__mark > i:nth-child(1) {
  left: 6.25%;            /*  4/64 */
  top: 26.5625%;          /* 17/64 */
  width: 87.5%;           /* 56/64 */
  height: 15.625%;        /* 10/64 */
  transform-origin: left center;
  clip-path: polygon(
    0% 0%, 17.857143% 0%, 17.857143% 100%, 46.428571% 100%,
    46.428571% 0%, 100% 0%, 100% 100%, 0% 100%);
  animation-name: plek-loader-h1-draw, plek-loader-h1-cut;
}

/* V1 — box x 17→27, y 4→60. Notch y 34→50, swept rightward by H2. */
.plek-loader__mark > i:nth-child(2) {
  left: 26.5625%;         /* 17/64 */
  top: 6.25%;             /*  4/64 */
  width: 15.625%;         /* 10/64 */
  height: 87.5%;          /* 56/64 */
  transform-origin: center top;
  clip-path: polygon(
    0% 0%, 0% 53.571429%, 100% 53.571429%, 100% 82.142857%,
    0% 82.142857%, 0% 100%, 100% 100%, 100% 0%);
  animation-name: plek-loader-v1-draw, plek-loader-v1-cut;
}

/* H2 — box x 4→60, y 37→47. Notch x 34→50, swept downward by V2. */
.plek-loader__mark > i:nth-child(3) {
  left: 6.25%;            /*  4/64 */
  top: 57.8125%;          /* 37/64 */
  width: 87.5%;           /* 56/64 */
  height: 15.625%;        /* 10/64 */
  transform-origin: left center;
  clip-path: polygon(
    0% 0%, 53.571429% 0%, 53.571429% 100%, 82.142857% 100%,
    82.142857% 0%, 100% 0%, 100% 100%, 0% 100%);
  animation-name: plek-loader-h2-draw, plek-loader-h2-cut;
}

/* V2 top segment — x 37→47, y 4→14 (teal). No cut: nothing crosses it. */
.plek-loader__mark > i:nth-child(4) {
  left: 57.8125%;         /* 37/64 */
  top: 6.25%;             /*  4/64 */
  width: 15.625%;         /* 10/64 */
  height: 15.625%;        /* 10/64 */
  background: var(--plek-loader-signal, #3C7EB3);
  transform-origin: center top;
  animation-name: plek-loader-v2a-draw;
}

/* V2 bottom segment — x 37→47, y 30→60 (teal). */
.plek-loader__mark > i:nth-child(5) {
  left: 57.8125%;         /* 37/64 */
  top: 46.875%;           /* 30/64 */
  width: 15.625%;         /* 10/64 */
  height: 46.875%;        /* 30/64 */
  background: var(--plek-loader-signal, #3C7EB3);
  transform-origin: center top;
  animation-name: plek-loader-v2b-draw;
}

/* ── The eyebrow label ────────────────────────────────────────────────── */

.plek-loader__label {
  /* v6: the label is a Space Mono caption, sentence case — the v5 eyebrow was
     uppercase Inter tracked 0.3em, which is not a v6 voice. */
  font-family: var(--pk-font-mono, 'Space Mono', ui-monospace, monospace);
  font-size: var(--pk-fs-caption, 12px);
  font-weight: 400;
  letter-spacing: var(--pk-ls-body, -0.04em);
  line-height: var(--pk-lh-tight, 1.2);
  color: var(--pk-muted, #6B6B6B);
}

.plek-loader--block .plek-loader__label { margin-right: 0; }
.plek-loader--on-dark .plek-loader__label { color: var(--pk-on-dark-2, #DADADA); }

/* ── The cycle ────────────────────────────────────────────────────────────
   2.6s. Percentages: 0.35s = 13.46%, 1.40s = 53.85%, 2.10s = 80.77%,
   2.30s = 88.46%. Every element runs the full 2.6s; its own window is baked
   into its keyframes, which is what lets a single negative animation-delay
   scrub the whole composition.
   ------------------------------------------------------------------------ */

@keyframes plek-loader-cycle {
  0%, 80.77%   { opacity: 1; }
  88.46%, 100% { opacity: 0; }
}

/* ── Draw-in ──────────────────────────────────────────────────────────── */

/* H1 — left→right, 0.00→0.35s */
@keyframes plek-loader-h1-draw {
  0%     { transform: scaleX(0); }
  13.46% { transform: scaleX(1); }
  100%   { transform: scaleX(1); }
}
/* V1 — top→bottom, 0.35→0.70s */
@keyframes plek-loader-v1-draw {
  0%, 13.46% { transform: scaleY(0); }
  26.92%     { transform: scaleY(1); }
  100%       { transform: scaleY(1); }
}
/* H2 — left→right, 0.70→1.05s */
@keyframes plek-loader-h2-draw {
  0%, 26.92% { transform: scaleX(0); }
  40.38%     { transform: scaleX(1); }
  100%       { transform: scaleX(1); }
}
/* V2 — one descent, 1.05→1.40s, y 4 → y 60. The top segment lands at y 14
   (42.79%); y 14→30 is the pass UNDER H1, drawn by nothing; the bottom
   segment picks up at y 30 (46.63%) and runs to y 60 (53.85%). */
@keyframes plek-loader-v2a-draw {
  0%, 40.38% { transform: scaleY(0); }
  42.79%     { transform: scaleY(1); }
  100%       { transform: scaleY(1); }
}
@keyframes plek-loader-v2b-draw {
  0%, 46.63% { transform: scaleY(0); }
  53.85%     { transform: scaleY(1); }
  100%       { transform: scaleY(1); }
}

/* ── The cuts ─────────────────────────────────────────────────────────────
   Each notch opens exactly while the crossing thread's leading edge sweeps
   the thread beneath: V1 crosses H1's band at 16.58→18.99%, H2 crosses V1's
   at 30.04→32.45%, V2 crosses H2's at 48.31→50.72%.
   ------------------------------------------------------------------------ */

@keyframes plek-loader-h1-cut {          /* notch grows downward */
  0%, 16.58% {
    clip-path: polygon(
      0% 0%, 17.857143% 0%, 17.857143% 0%, 46.428571% 0%,
      46.428571% 0%, 100% 0%, 100% 100%, 0% 100%);
  }
  18.99%, 100% {
    clip-path: polygon(
      0% 0%, 17.857143% 0%, 17.857143% 100%, 46.428571% 100%,
      46.428571% 0%, 100% 0%, 100% 100%, 0% 100%);
  }
}

@keyframes plek-loader-v1-cut {          /* notch grows rightward */
  0%, 30.04% {
    clip-path: polygon(
      0% 0%, 0% 53.571429%, 0% 53.571429%, 0% 82.142857%,
      0% 82.142857%, 0% 100%, 100% 100%, 100% 0%);
  }
  32.45%, 100% {
    clip-path: polygon(
      0% 0%, 0% 53.571429%, 100% 53.571429%, 100% 82.142857%,
      0% 82.142857%, 0% 100%, 100% 100%, 100% 0%);
  }
}

@keyframes plek-loader-h2-cut {          /* notch grows downward */
  0%, 48.31% {
    clip-path: polygon(
      0% 0%, 53.571429% 0%, 53.571429% 0%, 82.142857% 0%,
      82.142857% 0%, 100% 0%, 100% 100%, 0% 100%);
  }
  50.72%, 100% {
    clip-path: polygon(
      0% 0%, 53.571429% 0%, 53.571429% 100%, 82.142857% 100%,
      82.142857% 0%, 100% 0%, 100% 100%, 0% 100%);
  }
}

/* ── Reduced motion: the finished mark, held ──────────────────────────── */

@media (prefers-reduced-motion: reduce) {
  .plek-loader__mark,
  .plek-loader__mark > i {
    animation: none;
  }
}
