/* ===========================================================================
 * RETICLE LOCK-ON — strip targeting frame + sticky HUD rails
 *
 * A game-style targeting frame spanning the full width of each strip.
 * There are NO static corner brackets: the frame's arms all live on two
 * sticky rails (top/bottom), which js/reticle.js lifts per-frame while a
 * section is open so they ride the viewport edges and dock onto the
 * section edges at the extremes.
 *
 *   - Rest (collapsed): faint corner ticks + section index.
 *   - Hover (collapsed): arms assemble to full length + brighten, and a
 *     "click to expand" prompt fades in.
 *   - Open: rails ride the viewport. Horizontal arms travel with them;
 *     VERTICAL arms draw on as a rail nears its dock — far end anchored
 *     one arm-length in from the section edge, near end glued to the
 *     rail — so each corner "completes" exactly at dock. The bottom-left
 *     horizontal arm doubles as the scroll-progress bar (stroke draw =
 *     scroll progress, "%" label riding its right end).
 *
 * State classes maintained by js/reticle.js for scroll-triggered HUD
 * features (pure-CSS show/hide for anything new):
 *   .strip-reticle--stuck-top     — scrolled past the section top
 *   .strip-reticle--stuck-bottom  — section end below the viewport
 *
 * Rail lifts and label rides are transform/opacity (compositor-only).
 * Arms are hand-drawn SVG strokes whose length animates via
 * stroke-dashoffset (paint-level, but tiny elements — see the arms
 * section). All scroll-driven per-frame JS writes must NOT have
 * transitions while active (see the `.active` transition:none rules).
 * Geometry is px, shared with js/reticle.js (INSET/ARM) — keep in sync.
 * ===========================================================================
 */

/* All geometry/style knobs are custom properties, live-tuned from the F6
   debug panel (js/reticle.js applyReticleVars ← debug-configs/reticle.json).
   Fallbacks mirror the JSON defaults so the reticle is correct pre-load. */
.strip-reticle {
  position: absolute;
  inset: var(--reticle-inset, 14px);  /* when collapsed the strip box == the
                                  header row; when open it frames the whole
                                  section. */
  z-index: 2;                  /* above the strip backdrop + header content */
  pointer-events: none;        /* clicks fall through to the strip handler;
                                  interactive HUD children opt back in */
  opacity: var(--reticle-opacity-rest, 0.4);
  transition: opacity 0.35s ease;
}

/* --- Per-section color modes ---------------------------------------------- */
/* Picked by hand per strip via data-reticle on .accordion-strip, matched
   to that section's backdrop. Three modes:
     (none)                    — white ink/lines (the defaults below)
     data-reticle="black"      — dark ink/lines for light backdrops
     data-reticle="difference" — per-pixel inversion; needs FULL-strength
                                 white content (alpha grays the result),
                                 and the blend must sit on the ROOT —
                                 deeper elements are isolated groups
                                 (transformed rails) and would blend
                                 against nothing. */
.accordion-strip[data-reticle="black"] {
  --reticle-ink: #0a0a0a;
  --reticle-line: rgba(10, 10, 10, 0.9);
}
.accordion-strip[data-reticle="difference"] {
  --reticle-ink: #fff;
  --reticle-line: #fff;
}
.accordion-strip[data-reticle="difference"] .strip-reticle {
  mix-blend-mode: difference;
}

/* Touch/static path never shows it (all strips open, no hover). The module
   also no-ops on coarse pointers — this is belt-and-suspenders. */
body.accordion-static .strip-reticle {
  display: none;
}

/* Open section: persistent "locked" frame, calmer than hover. */
.accordion-strip.active .strip-reticle {
  opacity: var(--reticle-opacity-active, 0.7);
}

/* Hover — brighten (the assemble is the arms growing, below). Gated off
   while releasing: a mid-release strip is not a hover candidate — a
   cursor resting on it would hold the reticle at hover opacity, block
   the release fade, and the post-fade reset would then hard-hide it. */
.accordion-strip:not(.active):hover .strip-reticle:not(.strip-reticle--releasing) {
  opacity: 0.95;
}

/* --- Sticky HUD rails ----------------------------------------------------- */
/* Zero-height full-width lines at the reticle's top/bottom edges; children
   hang off them with absolute offsets. The per-frame translateY lift comes
   from js/reticle.js — NO transition on the rails (scroll-driven; a
   transition would make the HUD lag the scroll). A collapsing strip's
   HUD keeps this exact layout through the root opacity fade (one rule,
   see js/reticle.js releaseController): stuck rails hold their viewport
   pin, docked rails hold the section corners, and the whole frame fades
   out as one unit. Inline state is cleared only once invisible. */
.strip-reticle__rail {
  position: absolute;
  left: 0;
  right: 0;
  height: 0;
}
.strip-reticle__rail--top    { top: 0; }
.strip-reticle__rail--bottom { bottom: 0; }

/* --- Frame arms ------------------------------------------------------------ */
/* Each corner = one horizontal + one vertical arm, children of its rail.
   An arm is a tiny inline SVG (built by js/reticle.js) holding ONE
   hand-drawn wobbly path. Length animation is a stroke DRAW —
   stroke-dashoffset over pathLength=1, so offset = 1 − drawn fraction —
   never a scale: scaling would stretch the wobble, drawing reveals it
   and keeps the hand-drawn character at every length. Paths are
   authored to start at the arm's anchor (corner vertex for h, rail line
   for v); mirrored corners get static flip transforms so every arm
   draws outward from its anchor. NOTE: dashoffset is a paint-level
   property, not compositor — acceptable here because each arm is a
   ≤80px element repainted only on frames its value changes. */
.strip-reticle__arm {
  position: absolute;
  overflow: visible;          /* round caps + wobble poke past the box */
}
.strip-reticle__arm--h {
  width: var(--reticle-arm, 22px);
  height: 8px;
}
.strip-reticle__arm--v {
  width: 8px;
  height: var(--reticle-arm, 22px);
}

/* Center the 8px wobble band on the exact line the old 2px bars drew,
   so the corner geometry (and the JS dock math) is unchanged. */
.strip-reticle__rail--top    .strip-reticle__arm--h { top:    calc(var(--reticle-thickness, 2px) / 2 - 4px); }
.strip-reticle__rail--bottom .strip-reticle__arm--h { bottom: calc(var(--reticle-thickness, 2px) / 2 - 4px); }
.strip-reticle__rail--top    .strip-reticle__arm--v { top: 0; }
.strip-reticle__rail--bottom .strip-reticle__arm--v { bottom: 0; }

.strip-reticle__arm--tl, .strip-reticle__arm--bl { left: 0; }
.strip-reticle__arm--tr, .strip-reticle__arm--br { right: 0; }
.strip-reticle__arm--v.strip-reticle__arm--tl,
.strip-reticle__arm--v.strip-reticle__arm--bl { left:  calc(var(--reticle-thickness, 2px) / 2 - 4px); }
.strip-reticle__arm--v.strip-reticle__arm--tr,
.strip-reticle__arm--v.strip-reticle__arm--br { right: calc(var(--reticle-thickness, 2px) / 2 - 4px); }

/* Draw direction: flips put every path's start on its anchor — corner
   vertex (h) / rail line (v). Static, never animated. */
.strip-reticle__arm--h.strip-reticle__arm--tr,
.strip-reticle__arm--h.strip-reticle__arm--br { transform: scaleX(-1); }
.strip-reticle__rail--bottom .strip-reticle__arm--v { transform: scaleY(-1); }

/* The stroke. dasharray + pathLength=1 normalizes the draw; rest state
   = a short tick drawn from the anchor. The gap is 2 (not 1): with a
   1/1 pattern the fully-hidden state (offset 1) puts the NEXT dash's
   start exactly on the path end, which round linecaps render as a
   phantom dot; the longer gap keeps that boundary off the path. */
.strip-reticle__arm path {
  fill: none;
  stroke: var(--reticle-line, rgba(240, 240, 240, 0.85));
  stroke-width: var(--reticle-thickness, 2px);
  stroke-linecap: round;
  stroke-dasharray: 1 2;
  stroke-dashoffset: calc(1 - var(--reticle-tick, 0.35));
  transition: stroke-dashoffset 0.35s ease;   /* rest ↔ hover assemble */
}

/* Hover (collapsed) = arms draw out to full length. */
.accordion-strip:not(.active):hover .strip-reticle__arm path { stroke-dashoffset: 0; }

/* Open section: js/reticle.js drives the draw per frame — transitions off
   so the writes track the scroll 1:1. The CSS values below are the
   correct first-frame state at the moment of expand (top rail docks at
   the viewport top → full v-arms; bottom rail is far below → none);
   inline JS values take over from the next tick. The bottom-left h-arm
   (progress line) also gets its dashoffset inline from JS — inline wins
   over the 0 here, which is what the other three h-arms use. */
.accordion-strip.active .strip-reticle__arm path { transition: none; }
.accordion-strip.active .strip-reticle__arm--h path { stroke-dashoffset: 0; }
.accordion-strip.active .strip-reticle__rail--top    .strip-reticle__arm--v path { stroke-dashoffset: 0; }
.accordion-strip.active .strip-reticle__rail--bottom .strip-reticle__arm--v path { stroke-dashoffset: 1; }

/* --- Shared HUD label treatment ------------------------------------------ */
.strip-reticle__index,
.strip-reticle__prompt,
.strip-reticle__totop,
.strip-reticle__title,
.strip-reticle__progress {
  font-family: "Patrick Hand", cursive;
  font-size: var(--reticle-font, 11px);
  line-height: 1;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--reticle-ink, #fff);
  white-space: nowrap;
  transition: opacity 0.35s ease;
}

/* Label slots sit one arm-length + gap in from an edge, so they always
   clear the corner arms whatever the tuned geometry. Left slots anchor
   with left:, right slots with right:. */

/* Section index, "n / total", BOTTOM-RIGHT. Visible whenever the reticle
   is (its opacity gates it — 0 at rest by default). */
.strip-reticle__index {
  position: absolute;
  bottom: -3px;
  right: calc(var(--reticle-arm, 22px) + var(--reticle-label-gap, 6px));
  opacity: 0.85;
}

/* --- Scroll-to-top affordances (top rail) -------------------------------- */
/* Two ways to return to the section top, one at each end of the top rail:
   the section TITLE (top-left) and an explicit "scroll to top" (top-right).
   Both are real buttons (keyboard/AT reachable) and appear only once the
   section top is scrolled past (--stuck-top) — exactly when they're useful;
   visibility gating also keeps them out of the tab order while hidden. */
.strip-reticle__title,
.strip-reticle__totop {
  position: absolute;
  top: -3px;
  background: none;
  border: 0;
  padding: 0;
  pointer-events: auto;        /* opt back in — the root is pe:none */
  opacity: 0;
  visibility: hidden;
  transition: opacity 0.35s ease, visibility 0.35s ease;
}
.strip-reticle__title  { left:  calc(var(--reticle-arm, 22px) + var(--reticle-label-gap, 6px)); }
.strip-reticle__totop  { right: calc(var(--reticle-arm, 22px) + var(--reticle-label-gap, 6px)); }
.strip-reticle--stuck-top .strip-reticle__title,
.strip-reticle--stuck-top .strip-reticle__totop {
  opacity: 0.9;
  visibility: visible;
}
.strip-reticle__title:hover,
.strip-reticle__totop:hover { opacity: 1; }

/* "Click to expand", bottom-left, revealed on hover of a COLLAPSED strip
   only — the progress readout takes this slot while open. */
.strip-reticle__prompt {
  position: absolute;
  bottom: -3px;
  left: calc(var(--reticle-arm, 22px) + var(--reticle-label-gap, 6px));
  opacity: 0;
}
.accordion-strip:not(.active):hover
  .strip-reticle:not(.strip-reticle--releasing) .strip-reticle__prompt { opacity: 0.9; }

/* --- Scroll-progress labels (bottom rail, open section only) ------------- */
/* The progress BAR is the bottom-left h-arm itself (stroke draw from
   JS). This label cluster rides the bar's right end: base left is the
   constant gap, js/reticle.js adds translateX(bar length). At 100% that
   lands at 6 + 22 = 28px — the standard label slot. */
.strip-reticle__progress {
  position: absolute;
  left: var(--reticle-label-gap, 6px);
  bottom: -3px;
  opacity: 0;
}
.accordion-strip.active .strip-reticle__progress {
  opacity: 0.85;
}

/* --- Reduced motion ----------------------------------------------------- */
/* No assemble transition on the arms (they sit full-length on collapsed
   strips); label fades become opacity-only. The rail/arm/progress writes
   while open are scroll position tracking, not decorative motion, so
   they stay. */
@media (prefers-reduced-motion: reduce) {
  .strip-reticle { transition: opacity 0.2s ease; }
  /* Fully drawn at rest, no assemble animation. The .active rules above
     are more specific and still control the open-section draw states. */
  .strip-reticle__arm path { transition: none; stroke-dashoffset: 0; }
}
