/* ============================================================
   Site 2.0: chrome
   Owned by P3. Two things live here:

   1. The masthead: two floating glass capsules, logo left, nav
      right. Fixed, always on top, legible over dark or bright
      film because the glass itself carries the contrast, not
      the frame beneath it.
   2. The journey: a vertical brand marker on the right edge that
      names the six legs of the flight and tracks the traveller
      between them as flight:progress fires.

   Neither reads scroll directly. The journey listens only to the
   flight:progress event dispatched by main.js.
   ============================================================ */

/* ---------- shared glass surface ---------- */

.mh-mark, .mh-nav, .mh-burger{
  background:var(--glass);
  border:1px solid var(--glass-line);
  box-shadow:var(--glass-cast), inset 0 1px 0 var(--glass-edge);
  backdrop-filter:blur(18px) saturate(1.5);
  -webkit-backdrop-filter:blur(18px) saturate(1.5);
}

/* ---------- masthead ---------- */

.masthead{
  position:fixed; inset:0 0 auto 0; z-index:500;
  height:var(--chrome-h);
  display:flex; align-items:center; justify-content:space-between;
  padding-inline:var(--gut);
  pointer-events:none; /* the band is a corridor, only its capsules catch input */
}
.masthead > *{ pointer-events:auto; }

.mh-mark{
  display:inline-flex; align-items:center;
  padding:.55rem 1.15rem;
  border-radius:100px;
  /* Much lighter than Site 2.0. The capsule is there to hold the mark off
     the film, not to be a component in its own right, and at .62 alpha it
     had become an opaque pill sitting on the picture. */
  background:rgba(255,253,250,.30);
  border:1px solid rgba(255,255,255,.42);
  backdrop-filter:blur(18px) saturate(1.2);
  -webkit-backdrop-filter:blur(18px) saturate(1.2);
  box-shadow:0 2px 10px rgba(10,26,47,.08);
}
.mh-mark img{ width:clamp(150px,17vw,215px); display:block; }
/* Larger and more prominent, at the client's request. The capsule padding
   grows with it so the mark keeps its breathing room instead of filling the
   pill edge to edge. */
.mh-mark img{ height:clamp(26px,3.6vh,38px); width:auto; }
.mh-mark{ padding:.6rem 1.2rem; }
@media (pointer:fine){
  .mh-mark:hover{ transform:translateY(-1px); }
}
.mh-mark:focus-visible{ transform:translateY(-1px); }

.mh-nav{
  display:flex; align-items:center; white-space:nowrap; gap:clamp(1.1rem,2.2vw,2.1rem);
  padding:.85rem clamp(1.2rem,2vw,1.8rem);
  border-radius:100px;
  background:rgba(255,253,250,.30);
  border:1px solid rgba(255,255,255,.42);
  backdrop-filter:blur(18px) saturate(1.2);
  -webkit-backdrop-filter:blur(18px) saturate(1.2);
  box-shadow:0 2px 10px rgba(10,26,47,.08);
}
/* Text stays var(--ink) always, never --accent: --accent was only measured
   safe against opaque paper. Composited over this translucent glass sitting
   on a near-black frame it drops to ~2:1, so the interactive signal is the
   amber underline (a fill, exempt from the text-contrast rule) instead. */
.mh-nav a{
  position:relative;
  padding:.6rem 1rem;
  font:500 var(--t-sm)/1 var(--sans);
  color:var(--ink);
  border-radius:999px;
}
.mh-nav a::after{
  content:''; position:absolute; left:1rem; right:1rem; bottom:.42rem; height:1px;
  background:var(--amber); transform:scaleX(0); transform-origin:left;
  transition:transform .55s var(--ease);
}
@media (pointer:fine){
  .mh-nav a:hover::after{ transform:scaleX(1); }
}
.mh-nav a:focus-visible::after{ transform:scaleX(1); }

/* burger: hidden until the nav capsule can no longer hold four links */
.mh-burger{
  display:none; position:relative;
  width:44px; height:44px; flex:none;
  align-items:center; justify-content:center;
  border-radius:999px; cursor:pointer;
}
@media (pointer:fine){
  .mh-burger:hover{ background:rgba(255,253,250,.9); }
}
.mh-burger:focus-visible{ background:rgba(255,253,250,.9); }
.mh-burger span{
  position:absolute; width:18px; height:2px; border-radius:2px;
  background:var(--ink);
  transition:transform .45s var(--ease);
}
.mh-burger span:first-child{ transform:translateY(-4px); }
.mh-burger span:last-child{ transform:translateY(4px); }
.masthead.is-open .mh-burger span:first-child{ transform:translateY(0) rotate(45deg); }
.masthead.is-open .mh-burger span:last-child{ transform:translateY(0) rotate(-45deg); }

/* The burger takes over at 1000, not 760. Between those widths the full nav
   had to wrap, and a menu item broken across two lines reads as a fault
   rather than as a layout. */
@media (max-width:1100px){
  .mh-burger{ display:flex; }
  .mh-nav{
    position:absolute; top:calc(100% + .6rem); right:var(--gut);
    flex-direction:column; align-items:stretch; gap:0;
    padding:.6rem; border-radius:22px;
    opacity:0; visibility:hidden; transform:translateY(-6px) scale(.98);
    transition:opacity .44s var(--ease), transform .44s var(--ease), visibility 0s linear .44s;
  }
  .masthead.is-open .mh-nav{
    opacity:1; visibility:visible; transform:none;
    transition:opacity .44s var(--ease), transform .44s var(--ease), visibility 0s linear 0s;
  }
  .mh-nav a{ padding:.85rem 1.1rem; }
  .mh-nav{ white-space:nowrap; }
  .mh-nav a::after{ left:1.1rem; right:1.1rem; }
}

/* ---------- journey: brand scroll indicator ----------
   A vertical rail on the right edge, never the middle, never under
   the masthead. Six named stops; a small head-and-Y traveller (the
   logo's own person shape) slides between them as the leg advances. */

.journey{
  position:fixed; z-index:400;
  right:clamp(1rem, 3vw, var(--gut));
  top:50%; transform:translateY(-50%);
  /* Sized for the longest label, THE LEARNING ROOM. Below this it ellipsises
     mid word, which looks like a bug rather than a design. */
  width:clamp(210px, 18vw, 240px);
  height:clamp(260px, 44vh, 420px);
  max-height:calc(100vh - (var(--chrome-h) * 2) - 2rem);
  display:flex; flex-direction:column;
  padding:1.4rem 1.3rem;
  pointer-events:none; /* decorative, aria-hidden in the markup */
  opacity:1;
  transition:opacity .4s var(--ease);
}
.journey.jy-hide{ opacity:0; }

/* No plate. This was in the shared glass group, and blur(18px) saturate(1.5)
   over warm sunlit footage turned the whole card into an amber glow with a
   visible 1px edge, parked over the picture for the entire flight: precisely
   the glare the client rejected, twice. Legibility now comes from a feathered
   field shaped to the block and faded to nothing well before it reads as a
   shape, which is the same treatment the titles use and the one that was
   accepted. */
.journey::before{
  content:''; position:absolute; z-index:-1;
  inset:-16% -13% -16% -26%;
  background:radial-gradient(58% 54% at 64% 50%,
    rgba(6,14,26,.58) 0%, rgba(6,14,26,.42) 36%,
    rgba(6,14,26,.19) 58%, rgba(6,14,26,0) 76%);
  pointer-events:none;
}

.jy-track{ position:relative; flex:1; }

.jy-rail{
  position:absolute; left:5px;
  top:var(--jy-half, 8%); bottom:var(--jy-half, 8%);
  width:2px; border-radius:2px;
  background:var(--amber); opacity:.32;
}

.jy-list{
  position:absolute; inset:0;
  display:grid;
  list-style:none; margin:0; padding:0;
}
.jy-item{ display:flex; align-items:center; gap:.65rem; min-width:0; }

/* Glass on EACH label, never one plate behind the whole rail. The plate was
   removed on 11 Aug because blur plus saturate over warm footage turned the
   card into an amber glow, which is the glare the client rejected twice. These
   are deliberately weaker: no saturate at all, a smaller blur, and a border
   barely above the noise floor. Enough to hold the words, not enough to read
   as a panel. */
.jy-label{
  padding:.3rem .62rem;
  border-radius:100px;
  background:rgba(252,250,247,.30);
  border:1px solid rgba(255,255,255,.26);
  backdrop-filter:blur(9px);
  -webkit-backdrop-filter:blur(9px);
}

.jy-dot{
  width:10px; height:10px; flex:none; border-radius:50%;
  background:var(--paper); border:2px solid var(--ink-faint);
  transition:background .45s var(--ease), border-color .45s var(--ease), transform .45s var(--ease);
}
/* Always the full var(--ink), never the fainter ink-soft: against a near-black
   frame ink-soft's built-in alpha reads at under 4:1, below the AA floor for
   text this small. Active vs inactive is carried by weight and the dot, not
   by dimming the letters. min-width:0 overrides the flex default of auto,
   which otherwise blocks the shrink that ellipsis depends on. */
.jy-label{
  font:500 var(--t-xs)/1.2 var(--mono);
  letter-spacing:.06em; text-transform:uppercase;
  color:var(--ink); white-space:nowrap; overflow:hidden; text-overflow:ellipsis;
  min-width:0; flex:1 1 auto;
}
.jy-item.is-active .jy-dot{ background:var(--amber); border-color:var(--amber); transform:scale(1.2); }
.jy-item.is-active .jy-label{ font-weight:600; }

.jy-marker{
  position:absolute; left:5px;
  top:calc(var(--jy-p, 0) * 100%);
  transform:translate(-50%,-50%);
  width:14px; height:21px;
  fill:none; stroke:var(--amber); stroke-width:2.2; stroke-linecap:round; stroke-linejoin:round;
  filter:drop-shadow(0 1px 3px rgba(154,91,0,.35));
  /* Exempt from the 400ms floor: the marker tracks scroll position, so any
     easing here reads as lag rather than polish. */
  transition:top .12s linear;
}
.jy-marker circle{ fill:var(--amber); stroke:none; }

@media (max-width:900px){
  .journey{ right:1rem; }
}

/* Coarse pointers on a small screen have no room to spare and the marker
   adds nothing a thumb can act on, so it steps aside there. */
/* The rail needs its own column. Below this width it has none, and it lands on
   top of the copy: measured at 375px the traveller sat on the middle of the
   headline, the last pill overlapped it, and four of the six labels truncated
   mid word. Gating on `pointer:coarse` was the wrong test, because the problem
   is the width, not the input device: a narrow laptop window collided just the
   same. The scenes are still announced by the copy itself, so nothing is lost. */
@media (max-width:1150px){
  .journey{ display:none; }
}

@media (prefers-reduced-motion:reduce){
  .jy-marker{ transition:none; }
}

/* Past the flight the masthead steps aside on the way down and comes back
   on the way up. Transform only, so it never costs a layout. */
.masthead{ transition:transform .45s var(--ease), opacity .45s var(--ease); }
.masthead.mh-away{
  transform:translateY(calc(-1 * var(--chrome-h) - 1.5rem));
  opacity:0;
  pointer-events:none;
}
@media (prefers-reduced-motion:reduce){
  .masthead{ transition:none; }
  .masthead.mh-away{ transform:none; opacity:1; pointer-events:auto; }
}

/* ---------- client login, in the top bar ----------
   Staff reach the editing screen from here, so it sits with the navigation
   where people look for it rather than buried in the footer. It is
   deliberately quieter than the nav links: it is a staff door, not a visitor
   destination, so it reads as secondary without being hard to find. */

.mh-div{
  width:1px; align-self:stretch;
  margin-inline:.15rem;
  background:rgba(10,26,47,.16);
}

.mh-login{
  display:inline-flex; align-items:center; gap:.42rem;
  color:var(--ink-soft);
  font-size:.92em;
  white-space:nowrap;
}
.mh-login svg{ width:12px; height:12px; flex:none; opacity:.75; }

/* Same underline signal as the nav, so the bar behaves as one system. */
.mh-login::after{
  content:''; position:absolute; left:0; right:0; bottom:0; height:2px;
  background:var(--amber);
  transform:scaleX(0); transform-origin:left;
  transition:transform .4s var(--ease);
}
.mh-login{ position:relative; padding-bottom:.3rem; }

@media (pointer:fine){
  .mh-login:hover{ color:var(--ink); }
  .mh-login:hover svg{ opacity:1; }
  .mh-login:hover::after{ transform:scaleX(1); }
}
.mh-login:focus-visible{ color:var(--ink); }
.mh-login:focus-visible::after{ transform:scaleX(1); }

@media (max-width:760px){
  .mh-div{ display:none; }
}
