/*
 * RAKT motion layer: scroll reveals and the animated diagrams.
 *
 * Two rules govern everything here.
 *
 * First, nothing is hidden unless JavaScript is running. Every hiding selector
 * is scoped to `html.rakt-motion`, a class motion.js sets on itself before the
 * first paint. If the script is blocked, fails to parse, or the browser has no
 * IntersectionObserver, no element ever receives an opacity of 0 and the page
 * reads exactly as it does today. Reveal-on-scroll implemented the other way
 * round, with the hidden state in the stylesheet and JS responsible for undoing
 * it, is the single most common way a marketing site ships a blank page.
 *
 * Second, motion is opt-out at the OS level. The reduced-motion block at the
 * foot neutralises transitions and animations rather than merely shortening
 * them, and it is written last so it wins on order alone.
 */

/* ─────────────────────────────────────────────────────────────
   Scroll reveal
   ───────────────────────────────────────────────────────────── */

html.rakt-motion .rakt-reveal {
  opacity: 0;
  transform: translateY(16px);
}

html.rakt-motion .rakt-reveal.is-in {
  opacity: 1;
  transform: none;
  /* Opacity and transform only. Both are compositor-driven, so a long list of
     revealing cards does not force layout on each frame. */
  transition:
    opacity 620ms cubic-bezier(0.22, 0.61, 0.36, 1),
    transform 620ms cubic-bezier(0.22, 0.61, 0.36, 1);
}

/* Staggered children. `--i` is set by motion.js on each child of a marked
   group; the cap keeps a twelve-card grid from taking a second and a half to
   finish, which reads as a slow page rather than a considered one. */
html.rakt-motion .rakt-reveal.is-in {
  transition-delay: calc(min(var(--i, 0), 6) * 70ms);
}

/* ─────────────────────────────────────────────────────────────
   Diagrams
   ───────────────────────────────────────────────────────────── */

.rakt-dgm {
  --dgm-ink: var(--rakt-ink, #0B1220);
  --dgm-body: var(--rakt-body, #475569);
  --dgm-muted: var(--rakt-muted, #64748B);
  --dgm-line: var(--rakt-line, #E3E8EF);
  --dgm-primary: var(--rakt-primary, #D0243C);
  --dgm-surface: var(--rakt-surface, #F7F9FC);
  --dgm-check: var(--rakt-check, #0F7B4F);
  --dgm-warn: var(--rakt-warning, #F4A623);

  width: 100%;
  margin: 0;
}

.rakt-dgm svg {
  display: block;
  width: 100%;
  height: auto;
  overflow: visible;
}

.rakt-dgm__cap {
  margin: 14px auto 0;
  max-width: 52rem;
  font-family: var(--rakt-font-primary, sans-serif);
  font-size: 0.84375rem;
  line-height: 1.5;
  color: var(--dgm-muted);
  text-align: center;
}

/* Typography inside the SVG.
 *
 * Set here rather than as presentation attributes so the diagram inherits the
 * site's font stack and honours a user font override.
 *
 * Painted with `currentColor` against an explicit `color`, never with a `fill`
 * of its own. Two reasons, and the second is the load-bearing one. It keeps the
 * diagram to colours the page already uses. And `fill` is invisible to anything
 * reading computed styles, so SVG text with a bare `fill` reports whatever
 * `color` it happened to inherit: the body grey, which is 30 RGB units from the
 * builder's ink and is not a colour these pages otherwise paint text in. That
 * showed up as a near-duplicate colour pair on every page carrying a diagram,
 * and the pair did not exist on screen.
 *
 * Sizes are viewBox units, not pixels. See the note on the mobile rule below for
 * what they resolve to. */
.rakt-dgm text {
  font-family: var(--rakt-font-primary, sans-serif);
  color: var(--dgm-ink);
  fill: currentColor;
}
.rakt-dgm .t-node   { font-size: 15px; font-weight: 600; letter-spacing: -0.01em; }
.rakt-dgm .t-sub    { font-size: 12.5px; font-weight: 500; color: var(--dgm-muted); }
.rakt-dgm .t-step   { font-size: 12px; font-weight: 700; letter-spacing: 0.08em; color: var(--dgm-primary); }
.rakt-dgm .t-day    { font-size: 12.5px; font-weight: 700; letter-spacing: 0.06em; color: var(--dgm-primary); }
.rakt-dgm .t-refuse { font-size: 14px; font-weight: 600; color: #9B1C2E; }

.rakt-dgm .n-box {
  fill: #FFFFFF;
  stroke: var(--dgm-line);
  stroke-width: 1;
}
.rakt-dgm .n-box--tint  { fill: var(--dgm-surface); }
.rakt-dgm .n-box--gate  { fill: #FDF2F4; stroke: #F3C6CE; }
.rakt-dgm .n-box--done  { fill: #F1F8F4; stroke: #C6E3D2; }

.rakt-dgm .n-link {
  fill: none;
  stroke: var(--dgm-line);
  stroke-width: 1.5;
  stroke-linecap: round;
}
.rakt-dgm .n-link--live { stroke: var(--dgm-primary); }
.rakt-dgm .n-link--dash { stroke-dasharray: 4 4; }

.rakt-dgm .n-dot { fill: var(--dgm-primary); }
.rakt-dgm .n-ico { fill: none; stroke: var(--dgm-primary); stroke-width: 1.6; stroke-linecap: round; stroke-linejoin: round; }

/* ── Animation: nodes ─────────────────────────────────────────
   Each animated part carries `--i`, its position in the sequence, and the
   diagram only starts once it is on screen. */

html.rakt-motion .rakt-dgm .a-node {
  opacity: 0;
  transform: translateY(8px) scale(0.985);
  transform-box: fill-box;
  transform-origin: center;
}
html.rakt-motion .rakt-dgm.is-in .a-node {
  animation: rakt-dgm-in 520ms cubic-bezier(0.22, 0.61, 0.36, 1) forwards;
  animation-delay: calc(var(--i, 0) * 150ms);
}

@keyframes rakt-dgm-in {
  from { opacity: 0; transform: translateY(8px) scale(0.985); }
  to   { opacity: 1; transform: none; }
}

/* ── Animation: connectors draw ───────────────────────────────
   `pathLength="1"` is set on the markup, so the dash figures are fractions of
   the path and one rule covers paths of any real length. */

html.rakt-motion .rakt-dgm .a-draw {
  stroke-dasharray: 1;
  stroke-dashoffset: 1;
}
html.rakt-motion .rakt-dgm.is-in .a-draw {
  animation: rakt-dgm-draw 420ms cubic-bezier(0.4, 0, 0.2, 1) forwards;
  animation-delay: calc(var(--i, 0) * 150ms + 260ms);
}

@keyframes rakt-dgm-draw {
  to { stroke-dashoffset: 0; }
}

/* ── Animation: the travelling segment ───────────────────────
   A short dash running the length of the flow once the chain has drawn, which
   is what makes a row of boxes read as a sequence with a direction.

   Done as a dash travelling along an overlaid copy of the connector rather than
   a dot on an `offset-path`: dash geometry is understood by every browser that
   renders SVG at all, where `offset-path: path()` would leave the dot parked at
   the origin wherever it is unsupported. */

html.rakt-motion .rakt-dgm .a-flow {
  opacity: 0;
  stroke-dasharray: 0.06 0.94;
  stroke-dashoffset: 1;
}
html.rakt-motion .rakt-dgm.is-in .a-flow {
  opacity: 1;
  animation: rakt-dgm-flow 2800ms linear var(--flow-delay, 1100ms) infinite;
}

@keyframes rakt-dgm-flow {
  from { stroke-dashoffset: 1; }
  to   { stroke-dashoffset: 0; }
}

/* ── Animation: the gate stamp ───────────────────────────────
   The refusal cross lands slightly late and with no bounce. A gate that springs
   playfully into place undercuts the thing it is illustrating. */

html.rakt-motion .rakt-dgm .a-stamp {
  opacity: 0;
  transform: scale(0.9);
  transform-box: fill-box;
  transform-origin: center;
}
html.rakt-motion .rakt-dgm.is-in .a-stamp {
  animation: rakt-dgm-stamp 340ms cubic-bezier(0.34, 1.2, 0.64, 1) forwards;
  animation-delay: calc(var(--i, 0) * 150ms + 340ms);
}

@keyframes rakt-dgm-stamp {
  to { opacity: 1; transform: none; }
}

/* Legibility floor, expressed as a width rather than a breakpoint.
 *
 * These are laid out in a 1000-unit viewBox and scale with the container, so a
 * font-size above is a fraction of the diagram's width and not a pixel
 * measurement. The label that goes illegible first is the 12-unit step eyebrow,
 * and the site holds text to 13.5px, so the diagram must never render narrower
 * than 13.5 / 12 x 1000, which is 1125px.
 *
 * `min-width` against the `width: 100%` above does that with no media query and
 * no magic breakpoint: above 1125px of container the diagram fills the space,
 * below it the figure scrolls instead of shrinking. Choosing a breakpoint
 * instead would have left every width between the phone and the desktop
 * rendering 8px labels, which is what a `max-width: 600px` version of this rule
 * actually did.
 *
 * Horizontal scroll is the honest trade. A seven-step flow chart cannot be read
 * on a 360px screen at any font size, and the figcaption underneath carries the
 * same explanation in prose, so a reader who never swipes still gets the point. */
.rakt-dgm--wide {
  overflow-x: auto;
  overflow-y: hidden;
  -webkit-overflow-scrolling: touch;
}
.rakt-dgm--wide > svg,
.rakt-dgm--wide .rakt-dgm__desktop {
  min-width: 1125px;
}

/* Mobile companion for diagrams that cannot shrink. Hidden on desktop; on a
   phone it replaces the sideways-scrolling SVG so the sequence is readable
   without a swipe. Built as an ol of real text, same visual language as the
   in-article step figures. Shared by every wide diagram via dgm(). */
.rakt-dgm__mobile,
.rakt-dgm__m-branch,
.rakt-dgm__m-leg {
  display: none;
}

@media (max-width: 767px) {
  .rakt-dgm--has-mobile {
    overflow: visible;
  }
  .rakt-dgm--has-mobile .rakt-dgm__desktop {
    display: none;
  }

  /* Left spine + cards. Centred chevrons in a 10px gap read as loose punctuation
     between full-width slabs; a rail keeps the sequence and lets the cards sit
     closer without looking stacked for no reason. */
  .rakt-dgm--has-mobile .rakt-dgm__mobile {
    display: flex;
    flex-direction: column;
    gap: 8px;
    margin: 0;
    padding: 2px 0 2px 18px;
    list-style: none;
    border-left: 2px solid var(--dgm-line);
  }
  .rakt-dgm__m-step {
    position: relative;
    margin: 0;
    padding: 12px 16px;
    background: #FFFFFF;
    border: 1px solid var(--dgm-line);
    border-radius: 10px;
  }
  .rakt-dgm__m-step::before {
    content: "";
    position: absolute;
    top: 50%;
    left: -23px; /* 18px pad + 2px rail, centred on the rail */
    width: 8px;
    height: 8px;
    margin-top: -4px;
    border-radius: 50%;
    background: var(--dgm-primary);
    box-shadow: 0 0 0 3px #FFFFFF;
  }
  .rakt-dgm__m-step--start {
    background: var(--dgm-surface);
  }
  .rakt-dgm__m-step--done {
    background: #F1F8F4;
    border-color: #C6E3D2;
  }
  .rakt-dgm__m-step--done::before {
    background: var(--dgm-check);
  }
  .rakt-dgm__m-step--gate {
    background: #FDF2F4;
    border-color: #F3C6CE;
  }
  .rakt-dgm__m-step--gate::before {
    background: #9B1C2E;
  }
  .rakt-dgm__m-eyebrow {
    display: block;
    margin-bottom: 4px;
    font-family: var(--rakt-font-primary, sans-serif);
    font-size: 0.6875rem;
    font-weight: 700;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    color: var(--dgm-primary);
  }
  .rakt-dgm__m-label {
    display: block;
    font-family: var(--rakt-font-primary, sans-serif);
    font-size: 0.9375rem;
    font-weight: 600;
    line-height: 1.35;
    letter-spacing: -0.01em;
    color: var(--dgm-ink);
    text-align: left;
  }
  .rakt-dgm__m-body {
    display: block;
    margin-top: 4px;
    font-family: var(--rakt-font-primary, sans-serif);
    font-size: 0.8125rem;
    font-weight: 500;
    line-height: 1.45;
    color: var(--dgm-body);
  }
  .rakt-dgm__m-outcome {
    display: block;
    margin-top: 6px;
    font-family: var(--rakt-font-primary, sans-serif);
    font-size: 0.75rem;
    font-weight: 600;
    letter-spacing: 0.01em;
  }
  .rakt-dgm__m-outcome--refuse {
    color: #9B1C2E;
  }
  .rakt-dgm__m-outcome--pass,
  .rakt-dgm__m-outcome--note {
    color: var(--dgm-check);
  }

  /* Same left edge as the step cards — prefix lives in the markup so each
     diagram can name its own origin (TTI Screening, the desk, …). */
  .rakt-dgm--has-mobile .rakt-dgm__m-branch {
    display: block;
    margin: 4px 0 0 18px;
    padding: 12px 16px;
    font-family: var(--rakt-font-primary, sans-serif);
    font-size: 0.8125rem;
    line-height: 1.5;
    color: var(--dgm-body);
    background: #FDF2F4;
    border: 1px dashed #F3C6CE;
    border-radius: 10px;
  }
  .rakt-dgm--has-mobile .rakt-dgm__m-branch--soft {
    background: var(--dgm-surface);
    border-color: var(--dgm-line);
    border-style: dashed;
  }
  .rakt-dgm__m-branch-from {
    font-weight: 600;
    color: var(--dgm-primary);
  }
  .rakt-dgm__m-branch-from::after {
    content: " ·";
  }

  /* Second leg under the main spine (eRaktKosh pull). Same rail language,
     separated by a short heading so the direction change is readable. */
  .rakt-dgm--has-mobile .rakt-dgm__m-leg {
    display: block;
    margin-top: 16px;
  }
  .rakt-dgm__m-leg-head {
    margin: 0 0 8px 18px;
    font-family: var(--rakt-font-primary, sans-serif);
    font-size: 0.75rem;
    font-weight: 600;
    line-height: 1.4;
    color: var(--dgm-body);
  }

  .rakt-dgm--has-mobile .rakt-dgm__cap {
    margin-top: 18px;
    text-align: left;
  }
}

/* ─────────────────────────────────────────────────────────────
   Reduced motion. Last, so it wins on order.
   ───────────────────────────────────────────────────────────── */

@media (prefers-reduced-motion: reduce) {
  html.rakt-motion .rakt-reveal,
  html.rakt-motion .rakt-reveal.is-in,
  html.rakt-motion .rakt-dgm .a-node,
  html.rakt-motion .rakt-dgm .a-draw,
  html.rakt-motion .rakt-dgm .a-stamp {
    opacity: 1;
    transform: none;
    stroke-dashoffset: 0;
    transition: none;
    animation: none;
  }
  /* The travelling segment is decorative and loops forever, so it is removed
     rather than stilled: a stopped dash mid-path just looks like a mistake. */
  html.rakt-motion .rakt-dgm .a-flow {
    display: none;
  }
}
