/* ThreadSync — rotating hero boundaries + caption
   Scoped .sov:not(.sov-cichocki), which is the discriminator this codebase
   already uses (see sov-threadsync.css). NOT a new .sov-threadsync class:
   inventing a second convention for the same job is how the two sites drift.

   Palette is deliberately the inverse of cichocki's: emerald = inside/yours,
   cyan = the frontier/outside. Warm gold appears nowhere. */

/* ── HERO FADE-IN ────────────────────────────────────────────────────────
   The base frame used to appear instantly at first paint, which made the
   rotation feel like it started abruptly rather than opening. Fade the whole
   ambient up from black instead.

   The WHOLE ambient fades — artwork, wash and scrim together — which is safe
   for the same reason the section edge-fade is: while the artwork is faint
   there is nothing to protect the copy from, and what shows through is the
   hero's own near-black ground. Contrast is best at the start of the fade and
   arrives at its measured value by the end.

   `both` holds the final state so the image cannot flash back at any point.
   Deliberately shorter than the 1400ms crossfade: this is the curtain going
   up, not a transition between two frames. */
@keyframes caHeroFadeIn{ from{opacity:0} to{opacity:1} }

.sov:not(.sov-cichocki) .sov-hero-ambient{
  position:absolute;
  inset:0;
  animation:caHeroFadeIn 900ms ease-out both;
}

/* Someone who asked for less motion gets the image immediately, not a fade. */
@media (prefers-reduced-motion:reduce){
  .sov:not(.sov-cichocki) .sov-hero-ambient{animation:none !important;opacity:1 !important}
}

.sov:not(.sov-cichocki) .sov-hero-ambient .ca-rot{
  position:absolute;
  inset:0;
  z-index:0;
  opacity:0;
  pointer-events:none;
  background-image:var(--rot-wash), var(--rot-src, none);
  background-repeat:no-repeat,no-repeat;
  background-size:cover,cover;
  background-position:var(--rot-pos),var(--rot-pos);
  transition:opacity 1400ms ease-in-out;
  will-change:opacity;
}
.sov:not(.sov-cichocki) .sov-hero-ambient .ca-rot.is-on{opacity:1}

/* RETIRE THE ORIGINAL BASE IMAGE.
   The hero still carries .sov-hero--crossing, and sov-ambient-system.css sets
   --sov-ambient-src from that class to hero-wide-channels.webp. Removing the
   HTML reference did nothing, because the reference is in CSS — the base layer
   is what shows at first paint and between turns, so the retired image was
   still the first thing every visitor saw.

   Override it here rather than stripping the class: the class also drives the
   scrim shape and layout, so removing it would change more than the picture.
   Specificity (0,3,0) beats .sov-hero--crossing (0,1,0), and this sheet loads
   later, so the override wins on both counts. */
.sov:not(.sov-cichocki) .sov-hero-ambient{
  --sov-ambient-src:url("/assets/img/tsh-one-door-at-a-time-1600w.webp");
}

/* Declared on the host, consumed on the child — a custom property set in the
   same rule that uses it cannot be overridden by an ancestor, which is what
   silently disabled a scrim on the other site. */
.sov:not(.sov-cichocki) .sov-hero-ambient{
  --rot-pos:70% 48%;
  --rot-wash:linear-gradient(90deg,
    rgba(8,11,16,.52) 0%,
    rgba(8,11,16,.46) 52%,
    rgba(8,11,16,.16) 80%,
    rgba(8,11,16,0)   100%);
}

@media (max-width:900px){
  .sov:not(.sov-cichocki) .sov-hero-ambient{
    --rot-pos:64% 50%;
    --rot-wash:linear-gradient(180deg,
      rgba(8,11,16,.84) 0%,
      rgba(8,11,16,.62) 32%,
      rgba(8,11,16,.26) 58%,
      rgba(8,11,16,0)   88%);
  }
}

@media (prefers-reduced-motion:reduce){
  .sov:not(.sov-cichocki) .sov-hero-ambient .ca-rot{display:none !important;transition:none !important}
}
@media print{ .sov:not(.sov-cichocki) .sov-hero-ambient .ca-rot{display:none !important} }

/* ── caption ─────────────────────────────────────────────────────────────
   Same idea as cichocki's, cool instead of warm: the number is the handle for
   talking about a frame, the name is the mechanism, the line under it is the
   claim that mechanism makes. */
.sov:not(.sov-cichocki) .ca-rot-badge{
  position:absolute;
  top:18px; right:18px;
  z-index:3;
  width:min(296px,34vw);
  padding:11px 14px 12px;
  border-radius:12px;
  color:#E6EDF3;
  background:rgba(8,11,16,.80);
  border:1px solid rgba(52,211,153,.34);
  -webkit-backdrop-filter:blur(9px) saturate(115%);
  backdrop-filter:blur(9px) saturate(115%);
  pointer-events:none;
  box-shadow:0 10px 30px rgba(0,0,0,.38);
}
.sov:not(.sov-cichocki) .ca-rot-badge__head{display:flex;align-items:baseline;gap:3px;flex-wrap:wrap}
.sov:not(.sov-cichocki) .ca-rot-badge b{
  font-family:ui-monospace,SFMono-Regular,Menlo,monospace;
  font-size:17px;font-weight:700;line-height:1;color:#34D399;letter-spacing:.02em}
.sov:not(.sov-cichocki) .ca-rot-badge span{
  font-family:ui-monospace,SFMono-Regular,Menlo,monospace;
  font-size:11px;line-height:1;color:rgba(230,237,243,.45);margin-right:7px}
.sov:not(.sov-cichocki) .ca-rot-badge strong{
  font-size:12px;font-weight:600;line-height:1.2;letter-spacing:.07em;
  text-transform:uppercase;color:#E6EDF3}
.sov:not(.sov-cichocki) .ca-rot-badge p{
  margin:6px 0 0;font-size:12.5px;line-height:1.42;color:rgba(230,237,243,.80)}

@media (max-width:900px){
  .sov:not(.sov-cichocki) .ca-rot-badge{width:auto;right:12px;top:12px;padding:8px 11px}
  .sov:not(.sov-cichocki) .ca-rot-badge p{display:none}
  .sov:not(.sov-cichocki) .ca-rot-badge strong{font-size:11px}
}
@media (prefers-reduced-motion:reduce){ .sov:not(.sov-cichocki) .ca-rot-badge{display:none !important} }
@media print{ .sov:not(.sov-cichocki) .ca-rot-badge{display:none !important} }

/* pause control (WCAG 2.2.2) — bottom-left, clear of any fixed launcher */
.sov:not(.sov-cichocki) .ca-rot-toggle{
  position:absolute;left:24px;bottom:22px;z-index:3;
  width:36px;height:36px;display:inline-flex;align-items:center;justify-content:center;
  padding:0;border-radius:999px;cursor:pointer;
  color:rgba(230,237,243,.72);
  background:rgba(8,11,16,.62);
  border:1px solid rgba(52,211,153,.30);
  -webkit-backdrop-filter:blur(6px);backdrop-filter:blur(6px);
  transition:color .18s ease,border-color .18s ease,background-color .18s ease}
.sov:not(.sov-cichocki) .ca-rot-toggle svg{width:15px;height:15px;fill:currentColor;display:block}
.sov:not(.sov-cichocki) .ca-rot-toggle:hover{color:#34D399;border-color:rgba(52,211,153,.62);background:rgba(8,11,16,.80)}
.sov:not(.sov-cichocki) .ca-rot-toggle:focus-visible{outline:2px solid #34D399;outline-offset:3px;color:#34D399}
@media (max-width:720px){ .sov:not(.sov-cichocki) .ca-rot-toggle{left:16px;bottom:16px;width:40px;height:40px} }
@media print{ .sov:not(.sov-cichocki) .ca-rot-toggle{display:none !important} }

/* ── HERO NODE PANELS — opacity raised for the brighter artwork ──────────
   The gate found .sov-tag (10.5px) at a MEDIAN 3.55:1 against a 4.5 floor.
   Not an outlier: 3,269 glyph pixels measured, and the typical background —
   not the worst pixel — fails.

   Cause is this campaign, not the panels. They are ~50% opaque, which read as
   dark over the old hero image. The new boundary frames are far brighter
   (right-side luminance 54-132 where the old art sat much lower), so the
   composite behind the small emerald text lifted and contrast fell with it.

   Fix the ground, not the type: raising panel opacity restores the dark
   backing the type was designed for, and leaves the artwork visible around
   the panels where no text sits. */
.sov:not(.sov-cichocki) .sov-hero .sov-node{
  background:rgba(11,14,20,.88) !important;
}
.sov:not(.sov-cichocki) .sov-hero .sov-node.is-bridge{
  background:rgba(20,26,36,.88) !important;
}
.sov:not(.sov-cichocki) .sov-hero .sov-node.is-island{
  /* The first attempt started this gradient at rgba(16,185,129,.16) — 16%
     opaque at the TOP, which is precisely where the .sov-tag label sits. That
     made the background behind the small text MORE transparent, not less, and
     the measured median barely moved (3.55 -> 3.65). Keep the emerald cast but
     never drop below ~.92 alpha anywhere the label can sit. */
  background:linear-gradient(180deg,
    rgba(12,30,26,.94) 0%,
    rgba(11,20,22,.93) 45%,
    rgba(11,14,20,.92) 100%) !important;
}

/* The panel these nodes sit on is itself only 46% opaque, so it contributes
   very little. Give the whole diagram a solid enough ground that small text
   never depends on which frame happens to be behind it. */
.sov:not(.sov-cichocki) .sov-hero .sov-diagram{
  background:rgba(8,11,17,.86) !important;
}
