/* ==========================================================================
   exe.cute v3 — the fixed chrome
   Two bars, the section readout, the layout guides, the position segment.

   The clone's header carries nine live instruments. v3 carries one, and it is
   re-subjected: haoqi's readout reports the pointer, exe.cute's reports the
   structure. No clock, no coordinates, no viewport panel, no theme or sound
   toggle — all rejected with reasons in docs/v3-direction.md.

   Geometry note: the guides and the segment share one source of truth. The two
   verticals sit on the real --gutter, the two horizontals on the two bars'
   inner baselines, so the overlay is the chrome's extension rather than
   floating decoration. js/ui/guides.js measures that geometry once per resize
   and publishes it as --guide-x0/--guide-x1/--guide-y0/--guide-y1; the segment
   below is positioned from those, with a pure-CSS fallback if guides.js fails.
   ========================================================================== */

/* --------------------------------------------------------------------------
   The two bars (z 50)
   -------------------------------------------------------------------------- */
.chrome {
  position: fixed;
  inset: 0;
  z-index: 50;
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  pointer-events: none;
  /* THE ENTRANCE. The chrome pops with the page reveal today — the only fixed layer that never
     transitions — so it reads as pre-existing furniture rather than as part of the page arriving.
     Both bars slide in from behind their own edge (top from above, bottom from below) while the
     readout and the contact link fade a beat later. js/ui/chrome.js adds .is-ready from pageReady,
     the same store the guides' .is-ready and the hero's .is-in already ride. Under no-JS nothing
     adds the class, so html:not(.js) forces the visible state — and .is-loading's visibility
     still covers the pre-reveal window, so there is no flash of the bars mid-flight. */
  --chrome-slide: calc(var(--bar-h) + 16px);
}
/* only the two links are interactive — everything else lets the page through */
.chrome a { pointer-events: auto; }

.chrome__bar {
  flex: 0 0 auto;
  display: flex;
  align-items: center;
  justify-content: space-between;
  height: var(--bar-h);
  padding: 0 var(--gutter);
  opacity: 0;
  transform: translateY(calc(var(--chrome-slide) * var(--bar-dir, -1)));
  transition: opacity 700ms var(--ease-out), transform 900ms var(--ease-out);
}
.chrome__bar--top { --bar-dir: -1; }
.chrome__bar--bottom { --bar-dir: 1; }
.chrome.is-ready .chrome__bar {
  opacity: 1;
  transform: translateY(0);
}
/* The two link labels come in a beat after their bars, so the entrance reads as layers resolving
   rather than as one block dropped in. The bars themselves carry the glass plate — sliding the
   plate first is what makes it read as a bar arriving. */
.chrome .chrome__brand,
.chrome .chrome__link {
  opacity: 0;
  transition: opacity 600ms var(--ease-out) 250ms;
}
.chrome.is-ready .chrome__brand,
.chrome.is-ready .chrome__link {
  opacity: 1;
}
/* The readout rides the bottom bar's own entrance — no separate delay, it IS the instrument. */
@media (prefers-reduced-motion: reduce) {
  .chrome__bar,
  .chrome .chrome__brand,
  .chrome .chrome__link { transition: none; }
}

/* The top bar is a plane, not a transparent strip.
   The hero's type is left-aligned now, and so is the wordmark sitting in this bar. The only thing
   keeping them apart was a clip written from the frame loop — and ui/hero.js returns before that
   loop under prefers-reduced-motion, so in exactly the state a reader asks for calm, the headline
   printed straight through the logo: measured 5,103px of hero ink inside .chrome__brand across 60
   samples at five viewports, worst 328px = 14.87% of the first line at 390x844. With the plate,
   0px on both chrome runs across 328 element-rows at 8 viewports, in all three states.

   Written this way round on purpose: the class TAKES the plane away, so the plane is what you get
   when ui/chrome.js never runs, when #segment is missing, or when scripting is off entirely.

   The cost is real and it is page-wide, not hero-local: outside the two text boxes this replaces
   the silk field inside the strip — 80.9% of pixels change at the top of the hero — and it covers
   the top row of the accent dot at each upper guide crossing. The bottom bar is deliberately NOT
   plated: every measured collision is with this one. */
/* The plate lives on its OWN layer (the ::before) and its appearing is an OPACITY ramp, not a
   background-color swap. The old form transitioned background-color while backdrop-filter flipped
   none <-> blur — and backdrop-filter is DISCRETE: it cannot interpolate, so the glass material
   popped in in a single frame no matter how long the colour ramp ran. With the filter permanently
   on the pseudo-element and only its opacity animating, the whole plate — tint AND blur — fades
   as one continuous 380ms ramp. The pseudo keeps the bar's own box (inset:0) so the plate still
   ends exactly where the bar does. */
.chrome__bar--top::before {
  content: "";
  position: absolute;
  inset: 0;
  background: rgba(11, 11, 13, 0.82);
  -webkit-backdrop-filter: blur(16px) saturate(1.35);
  backdrop-filter: blur(16px) saturate(1.35);
  opacity: 1;
  transition: opacity 380ms var(--ease-out);
  z-index: -1;                         /* behind the bar's own content, which is statically positioned */
}
html.at-top .chrome__bar--top::before { opacity: 0; }
@media (prefers-reduced-motion: reduce) {
  .chrome__bar--top::before { transition: none; }
}
/* The bar needs its own stacking context so the pseudo's z-index:-1 cannot fall behind the PAGE
   (a negative z-index child escapes to the nearest stacking context, and .chrome is fixed with no
   z-index of its own beyond the one on #chrome). */
.chrome__bar--top { position: relative; z-index: 0; }

/* ---- brand (v2's values, carried over) ---- */
.chrome__brand {
  display: inline-flex;
  align-items: center;
  line-height: 0;
}
.chrome__logo {
  height: clamp(18px, 1.6vw, 22px);
  width: auto;
  display: block;
  transition: opacity 0.4s var(--ease-out);
}

/* ---- contact link ---- */
.chrome__link {
  display: inline-flex;
  align-items: center;
  gap: 0.5em;
  font-family: var(--font-mono);
  font-weight: 300;
  font-size: 0.78rem;
  letter-spacing: 0.04em;
  text-transform: lowercase;
  color: var(--bone-70);
  transition: color 0.4s var(--ease-out);
}
.chrome__arrow {
  display: inline-block;
  transition: transform 0.5s var(--ease-out);
}
@media (hover: hover) {
  .chrome__brand:hover .chrome__logo { opacity: 0.75; }
  .chrome__link:hover { color: var(--bone); }
  .chrome__link:hover .chrome__arrow { transform: translateX(4px); }
}

/* ---- the one instrument: the section readout ---- */
.chrome__readout {
  font-family: var(--font-mono);
  font-weight: 300;
  font-size: 0.74rem;
  letter-spacing: 0.06em;
  text-transform: lowercase;
  color: var(--bone-70);           /* 8.27:1. See the note on .section__meta in base.css. */
  white-space: nowrap;
}
/* The readout's static screen-reader copy is now .sr-only in base.css, created by
   core/scramble.js for every scrambling element rather than by this one module for this one. */

/* --------------------------------------------------------------------------
   The position segment — the clone's draggable scroll rail, subtracted.
   A 24px --bone tick sliding down the right-hand vertical guide between the
   two horizontals as scroll.progress goes 0 -> 1. Not draggable, not a
   control: js/ui/chrome.js writes --seg-p and toggles .is-active only.
   -------------------------------------------------------------------------- */
.chrome__segment {
  position: absolute;
  left: var(--guide-x1, calc(100% - var(--gutter)));
  top: var(--guide-y0, var(--bar-h));
  width: 1px;
  height: 24px;
  background: var(--bone);
  opacity: 0;
  pointer-events: none;
  transform: translateY(calc(
    (var(--guide-y1, calc(100vh - var(--bar-h))) - var(--guide-y0, var(--bar-h)) - 24px)
    * var(--seg-p, 0)
  ));
  transition: opacity 0.5s var(--ease-std);
}
.chrome__segment.is-active { opacity: 1; }

/* --------------------------------------------------------------------------
   The layout guides (z 25) — measurement host, no rendering.
   The grid overlay this container used to draw is retired: js/ui/guides.js now
   publishes only the geometry (--guide-*, --type-col), read from the probe
   below. Nothing paints inside #guides.
   -------------------------------------------------------------------------- */
.guides {
  position: fixed;
  inset: 0;
  z-index: 25;
  pointer-events: none;
}

/* Measured, never painted: gives guides.js the resolved px value of --gutter
   and --bar-h without re-implementing their clamp() in JS. */
.guides__probe {
  position: absolute;
  top: 0;
  left: 0;
  width: var(--gutter);
  height: var(--bar-h);
  visibility: hidden;
  pointer-events: none;
}

/* --------------------------------------------------------------------------
   Reduced motion — the chrome is static type and static lines either way, so
   only the transitions stop. The segment still tracks scroll position, which
   is a readout of where you are, not an animation.
   -------------------------------------------------------------------------- */
@media (prefers-reduced-motion: reduce) {
  .chrome__logo,
  .chrome__link,
  .chrome__arrow,
  .chrome__segment {
    transition: none;
  }
}

/* No JS: nothing will ever add .is-ready, so the chrome sits in its final, fully visible state. */
html:not(.js) .chrome__bar,
html:not(.js) .chrome .chrome__brand,
html:not(.js) .chrome .chrome__link {
  opacity: 1;
  transform: none;
}

/* --------------------------------------------------------------------------
   Narrow viewports: the bars keep their structure (one page, two links — the
   clone's fullscreen menu is rejected), the readout just gets quieter.
   -------------------------------------------------------------------------- */
@media (max-width: 560px) {
  .chrome__readout { font-size: 0.68rem; letter-spacing: 0.04em; }
  .chrome__link { font-size: 0.72rem; }
}
