/* =========================================================================
   FREE SAILING — the public world.

   Tokens, header, footer and card patterns copied out of classhub-site and
   then diverged. classhub-site is a separate, class-centric site and is never
   written to from here; this is a copy, taken once, on purpose.

   No external requests. Leaflet, GSAP, Lenis and three are vendored locally.
   ========================================================================= */

:root{
  --navy:      #022B83;
  --navy-deep: #011C57;
  --cyan:      #02A2EE;
  --teal:      #01B9BA;
  --hl:        #22DDF9;
  --pale:      #EEF3F8;
  --ink:       #0D1417;

  --orange:      #F98A57;
  --orange-deep: #EE7442;

  --ink-60:  #48555C;   /* 7.69:1 on white */
  --ink-40:  #5C6B74;   /* was #74838B, 3.92:1 — now 5.51:1 */
  --ink-25:  #66757D;   /* was #9AA7AF, 2.46:1 — now 4.77:1 */

  /* Text-only variants. The fill tokens above are untouched; these exist
     because the brand hues are too light to read as small type on white. */
  --cyan-text:   #026C9E;   /* 5.77:1 */
  --teal-text:   #01706F;   /* 5.92:1 */
  --orange-text: #B84A1B;   /* 5.21:1 */
  --line:    #DCE5EF;
  --line-2:  #EAF0F7;
  --white:   #fff;

  --sand:    #F5E7D3;
  --coral:   #FF6B4A;

  --sans: "DIN Next LT Pro","DIN Next","DIN Next W01","Helvetica Neue",Helvetica,Arial,sans-serif;

  --shadow-1: 0 1px 2px rgba(2,43,131,.05), 0 6px 18px rgba(2,43,131,.05);
  --shadow-2: 0 2px 6px rgba(2,43,131,.07), 0 18px 44px rgba(2,43,131,.10);
  --shadow-3: 0 4px 12px rgba(2,43,131,.09), 0 30px 70px rgba(2,43,131,.14);

  --r:   14px;
  --r-s: 9px;
  --r-l: 22px;
  --hd:  127px;   /* measured height of the two-row header at 1440 */
  --wrap: 1280px;

  --ease: cubic-bezier(.22,.61,.36,1);
  /* the three reused easings, measured off Class Sails. No browser defaults. */
  --e1: cubic-bezier(.76,0,.24,1);
  --e2: cubic-bezier(.22,.61,.36,1);
  --e3: cubic-bezier(.2,.7,.2,1);
}

*,*::before,*::after{ box-sizing:border-box; }
html,body{ margin:0; padding:0; }
html{ -webkit-text-size-adjust:100%; scroll-behavior:smooth; }
body{
  font-family:var(--sans);
  color:var(--ink);
  background:var(--pale);
  font-size:16px;
  line-height:1.45;
  -webkit-font-smoothing:antialiased;
  overflow-x:clip;                 /* never `hidden` — it kills position:sticky */
}
img{ max-width:100%; display:block; }
a{ color:var(--navy); text-decoration:none; }
a:hover{ text-decoration:underline; }
button{ font:inherit; color:inherit; }
h1,h2,h3,h4{ margin:0; line-height:1.12; letter-spacing:-.015em; font-weight:700; }
p{ margin:0; }
:focus-visible{ outline:3px solid var(--hl); outline-offset:2px; border-radius:4px; }

.wrap{ width:100%; max-width:var(--wrap); margin:0 auto; padding:0 22px; }
.skip{
  position:absolute; left:-9999px; top:0; z-index:200; background:#fff; color:var(--navy);
  padding:12px 18px; border-radius:0 0 10px 0; font-weight:700;
}
.skip:focus{ left:0; }

/* The header is injected by shell.js, replacing an empty placeholder. Without a
   reserved height the placeholder is 0px and the real header is 64px, so main
   and the footer dropped 64px the moment it landed — that single swap measured
   CLS 0.61 on every page with a page-head. Reserving it costs nothing and takes
   the shift to zero. */
#fs-hd{ height:var(--hd); background:#F7FAFD; }
@media (max-width:1319px){ :root{ --hd:123px; } }
@media (max-width:1095px){ :root{ --hd:111px; } }
@media (max-width:900px){  :root{ --hd:67px;  } }
@media (min-width:1600px){ :root{ --hd:135px; } }
#fs-ft{ min-height:360px; background:var(--navy-deep); }
@media (max-width:640px){ #fs-ft{ min-height:600px; } }

/* --------------------------------------------------------------- header
   The navy bar with a white box behind the mark is GONE. It is replaced by
   the light shelf bar at the foot of this file. The box was never styling:
   the lockup's word-ink is #12379B, which measures 1.21:1 against --navy,
   so somebody boxed it three times to make it visible. A light ground
   removes the cause. Replaces: .site-hd .hd-in .lockup .hd-nav .hd-right
   ---------------------------------------------------------------------- */

.burger{
  display:none; width:40px; height:38px; border-radius:9px; cursor:pointer;
  border:1px solid rgba(255,255,255,.28); background:transparent;
}
.burger span{ display:block; width:18px; height:2px; background:#fff; margin:3px auto; border-radius:2px; }
.hd-drawer{ display:none; background:var(--navy-deep); border-top:1px solid rgba(255,255,255,.12); }
.hd-drawer.open{ display:block; }
.hd-drawer a{
  display:block; color:#D6E2F6; padding:13px 22px; font-size:15.5px; font-weight:500;
  border-bottom:1px solid rgba(255,255,255,.07); text-decoration:none;
}
.hd-drawer a.is-active{ color:#fff; font-weight:700; box-shadow:inset 3px 0 0 var(--hl); }

/* -------------------------------------------------------------- helpers */
.section{ padding:46px 0; }
.section.tight{ padding:30px 0; }
.section-hd{ display:flex; align-items:flex-end; justify-content:space-between; gap:16px; margin-bottom:20px; flex-wrap:wrap; }
.section-hd h2{ font-size:30px; color:var(--navy); letter-spacing:-.022em; }
.section-hd .sub{ color:var(--ink-40); font-size:15px; margin-top:6px; max-width:62ch; }
.section-hd .more{ font-size:14px; font-weight:700; color:var(--cyan-text);
  white-space:nowrap; padding:4px 2px; display:inline-block; }
.section-hd .more:hover{ color:var(--navy); }

.eyebrow{ font-size:11px; font-weight:700; letter-spacing:.15em; text-transform:uppercase; color:var(--cyan-text); }
.card{
  background:#fff; border:1px solid var(--line); border-radius:var(--r);
  box-shadow:var(--shadow-1);
  transition:box-shadow .26s var(--ease), transform .26s var(--ease), border-color .26s var(--ease);
}
a.card:hover, .card.hoverable:hover{
  box-shadow:var(--shadow-2); transform:translateY(-3px); border-color:#C9D8EA; text-decoration:none;
}
.card-pad{ padding:22px; }
.grid{ display:grid; gap:18px; }
.g2{ grid-template-columns:repeat(2,1fr); }
.g3{ grid-template-columns:repeat(3,1fr); }
.g4{ grid-template-columns:repeat(4,1fr); }
.g5{ grid-template-columns:repeat(5,1fr); }
.muted{ color:var(--ink-40); }
.small{ font-size:13.5px; }
.tiny{ font-size:12px; }
.rule{ height:1px; background:var(--line); border:0; margin:0; }

.btn{
  display:inline-flex; align-items:center; justify-content:center; gap:8px;
  border-radius:999px; padding:11px 20px; font-weight:700; font-size:14.5px;
  border:1px solid transparent; cursor:pointer; text-decoration:none; white-space:nowrap;
  transition:filter .18s var(--ease), transform .18s var(--ease), box-shadow .18s var(--ease);
}
.btn:hover{ text-decoration:none; filter:brightness(1.04); transform:translateY(-1px); }
.btn-orange{ background:linear-gradient(180deg,var(--orange),var(--orange-deep)); color:#fff; box-shadow:0 2px 8px rgba(238,116,66,.35); }
.btn-navy{ background:var(--navy); color:#fff; }
.btn-cyan{ background:linear-gradient(180deg,#0EB2F6,var(--cyan)); color:#fff; box-shadow:0 2px 8px rgba(2,162,238,.32); }
.btn-ghost{ background:#fff; color:var(--navy); border-color:var(--line); box-shadow:var(--shadow-1); }
.btn-clear{ background:rgba(255,255,255,.12); color:#fff; border-color:rgba(255,255,255,.4); }
.btn-sm{ padding:8px 15px; font-size:13.5px; }
.btn-block{ display:flex; width:100%; }

.chip{
  display:inline-flex; align-items:center; gap:6px; border-radius:999px;
  padding:5px 12px; font-size:11.5px; font-weight:700; letter-spacing:.09em; text-transform:uppercase;
  background:#fff; color:var(--navy); border:1px solid var(--line);
}
.chip.solid{ background:var(--navy); color:#fff; border-color:var(--navy); }
.chip.cyan{ background:#E6F6FE; color:#00688F; border-color:#BFE7FA; }
.chip.teal{ background:#E4F8F7; color:#016F70; border-color:#BEEBEA; }
.chip.sand{ background:#FBF1E3; color:#8A5A28; border-color:#F0DCC1; }
.chip.coral{ background:#FFEDE8; color:#B03A21; border-color:#FFD3C7; }
.chip.young{ background:#EFF3FF; color:#2A3F94; border-color:#D3DDFB; }

/* stat row */
.statrow{ display:grid; grid-template-columns:repeat(4,1fr); gap:14px; }
.stat{
  background:#fff; border:1px solid var(--line); border-radius:var(--r); padding:18px 20px;
  box-shadow:var(--shadow-1);
}
.stat b{ display:block; font-size:32px; color:var(--navy); letter-spacing:-.03em; line-height:1; font-variant-numeric:tabular-nums; }
.stat span{ display:block; margin-top:7px; color:var(--ink-40); font-size:13px; line-height:1.35; }

/* ------------------------------------------------------------- the hero */
.hero-sticky{
  position:relative; height:min(86vh,760px); min-height:520px; overflow:hidden;
  background:
    radial-gradient(125% 95% at 50% 12%, #ffffff 0%, #EDF4FB 40%, #DCE9F5 70%, #C7DAEC 100%);
  isolation:isolate;
}
.hero-sticky::after{  /* grain — draw-only, one paint, no JS */
  content:""; position:absolute; inset:0; pointer-events:none; z-index:3; opacity:.30;
  background-image:url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='140' height='140'><filter id='n'><feTurbulence type='fractalNoise' baseFrequency='.9' numOctaves='3'/><feColorMatrix type='saturate' values='0'/></filter><rect width='140' height='140' filter='url(%23n)' opacity='.42'/></svg>");
  mix-blend-mode:multiply;
}
#heroGl{ position:absolute; inset:0; width:100%; height:100%; display:block; z-index:2; touch-action:pan-y; }
.hero-fallback{ position:absolute; inset:0; z-index:1; display:none; }
.hero-sticky.fallback .hero-fallback{ display:block; }
.hero-sticky.fallback #heroGl{ display:none; }
/* The still is the LIGHT composite, pre-flattened onto the page ground.

   IT MUST HOLD THE SAME COMPOSITION AS THE WEBGL MARK, and for a long time it
   did not. hero.js puts the mark at composeX = vw * 0.155 right of centre and
   composeY = vh * 0.135 up, precisely so the copy can own the left 52% and
   "the two never share a pixel" (the rule stated four rules below). The still
   was left at object-position:50% — dead centre — so in the fallback the mark
   sprawled straight through the copy column and the h1 sat unreadable on top
   of the wordmark. This is not a rare path: every browser reporting
   prefers-reduced-motion gets it, which is an accessibility setting, and it is
   also what every headless screenshot of this page has been showing.
   Percentages below are that same composition expressed as CSS. */
.hero-fallback picture{
  display:block; position:absolute;
  right:0; left:auto; top:36.5%; transform:translateY(-50%);
  width:min(52%, 760px);
}
/* Why right-anchored and 52%, rather than the centre-offset the WebGL path
   uses: the still carries ~11% transparent padding on its left edge and ~9% on
   its right, so matching composeX by the ELEMENT box still put 184px of actual
   ink through the copy — measured by rasterising the webp and finding the
   leftmost non-ground column, not by eye. Anchoring right and sizing to 52%
   makes the clearance hold as the viewport moves, because the copy's right
   edge and the mark's left edge then scale off the same width:
       1100px -> copy ends 571, ink starts 592   (21px clear)
       1280px -> copy ends 665, ink starts 689   (24px clear)
       1440px -> copy ends 746, ink starts 775   (29px clear)
       1600px -> copy ends 826, ink starts 925   (99px clear)
   No right gutter on purpose — a gutter subtracts from that clearance, and the
   still's own transparent margin already reads as one. */
/* THE STILL IS AN OPAQUE RECTANGLE AND MUST NOT LOOK LIKE ONE.
   Sampled from the decoded webp: every edge pixel is alpha 255 on a FLAT baked
   ground of rgb(237,243,248), and the bottom-right corner is rgb(229,233,236)
   where the drop shadow was flattened in. The hero behind it is a RADIAL
   gradient, so a flat ground can only match it along one contour — everywhere
   else the still reads as a pasted box with a hard seam. That seam is most of
   what "the logo looks stuck on top of the interface" was pointing at.
   A blend mode does not fix this: multiply against a lighter ground darkens
   the rectangle instead of dissolving it, and darken leaves the grey shadow
   corner. So the edges are masked to transparent instead.
   Stops are chosen against the measured ink box (ink spans 11%..91% across and
   23%..99% down the picture), so no fade touches the mark: left clears by 1%,
   top by 11%, and the bottom fade deliberately eats the baked shadow. The
   right edge is left hard because it sits on the viewport boundary. */
.hero-fallback img{
  display:block; width:100%; height:auto;
  -webkit-mask-image:
    linear-gradient(to right, transparent 0%, #000 10%),
    linear-gradient(to bottom, transparent 0%, #000 12%, #000 82%, transparent 100%);
  -webkit-mask-composite: source-in;
          mask-image:
    linear-gradient(to right, transparent 0%, #000 10%),
    linear-gradient(to bottom, transparent 0%, #000 12%, #000 82%, transparent 100%);
          mask-composite: intersect;
}
/* Narrow: hero.js recentres the mark (composeX 0) and lifts it (composeY
   vh*0.20) because the copy takes the floor beneath it instead of the left.
   Stated TWICE on purpose. fallback() adds only the "fallback" class and
   returns before resize() ever runs, so .hero-narrow is never applied on this
   path — the class selector alone would have been dead code. The media query
   is the one that actually fires; it keys off viewport aspect where hero.js
   keys off stage aspect, so the two can disagree in a thin band around the
   threshold, where the only consequence is a centred mark instead of an
   offset one. */
.hero-sticky.hero-narrow .hero-fallback picture{
  left:50%; right:auto; transform:translate(-50%,-50%);
  top:30%; width:min(66%, 520px);
}
@media (max-aspect-ratio: 105/100){
  /* right:auto and the X translate must BOTH be restored here. Setting left
     alone leaves the wide rule's right:0 and translateY-only transform in
     force; left then wins against an explicit width and the mark is shoved
     60px off the right edge — clipped rather than scrolling, because the hero
     is overflow:hidden, so it fails silently and looks merely cropped. */
  /* top:8% and 60% are derived, not eyeballed. Measured off the rasterised
     still: ink starts 0.1452W below the picture's top edge and is 0.4758W
     tall, where W is the picture width. Solving for "ink sits entirely above
     the copy" on a 375x812 screen — hero top 58, copy top 198 — gives
     W <= 244 and a picture centre of ~108, i.e. 8% of the hero. At 60%/440px
     that lands ink at 70..177 against a floor of 182: it clears by 5px.
     Five pixels is thin, so the scrim below is the real guarantee, not this. */
  .hero-fallback picture{
    left:50%; right:auto; transform:translate(-50%,-50%);
    top:8%; width:min(60%, 440px);
  }
  /* Ramps in ABOVE where the copy starts (~23% of the hero on a 375x812), so
     the h1's first line never lands on unscrimmed ink even if the geometry
     above drifts on a screen shape I have not measured. */
  .hero-sticky.fallback .hero-fallback::after{
    background:linear-gradient(180deg,
      rgba(237,244,251,0) 16%, rgba(237,244,251,.62) 26%,
      rgba(237,244,251,.95) 38%);
  }
}
/* The scrim the old comment promised and never defined. The still is brightest
   through its middle, which is exactly where the copy's last line lands. */
.hero-sticky.fallback .hero-fallback::after{
  content:""; position:absolute; inset:0; pointer-events:none;
  background:linear-gradient(100deg,
    rgba(237,244,251,.92) 0%, rgba(237,244,251,.72) 30%,
    rgba(237,244,251,.20) 52%, rgba(237,244,251,0) 68%);
}


.hero-copy{
  position:absolute; left:0; right:0; bottom:0; z-index:4; pointer-events:none;
  padding:0 22px 44px;
}
.hero-copy .in{ max-width:var(--wrap); margin:0 auto; }
.hero-copy h1{
  font-size:clamp(30px,4.0vw,52px); color:var(--navy-deep); letter-spacing:-.032em;
  max-width:15ch;
}
.hero-copy p{
  margin-top:12px; font-size:clamp(15px,1.4vw,19px); color:#2C4763; max-width:44ch; font-weight:400;
}
/* The mark holds the right of a wide hero, so the copy is bounded to the left
   half and the two never share a pixel. */
.hero-copy .in > *{ max-width:52%; }
.hero-sticky.hero-narrow .hero-copy .in > *{ max-width:100%; }
.hero-sticky.hero-narrow .hero-copy h1{ max-width:18ch; }
.hero-copy .hero-actions{ display:flex; gap:12px; margin-top:22px; flex-wrap:wrap; pointer-events:auto; }
.hero-scroll{
  position:absolute; right:26px; bottom:30px; z-index:5;
  font-size:11px; letter-spacing:.2em; text-transform:uppercase; color:#5F7B95;
  display:flex; align-items:center; gap:9px; pointer-events:none;
}
.hero-scroll i{ display:block; width:1px; height:34px; background:linear-gradient(180deg,#5F7B95,transparent); animation:drop 2.4s var(--ease) infinite; }
@keyframes drop{ 0%{transform:scaleY(.2);transform-origin:top;opacity:0} 40%{transform:scaleY(1);opacity:1} 100%{transform:scaleY(1);transform-origin:bottom;opacity:0} }

/* -------------------------------------------------------- reveal on scroll */
.js-reveal .rv{ opacity:0; transform:translateY(16px); }
.js-reveal .rv.in{ opacity:1; transform:none;
  transition:opacity .7s var(--ease), transform .7s var(--ease); }
@media (prefers-reduced-motion:reduce){
  .rv{ opacity:1; transform:none; }
  .hero-scroll i{ animation:none; }
  html{ scroll-behavior:auto; }
}

/* ---------------------------------------------------------------- map */
.mapwrap{
  position:relative; border-radius:var(--r-l); overflow:hidden;
  border:1px solid var(--line); box-shadow:var(--shadow-2); background:#0A2440;
}
.mapwrap.home{ height:clamp(380px,52vh,560px); }
.mapwrap.full{ height:calc(100vh - var(--hd) - 118px); min-height:460px; }
#map, .fsmap{ position:absolute; inset:0; }
.leaflet-container{ background:#0A2440; font-family:var(--sans); }
.leaflet-control-attribution{ font-size:10px; background:rgba(255,255,255,.82); }

.lenses{
  display:flex; gap:8px; overflow-x:auto; padding:2px 0 10px; scrollbar-width:none;
}
.lenses::-webkit-scrollbar{ display:none; }
.lens{
  border:1px solid var(--line); background:#fff; color:var(--ink-60);
  border-radius:999px; padding:9px 16px; font-size:13.5px; font-weight:700; cursor:pointer;
  white-space:nowrap; transition:all .18s var(--ease);
}
.lens:hover{ border-color:var(--cyan); color:var(--navy); }
.lens.on{ background:var(--navy); border-color:var(--navy); color:#fff; }

.mapbar{
  position:absolute; z-index:500; left:14px; top:14px; right:14px;
  display:flex; gap:8px; flex-wrap:wrap; pointer-events:none;
}
.mapbar > *{ pointer-events:auto; }
.mapchip{
  background:rgba(255,255,255,.94); border:1px solid rgba(255,255,255,.6);
  backdrop-filter:blur(8px); border-radius:999px; padding:7px 14px;
  font-size:12.5px; font-weight:700; color:var(--navy); box-shadow:0 3px 14px rgba(3,25,60,.22);
  cursor:pointer; transition:all .18s var(--ease);
}
.mapchip.off{ background:rgba(255,255,255,.55); color:var(--ink-40); }
.mapchip:hover{ background:#fff; }
.maplegend{
  position:absolute; z-index:500; left:14px; bottom:22px;
  background:rgba(255,255,255,.94); backdrop-filter:blur(8px);
  border-radius:12px; padding:11px 13px 12px; box-shadow:0 3px 14px rgba(3,25,60,.22);
  font-size:11px; color:var(--ink-60); max-width:236px;
}
/* Matches map-engine.js DENS_RAMP — the swatch reads as the homepage heatmap. */
.maplegend .ramp{ height:9px; border-radius:5px; margin:7px 0 6px;
  background:linear-gradient(90deg,rgba(28,92,176,0) 0%,#1C5CB0 12%,#1696CA 32%,#1EC8A8 52%,#8CD450 70%,#F2CD37 86%,#E23728 100%); }
.maplegend .ends{ display:flex; justify-content:space-between; font-weight:700; color:var(--ink-40); font-size:10.5px; letter-spacing:.06em; text-transform:uppercase; }
.maplegend b{ display:block; font-size:11px; letter-spacing:.13em; text-transform:uppercase; color:var(--navy); }
.mapcount{
  position:absolute; z-index:500; right:14px; bottom:22px;
  background:rgba(4,30,64,.86); color:#DCEBF8; backdrop-filter:blur(8px);
  border-radius:999px; padding:8px 15px; font-size:12px; font-weight:700;
  font-variant-numeric:tabular-nums; box-shadow:0 3px 14px rgba(3,25,60,.3);
}

.leaflet-popup-content-wrapper{ border-radius:12px; box-shadow:var(--shadow-3); }
.leaflet-popup-content{ margin:14px 16px; font-size:13.5px; line-height:1.45; }
.pop-t{ font-weight:700; color:var(--navy); font-size:15px; letter-spacing:-.01em; }
.pop-s{ color:var(--ink-40); font-size:12.5px; margin-top:2px; }
.pop-q{ margin-top:9px; padding-left:10px; border-left:2px solid var(--cyan); color:var(--ink-60); font-size:12.5px; font-style:italic; }
.pop-k{ margin-top:9px; display:flex; gap:5px; flex-wrap:wrap; }
.pop-k span{ font-size:10px; font-weight:700; letter-spacing:.07em; text-transform:uppercase; color:#00688F; background:#E6F6FE; border-radius:999px; padding:3px 8px; }
.pop-a{ margin-top:11px; display:inline-block; font-weight:700; color:var(--cyan-text); font-size:13px; }
.cluster-pin{ background:none; border:0; }
.cluster-pin i{
  display:grid; place-items:center; border-radius:50%; color:#fff; font-style:normal;
  font-weight:700; font-size:12px; background:rgba(2,43,131,.86); border:2px solid rgba(255,255,255,.75);
  box-shadow:0 3px 12px rgba(2,30,70,.4); font-variant-numeric:tabular-nums;
}

/* ---------------------------------------------------------- tiles / rows */
.tile{ display:block; border-radius:var(--r); overflow:hidden; background:#fff; border:1px solid var(--line); box-shadow:var(--shadow-1);
  transition:box-shadow .26s var(--ease), transform .26s var(--ease); }
.tile:hover{ text-decoration:none; box-shadow:var(--shadow-2); transform:translateY(-3px); }
.tile .art{ aspect-ratio:16/10; position:relative; overflow:hidden; background:#DCE9F5; }
.tile .art svg{ position:absolute; inset:0; width:100%; height:100%; }
.tile .art img{ position:absolute; inset:0; width:100%; height:100%; object-fit:cover; }
.tile .bd{ padding:16px 18px 18px; }
.tile h3{ font-size:17px; color:var(--navy); letter-spacing:-.018em; }
.tile p{ margin-top:6px; color:var(--ink-40); font-size:13.5px; line-height:1.42; }
.tile .foot{ margin-top:12px; display:flex; align-items:center; gap:8px; flex-wrap:wrap; }

.row{
  display:flex; gap:16px; align-items:flex-start; padding:16px 0; border-bottom:1px solid var(--line-2);
}
.row:last-child{ border-bottom:0; }
.row .when{
  flex:0 0 62px; text-align:center; border-radius:10px; background:#F4F8FC; border:1px solid var(--line-2); padding:8px 4px;
}
.row .when b{ display:block; font-size:20px; color:var(--navy); line-height:1; font-variant-numeric:tabular-nums; }
.row .when span{ display:block; font-size:10.5px; letter-spacing:.11em; text-transform:uppercase; color:var(--ink-40); margin-top:4px; }
.row .bd{ flex:1 1 auto; min-width:0; }
.row .bd h3{ font-size:16px; color:var(--navy); letter-spacing:-.015em; }
.row .bd .meta{ margin-top:4px; color:var(--ink-40); font-size:13px; }
.row .bd .tags{ margin-top:8px; display:flex; gap:6px; flex-wrap:wrap; }
.row .go{ flex:0 0 auto; align-self:center; }

.quote{ border-left:2px solid var(--cyan); padding:2px 0 2px 12px; color:var(--ink-60); font-size:13.5px; font-style:italic; }
.src{ margin-top:9px; font-size:11.5px; color:var(--ink-25); letter-spacing:.02em; }
.src a{ color:var(--ink-40); text-decoration:underline; text-underline-offset:2px; }
.src a:hover{ color:var(--navy); }

/* filter bar */
.filters{ display:flex; gap:10px; flex-wrap:wrap; align-items:center; margin-bottom:18px; }
.filters select, .filters input[type=text], .filters input[type=search]{
  font:inherit; font-size:14px; border:1px solid var(--line); border-radius:999px;
  padding:9px 15px; background:#fff; color:var(--ink); min-width:0;
}
.filters input[type=search]{ min-width:230px; }
.filters .count{ margin-left:auto; color:var(--ink-40); font-size:13px; font-variant-numeric:tabular-nums; }

.empty{
  border:1px dashed var(--line); border-radius:var(--r); padding:34px 24px; text-align:center;
  color:var(--ink-40); background:#fff;
}
.empty b{ display:block; color:var(--navy); font-size:17px; margin-bottom:6px; }

/* ---------------------------------------------------------- panorama band */
.band{ background:var(--navy); color:#fff; position:relative; overflow:hidden; }
.band.deep{ background:linear-gradient(160deg,var(--navy-deep),#063A6E 62%,#0C5C86); }
.band::before{
  content:""; position:absolute; inset:0; opacity:.16; pointer-events:none;
  background:
    radial-gradient(70% 120% at 12% 0%, var(--hl), transparent 62%),
    radial-gradient(60% 110% at 92% 100%, var(--teal), transparent 60%);
}
.band .wrap{ position:relative; z-index:1; }
.band h2{ color:#fff; }
.band .sub, .band .muted{ color:#A9C6E4; }
.band .card{ background:rgba(255,255,255,.06); border-color:rgba(255,255,255,.16); box-shadow:none; color:#EAF4FB; }
.band .card h3{ color:#fff; }
.band a.card:hover{ background:rgba(255,255,255,.11); border-color:rgba(255,255,255,.3); transform:translateY(-3px); }

/* ------------------------------------------------------------- personal */
.panel{
  border:1px solid var(--line); border-radius:var(--r); background:#fff; box-shadow:var(--shadow-1);
  overflow:hidden;
}
.panel > summary{
  list-style:none; cursor:pointer; padding:15px 20px; display:flex; align-items:center; gap:12px;
  font-weight:700; color:var(--navy); font-size:15px;
}
.panel > summary::-webkit-details-marker{ display:none; }
.panel > summary .car{ margin-left:auto; color:var(--ink-40); font-size:12px; font-weight:600; }
.panel > summary:hover{ background:#F7FAFD; }
.panel .pbody{ padding:4px 20px 20px; border-top:1px solid var(--line-2); }

/* -------------------------------------------------------------- mascot */
.guide{
  position:fixed; right:18px; bottom:18px; z-index:70; display:flex; align-items:flex-end; gap:10px;
}
.guide-btn{
  width:66px; height:66px; border-radius:50%; border:2px solid #fff; padding:0; cursor:pointer;
  background:#EAF4FB center/86% no-repeat; box-shadow:0 6px 22px rgba(2,30,70,.30);
  transition:transform .26s var(--ease), box-shadow .26s var(--ease);
  overflow:hidden; display:grid; place-items:center;
}
.guide-btn img{ width:100%; height:100%; object-fit:cover; object-position:50% 42%; }
.guide-btn:hover{ transform:translateY(-3px) scale(1.04); box-shadow:0 10px 30px rgba(2,30,70,.36); }
.guide-x{
  position:absolute; right:-5px; top:-5px; width:26px; height:26px; border-radius:50%;
  border:1px solid var(--line); background:#fff; color:var(--ink-40); font-size:12px; line-height:1;
  cursor:pointer; display:grid; place-items:center; box-shadow:var(--shadow-1);
}
.guide-hint{
  background:#fff; border:1px solid var(--line); border-radius:14px 14px 4px 14px;
  padding:11px 14px; font-size:13.5px; color:var(--ink-60); max-width:220px; box-shadow:var(--shadow-2);
}
.guide-hint b{ color:var(--navy); }
.guide-sheet{
  position:fixed; right:18px; bottom:96px; z-index:71; width:min(390px,calc(100vw - 36px));
  background:#fff; border:1px solid var(--line); border-radius:var(--r-l);
  box-shadow:var(--shadow-3); overflow:hidden; display:none;
}
.guide-sheet.open{ display:block; }
.guide-sheet .gh{ display:flex; align-items:center; gap:11px; padding:15px 18px; border-bottom:1px solid var(--line-2); }
.guide-sheet .gh img{ width:40px; height:40px; border-radius:50%; object-fit:cover; object-position:50% 42%; background:#EAF4FB; }
.guide-sheet .gh b{ color:var(--navy); font-size:15px; }
.guide-sheet .gh span{ display:block; color:var(--ink-40); font-size:12px; }
.guide-sheet .gh button{ margin-left:auto; border:0; background:none; color:var(--ink-40); cursor:pointer; font-size:19px; line-height:1; }
.guide-body{ padding:16px 18px 18px; max-height:min(56vh,460px); overflow:auto; }
.guide-body .ask{ display:flex; gap:8px; margin-bottom:14px; }
.guide-body .ask input{ flex:1; font:inherit; font-size:14px; padding:10px 14px; border:1px solid var(--line); border-radius:999px; }
.guide-sug{ display:flex; gap:7px; flex-wrap:wrap; margin-bottom:6px; }
.guide-sug button{
  border:1px solid var(--line); background:#F7FAFD; border-radius:999px; padding:7px 12px;
  font-size:12.5px; color:var(--ink-60); cursor:pointer; text-align:left;
}
.guide-sug button:hover{ border-color:var(--cyan); color:var(--navy); }
.guide-res{ margin-top:14px; display:grid; gap:10px; }
.guide-res .card-pad{ padding:14px 16px; }

/* --------------------------------------------------------------- footer */
.site-ft{ background:var(--navy-deep); color:#B9CFEA; margin-top:20px; }
.ft-in{ max-width:var(--wrap); margin:0 auto; padding:44px 22px 26px; }
.ft-cols{ display:grid; grid-template-columns:1.5fr 1fr 1fr 1fr; gap:28px; }
.ft-cols h4{ color:#fff; font-size:12px; letter-spacing:.15em; text-transform:uppercase; margin-bottom:12px; }
.ft-cols a{ display:block; color:#B9CFEA; font-size:14px; padding:5px 0; }
.ft-cols a:hover{ color:#fff; }
.ft-mark{ width:150px; margin-bottom:14px; }
.ft-mark svg{ width:100%; height:auto; display:block; }
.ft-blurb{ font-size:14px; line-height:1.5; max-width:34ch; color:#9DB8D8; }
.ft-base{
  margin-top:32px; padding-top:18px; border-top:1px solid rgba(255,255,255,.13);
  display:flex; gap:14px; flex-wrap:wrap; align-items:center; font-size:12.5px; color:#8FAAC9;
}
.ft-base .pb{ margin-left:auto; }
.ft-base a{ color:#B9CFEA; }

/* ------------------------------------------------------------ page head */
.phead{ background:linear-gradient(165deg,var(--navy-deep),#0A4B85 78%,#0C5C86); color:#fff; position:relative; overflow:hidden; }
.phead::before{
  content:""; position:absolute; inset:0; opacity:.2; pointer-events:none;
  background:radial-gradient(65% 130% at 8% 0%, var(--hl), transparent 60%),
             radial-gradient(55% 110% at 96% 100%, var(--teal), transparent 58%);
}
.phead-in{ position:relative; z-index:1; max-width:var(--wrap); margin:0 auto; padding:40px 22px 34px; }
.phead h1{ font-size:clamp(28px,3.6vw,44px); letter-spacing:-.028em; margin-top:12px; max-width:20ch; }
.phead p{ margin-top:11px; font-size:clamp(15px,1.4vw,18px); color:#CDE3F6; max-width:60ch; }
.phead .eyebrow{ color:var(--hl); }
.phead .facts{ margin-top:20px; display:flex; gap:22px; flex-wrap:wrap; }
.phead .facts div b{ display:block; font-size:24px; color:#fff; font-variant-numeric:tabular-nums; letter-spacing:-.02em; }
.phead .facts div span{ font-size:12px; color:#A9C6E4; }

/* ----------------------------------------------------------- responsive */
@media (max-width:1080px){
  .g4{ grid-template-columns:repeat(2,1fr); }
  .g5{ grid-template-columns:repeat(3,1fr); }
  .ft-cols{ grid-template-columns:1fr 1fr; }
}
@media (max-width:900px){
  .burger{ display:block; margin-left:auto; }
  .g3{ grid-template-columns:repeat(2,1fr); }
  .statrow{ grid-template-columns:repeat(2,1fr); }
}
@media (max-width:640px){
  .section{ padding:34px 0; }
  .g2,.g3,.g4,.g5{ grid-template-columns:1fr; }
  .section-hd h2{ font-size:24px; }
  .hero-sticky{ height:min(76vh,620px); min-height:460px; }
  .hero-copy{ padding-bottom:30px; }
  .mapwrap.home{ height:360px; }
  .mapwrap.full{ height:calc(100vh - var(--hd) - 150px); }
  .ft-cols{ grid-template-columns:1fr; }
  .guide{ right:12px; bottom:12px; }
  .guide-btn{ width:56px; height:56px; }
  .guide-hint{ display:none; }
  .guide-sheet{ right:12px; left:12px; bottom:78px; width:auto; }
  .filters input[type=search]{ min-width:0; width:100%; }
  .row .when{ flex-basis:54px; }
}


/* ------------------------------------------------- loading and failure
   A region waiting on data shows a shimmer, never words. A region whose data
   did not arrive says so plainly and offers to try again — a silent hole is
   the failure this prevents. */
.skel{ position:relative; overflow:hidden; background:#E7EEF6; border-radius:var(--r); min-height:104px; }
.skel::after{
  content:""; position:absolute; inset:0; transform:translateX(-100%);
  background:linear-gradient(90deg,transparent,rgba(255,255,255,.66),transparent);
  animation:sheen 1.35s ease-in-out infinite;
}
@keyframes sheen{ 100%{ transform:translateX(100%); } }
.band .skel{ background:rgba(255,255,255,.08); }
.failed{
  grid-column:1/-1; border:1px solid var(--line); border-radius:var(--r);
  background:#fff; padding:26px 22px; text-align:center; color:var(--ink-40);
}
.failed b{ display:block; color:var(--navy); font-size:16px; margin-bottom:6px; }
.band .failed{ background:rgba(255,255,255,.07); border-color:rgba(255,255,255,.18); color:#A9C6E4; }
.band .failed b{ color:#fff; }
@media (prefers-reduced-motion:reduce){ .skel::after{ animation:none; } }


/* ------------------------------------------------- layout stability
   A results list starts empty and then fills, and everything beneath it moved
   when it did — measured CLS 0.62 on the list pages. The container now holds
   its height from first paint, so the footer never jumps. */
/* Anything that starts empty and fills gets its height reserved. The measure
   that matters is whether the FOOTER is still on screen when the fill lands: if
   it is, it moves, and that move is the shift. So the main list on a listing
   page reserves a viewport's worth, which pushes the footer off screen from
   first paint and takes the shift to zero. */
#list, #reco, #stats, #waysin, #market, #classes, #learn, #topharbours, #named{
  align-content:start;
}
#list{ min-height:78vh; }
#games{ min-height:120vh; }
#coverage{ min-height:430px; }
/* The organisation views fill the same way; reserved here rather than in the
   supply stylesheet so that lane's files stay its own. */
#sup-stats{ min-height:112px; }
#sup-panel{ min-height:420px; }
#sup-quotes, #sup-cards, #sup-breakdown{ min-height:260px; }
#reco, #waysin, #market, #classes, #learn, #topharbours, #named{ min-height:240px; }
/* The page-head fact strip is filled from the data and grew the head when it
   landed, moving the whole page under it. */
.phead .facts{ min-height:58px; }
.skel{ min-height:150px; }
/* Filter selects grow as they are populated; a floor stops the row reflowing. */
.filters select{ min-width:132px; }
.filters{ min-height:44px; }

/* ------------------------------------------------------- the water child
   The second mascot draft, used where it was drawn for: a brand moment in the
   band about actually getting afloat, not as an icon. Art unmodified — scaled
   only, never recoloured or restretched. */
.mascot-band{
  margin-top:36px; display:flex; align-items:center; gap:28px; flex-wrap:wrap;
  justify-content:center;
}
.mascot-band img{
  width:min(44vw,400px); height:auto; flex:0 0 auto;
  filter:drop-shadow(0 14px 34px rgba(0,20,50,.34));
}
.mascot-band p{
  flex:1 1 260px; max-width:36ch; color:#CDE3F6; font-size:17px; line-height:1.5;
}
@media (max-width:640px){
  .mascot-band{ gap:14px; margin-top:26px; }
  .mascot-band img{ width:min(72vw,300px); }
  .mascot-band p{ font-size:15.5px; text-align:center; max-width:none; }
}

/* =========================================================================
   NAV v2 — the light shelf bar. Replaces .site-hd / .hd-nav / .lockup above.
   Eight lanes, each opening a full-width shelf of COLUMNS with headings from
   one fixed vocabulary, and a cross bar of the filters that cut across every
   lane. Pure :hover / :focus-within, so it works with the script dead.
   ========================================================================= */
.fs-hd{
  /* 60 put the whole header BELOW the "Say what you're after" guide sheet,
     which is position:fixed at z-index 71 in the root stacking context: the
     open Marketplace and Tools panels were being covered by it, mid-menu.
     The shelf's own z-index:70 could never win, because it is inside the
     header's stacking context and so is capped by the header's. The bar and
     its panels are now above every page-level overlay. */
  position:sticky; top:0; z-index:90; background:rgba(255,255,255,.88);
  -webkit-backdrop-filter:saturate(170%) blur(16px); backdrop-filter:saturate(170%) blur(16px);
  border-bottom:1px solid transparent;
  transition:border-color .34s var(--e2), box-shadow .34s var(--e2), background-color .34s var(--e2);
}
.fs-hd.is-scrolled{ border-bottom-color:var(--line); box-shadow:0 4px 12px rgba(2,43,131,.09); }
.fs-hd::after{
  content:""; position:absolute; left:0; bottom:-1px; width:100%; height:1px;
  background:linear-gradient(90deg,transparent,var(--cyan),transparent);
  opacity:0; transition:opacity .5s var(--e2);
}
.fs-hd.is-scrolled::after{ opacity:.42; }
.fs-hd-in{
  position:relative; max-width:var(--wrap); margin:0 auto; padding:12px 22px 0;
  display:flex; flex-wrap:wrap; align-items:center; gap:clamp(10px,1.5vw,24px); row-gap:0;
  transition:padding-top .34s var(--e1);
}
.fs-hd.is-scrolled .fs-hd-in{ padding-top:7px; }

.fs-brand{ flex:0 0 auto; display:flex; align-items:center; }
.fs-brand .lk{
  height:clamp(46px,4.4vw,64px); width:auto;
  transition:height .34s var(--e1), transform .46s var(--e3), filter .4s var(--e2);
}
.fs-brand:hover .lk{ transform:translateY(-1px) scale(1.012);
  filter:drop-shadow(0 4px 12px rgba(2,43,131,.16)); }
.fs-hd.is-scrolled .fs-brand .lk{ height:clamp(38px,3.6vw,50px); }

/* row two, always. Eight lanes never share a line with the mark and the
   utilities: measured, they need 797px in a 726px slot, and the slot cannot grow
   because --wrap is 1280 at every desktop width. space-between cannot overflow. */
.fs-nav{ order:3; display:flex; align-items:center; justify-content:space-between;
  flex:1 0 100%; margin:8px 0 0; padding:4px 0 5px; gap:6px; min-width:0;
  border-top:1px solid var(--line-2); }
/* ── NAV v3 — panels anchored under their own lane. Rebuilt whole 2026-08-22
   on Kealan's instruction ("complete rebuild … structurally doesn't fit").
   The old shelf was position:absolute left:22 right:22 — full-bleed, re-anchored
   to the header edge, forcing equal columns onto lanes that are really trees.
   Now each panel is content-sized and hangs under its OWN lane, reading as the
   sub-tree he drew: flat items as rows, nested items as their own titled group.
   Still pure :hover / :focus-within to open, so it survives the script dying;
   the last two lanes right-anchor so a content panel can never spill off-screen.
   Precision (one 8px rhythm, one type scale) · restraint (layered soft shadow,
   one quiet motion) · warmth (the cyan→teal sail gradient on the active rule). */
.fs-lane{ position:relative; display:flex; align-items:center; }
.fs-lane>.t{
  display:inline-flex; align-items:center; gap:6px; padding:9px 3px; position:relative;
  font-size:clamp(13.5px,1.05vw,15.5px); font-weight:600; letter-spacing:-.006em;
  color:var(--ink-60); white-space:nowrap; text-decoration:none;
  transition:color .26s var(--e2);
}
.fs-lane>.t::after{ content:""; position:absolute; left:3px; right:100%; bottom:0; height:2px;
  border-radius:2px; background:linear-gradient(90deg,var(--cyan),var(--teal));
  transition:right .34s var(--e3); }
.fs-lane:hover>.t,.fs-lane:focus-within>.t,.fs-lane.is-here>.t{ color:var(--navy); text-decoration:none; }
.fs-lane:hover>.t::after,.fs-lane:focus-within>.t::after,.fs-lane.is-here>.t::after{ right:3px; }
.fs-lane>.t .cv{ width:9px; height:9px; opacity:.5; flex:0 0 auto;
  transition:transform .32s var(--e1), opacity .32s var(--e2); }
.fs-lane:hover>.t .cv,.fs-lane:focus-within>.t .cv{ transform:rotate(180deg); opacity:.9; }

/* the panel — content-sized, hangs under the lane, premium card */
.fs-shelf{
  position:absolute; top:100%; left:-14px; margin-top:10px;
  /* 880 was the cap on the panel's OUTER width while .fs-lay-map asks for
     880 of CONTENT, so the map panel's last column ("Locations") hung 23px
     past the padding and the italic "soon" was sliced in half -- Kealan
     2026-08-23: "one of the menu's text etc is cut off". The cap now clears
     the widest layout plus its 44px of padding. .fs-lay gets max-width:100%
     below as the belt-and-braces: no layout can exceed its panel again, at
     any viewport, whatever width it asks for. */
  width:max-content; max-width:min(940px,94vw);
  max-height:calc(100vh - var(--hd) - 24px); overflow-y:auto; overscroll-behavior:contain;
  padding:16px 18px; background:#fff; border:1px solid var(--line); border-radius:16px;
  box-shadow:0 1px 2px rgba(2,43,131,.05), 0 12px 28px rgba(2,43,131,.10), 0 44px 80px rgba(2,43,131,.11);
  z-index:70;
  opacity:0; visibility:hidden; pointer-events:none; transform:translateY(-6px) scale(.99);
  transform-origin:26px top;
  transition:opacity .2s var(--e2), transform .34s var(--e3), visibility 0s linear .34s;
}
.fs-lane.is-right>.fs-shelf,.fs-shelf-r{ left:auto; right:-14px; transform-origin:calc(100% - 26px) top; }
.fs-lane:hover>.fs-shelf,.fs-lane:focus-within>.fs-shelf,.fs-lane.is-open>.fs-shelf{
  opacity:1; visibility:visible; pointer-events:auto; transform:translateY(0) scale(1);
  transition:opacity .2s var(--e2), transform .4s var(--e3), visibility 0s linear 0s;
}
/* keep the trigger-to-panel gap hoverable so the panel never flickers shut */
.fs-shelf::before{ content:""; position:absolute; top:-14px; left:0; right:0; height:16px; }

/* THE GAP BUG, diagnosed 2026-08-22 (Kealan's screenshots: "Ways in &
   opportunities" showed 5 items, a ~200px void, then "Events / Crew needed"
   stranded at the bottom; "Map" stacked three half-empty rows). Cause:
   flex-wrap:wrap lays groups out in ROWS, and a row's height is set by its
   TALLEST group — a short group next to a tall one leaves the row's own
   empty space below it, then the next row starts even lower, clearing the
   tallest item above. CSS multi-column doesn't row-lock: content flows
   top-to-bottom and fills one column before starting the next, so groups
   stack tightly with no dead vertical space. column-count reads --n (already
   computed per-panel below, in the inline style on .fs-cols) capped at 2, so
   a panel with only one group renders as a single column instead of a
   lopsided empty second one. break-inside:avoid stops a group being split
   across the column break. */
/* ── THE COMPOSITION. Ratified 2026-08-22 after the static lab.
   Columns are now PACKED IN JS (shell.js cols() — an optimal order-preserving
   partition), so this is a plain grid of the columns it produced. It is NOT
   column-count any more: auto-flow decided placement by accident, which is the
   thing Kealan called out. Reading order is top-to-bottom then left-to-right.
   Measured after this change: dead zones 0-10px on every lane, down from ~200px+.
   HIERARCHY IS DRAWN, NOT IMPLIED: a leaf sits at level 0; a parent prints its
   label and hangs its children off a spine. */
.fs-cols{ display:grid; grid-auto-flow:column; grid-auto-columns:minmax(216px,max-content);
  gap:0; align-items:start; }
.fs-col{ position:relative; min-width:0; padding:0 16px;
  opacity:0; transform:translateY(7px);
  transition:opacity .3s var(--e2), transform .42s var(--e3); }
.fs-col + .fs-col{ border-left:1px solid var(--line-2); }
.fs-lane:hover>.fs-shelf .fs-col,.fs-lane:focus-within>.fs-shelf .fs-col,
.fs-lane.is-open>.fs-shelf .fs-col{ opacity:1; transform:none; }
.fs-lane:hover>.fs-shelf .fs-col:nth-child(2),
.fs-lane:focus-within>.fs-shelf .fs-col:nth-child(2){ transition-delay:.04s; }
.fs-lane:hover>.fs-shelf .fs-col:nth-child(3),
.fs-lane:focus-within>.fs-shelf .fs-col:nth-child(3){ transition-delay:.07s; }

/* a LEAF — an entry with no children, at level 0 */
.fs-leaf{ list-style:none; margin:0; padding:0; }
/* a PARENT — label, then its children on a spine */
.fs-par{ margin:9px 0 3px; }
.fs-col>.fs-par:first-child{ margin-top:0; }
.fs-par-h{ font-size:14.5px; font-weight:650; color:var(--navy); padding:5px 10px 3px;
  letter-spacing:-.006em; }
.fs-kids{ list-style:none; margin:0; padding:0 0 0 11px; margin-left:9px;
  border-left:1.5px solid var(--line);
  transition:border-color .3s var(--e2); }
.fs-par:hover>.fs-kids{ border-left-color:var(--teal); }
.fs-kids li a,.fs-kids li .soon{ font-size:14px; }

.fs-col ul{ list-style:none; margin:0; padding:0; }
.fs-col li{ margin:0; }
.fs-col li a{ display:flex; align-items:center; justify-content:space-between; gap:16px;
  padding:7px 10px; border-radius:9px; font-size:14.5px; font-weight:500;
  color:var(--ink-60); line-height:1.3; text-decoration:none;
  transition:color .2s var(--e2), background-color .2s var(--e2); }
.fs-col li a:hover{ color:var(--navy); background:var(--pale); text-decoration:none; }
.fs-col li a .ar{ opacity:0; color:var(--cyan); font-size:14px; transform:translateX(-3px);
  flex:0 0 auto; transition:opacity .22s var(--e2), transform .3s var(--e3); }
.fs-col li a:hover .ar{ opacity:1; transform:translateX(0); }

/* ── the real country search, inline in Map > Countries. Never a dead control:
   if its data cannot load it degrades to the "See all countries" link below. */
/* Selectors match countrySearchRow()'s ACTUAL markup (.fs-cty-srch / .fs-cty-lbl
   / span.ic). An earlier pass styled a .fs-cty-box that does not exist, so the
   magnifier SVG inherited no size and rendered ~200px tall in the panel. */
.fs-cty-row{ list-style:none; }
.fs-cty-lbl{ position:absolute; width:1px; height:1px; overflow:hidden;
  clip:rect(0 0 0 0); white-space:nowrap; }
.fs-cty-srch{ display:flex; align-items:center; gap:7px; margin:2px 10px 6px;
  border:1px solid var(--line); border-radius:9px; padding:7px 10px; background:var(--pale);
  transition:border-color .2s var(--e2), background-color .2s var(--e2); }
.fs-cty-srch:focus-within{ border-color:var(--cyan); background:#fff; }
.fs-cty-srch .ic{ display:flex; flex:0 0 auto; color:var(--ink-40); }
.fs-cty-srch .ic svg{ width:14px; height:14px; display:block; }
.fs-cty-in{ border:0; background:none; outline:none; font:inherit; font-size:13.5px;
  width:100%; min-width:0; color:var(--ink); }
.fs-cty-list{ list-style:none; margin:0 10px 4px; padding:0; max-height:212px; overflow:auto; }
.fs-cty-list li a{ font-size:14px; padding:6px 9px; }
/* the keyboard-highlighted option. shell.js toggles `is-active` on the <li>
   (role=option), so the selector matches the code rather than the code being
   bent to match a guess. */
.fs-cty-list li.is-active > a{ background:var(--pale); color:var(--navy); }
.fs-cty-list li.is-active > a .ar{ opacity:1; transform:translateX(0); }
.fs-cty-none{ font-size:13px; color:var(--ink-25); padding:5px 9px; }

/* utility cluster + the persistent right-hand lane */
.fs-util{ flex:0 0 auto; display:flex; align-items:center; gap:clamp(6px,.9vw,12px);
  margin-left:auto; }
/* THE SEARCH. Structural fix, 2026-08-19: the old field was position:absolute
   inside the flex row, so it contributed ZERO width and lay on top of the last
   two lanes whenever it was wide -- on focus, and permanently under
   prefers-reduced-motion, which hard-set it to 190px. Measured at 1440: the
   input spanned 842-1032 across Deals (839-898) and Tools (916-973).
   Now: a 38px button that NEVER changes size, and a panel under the bar on the
   same geometry as a shelf. No header element can overlay another in any state. */
.fs-srch-btn{ flex:0 0 38px; width:38px; height:38px; border-radius:999px; cursor:pointer;
  border:1px solid var(--line); background:var(--pale); color:var(--ink-40);
  display:inline-flex; align-items:center; justify-content:center; padding:0;
  transition:background-color .26s var(--e2), border-color .26s var(--e2), color .26s var(--e2); }
.fs-srch-btn svg{ width:16px; height:16px; }
.fs-srch-btn:hover{ background:#fff; border-color:#C7D6E8; color:var(--cyan-text); }
.fs-hd.search-open .fs-srch-btn{ background:var(--navy); border-color:var(--navy); color:#fff; }

.fs-search{ position:absolute; top:100%; left:22px; right:22px; margin-top:0; z-index:72;
  display:flex; align-items:center; gap:10px; padding:14px 16px; background:#fff;
  border:1px solid var(--line); border-radius:14px;
  box-shadow:0 4px 12px rgba(2,43,131,.09), 0 30px 70px rgba(2,43,131,.14);
  opacity:0; visibility:hidden; pointer-events:none; transform:translateY(-8px);
  transition:opacity .22s var(--e2), transform .34s var(--e3), visibility 0s linear .34s; }
.fs-hd.search-open .fs-search{ opacity:1; visibility:visible; pointer-events:auto;
  transform:translateY(0);
  transition:opacity .2s var(--e2), transform .38s var(--e3), visibility 0s linear 0s; }
.fs-search .ic{ flex:0 0 18px; color:var(--ink-25); line-height:0; }
.fs-search .ic svg{ width:18px; height:18px; }
.fs-search input{ flex:1 1 auto; min-width:0; border:0; outline:0; background:none;
  font:inherit; font-size:16px; color:var(--ink); }
.fs-search input::placeholder{ color:var(--ink-25); }
.fs-search button{ flex:0 0 auto; padding:9px 18px; border:0; border-radius:999px;
  background:var(--navy); color:#fff; font-weight:700; font-size:14px; cursor:pointer;
  transition:background-color .26s var(--e2), transform .3s var(--e1); }
.fs-search button:hover{ background:var(--navy-deep); transform:translateY(-1px); }

.fs-lane-orgs{ flex:0 0 auto; margin-left:clamp(6px,.9vw,12px); }
.fs-lane-orgs>.t{ padding:10px 18px; border-radius:999px; background:var(--navy); color:#fff;
  font-size:14px; font-weight:700; white-space:nowrap; gap:8px;
  box-shadow:0 2px 10px rgba(2,43,131,.18);
  transition:background-color .28s var(--e2), transform .3s var(--e1), box-shadow .3s var(--e2); }
.fs-lane-orgs>.t::after{ display:none; }
.fs-lane-orgs:hover>.t,.fs-lane-orgs:focus-within>.t{ background:var(--navy-deep); color:#fff;
  transform:translateY(-1px); box-shadow:0 8px 22px rgba(2,43,131,.28); }
.fs-lane-orgs>.t .dot{ width:6px; height:6px; border-radius:50%; background:var(--hl); flex:0 0 auto;
  transition:transform .5s var(--e3), background-color .3s var(--e2); }
.fs-lane-orgs:hover>.t .dot{ transform:scale(1.5); }

/* drawer, reskinned light to match */
.hd-drawer{ background:#fff; border-top:1px solid var(--line); max-height:78vh; overflow-y:auto; }
.hd-drawer h3{ font-size:10.5px; font-weight:700; letter-spacing:.15em; text-transform:uppercase;
  color:var(--ink-25); margin:20px 22px 6px; transition:color .3s var(--e2); }
.hd-drawer a.dw-lane{ display:block; padding:12px 22px; font-size:17px; font-weight:700;
  color:var(--navy); border-bottom:1px solid var(--line-2); text-decoration:none;
  transition:color .24s var(--e2), padding-left .3s var(--e3); }
.hd-drawer a.dw-lane:hover{ padding-left:27px; text-decoration:none; }
.hd-drawer a.dw-sub{ display:block; padding:8px 22px 8px 35px; font-size:14.5px; color:var(--ink-60);
  border-bottom:0; box-shadow:inset 2px 0 0 var(--line);
  transition:color .22s var(--e2), box-shadow .26s var(--e2), padding-left .3s var(--e3); }
.hd-drawer a.dw-sub:hover{ color:var(--navy); box-shadow:inset 2px 0 0 var(--cyan); padding-left:39px; }

/* ---- the band nobody tested: 901–1095px. The lanes take their own full-width
   row rather than being squeezed, so nothing is ever clipped or scrolled away.
   The old build had no rule here at all and hid the damage with overflow-x. --- */
@media (max-width:1380px){ .fs-hd-in{ gap:10px; } }
/* the two-row header is now the BASE rule, so this block no longer restates it;
   it only tightens type and columns where the room genuinely runs out. */
@media (max-width:1319px){
  .fs-lane>.t{ font-size:14px; padding:8px 0; }
  /* NAV v3 panels are content-sized flex, not a grid — the old grid override
     that lived here would have re-imposed columns and broken the wrap. In this
     tight band (900–1319px, before the drawer takes over at 900) the panel is
     capped harder so a centre lane's panel clears BOTH viewport edges; measured
     at 1000px, nothing spills. */
  .fs-shelf{ max-width:min(660px,94vw); }
  /* Below this width the panel cannot hold four tracks without squeezing
     every label into three lines, so the facets fold to two runs instead of
     the layout overflowing its card. */
  .fs-lay-map .fs-facets{ grid-template-columns:repeat(2,minmax(0,1fr)); }
  .fs-lay-grid{ grid-template-columns:repeat(min(var(--mk-cols,4),2),minmax(0,1fr)); }
  .fs-lay-tools{ grid-template-columns:minmax(0,1fr); }
}
@media (max-width:900px){
  .fs-nav{ display:none; }
  .fs-srch-btn{ display:none; }
  .fs-search{ display:none; }
  .fs-lane-orgs>.fs-shelf{ display:none; }
  .fs-hd-in{ flex-wrap:nowrap; padding:0 22px; height:66px; }
  .fs-hd.is-scrolled .fs-hd-in{ height:60px; padding-top:0; }
}
@media (max-width:520px){
  .fs-lane-orgs>.t .lb{ display:none; }
  .fs-lane-orgs>.t{ padding:10px 13px; }
}

/* ------------------------------------------------------------ footer v2
   Full sitemap first, then everything else. Replaces .ft-cols / .ft-blurb. */
.ft-top{ display:grid; grid-template-columns:minmax(210px,1fr) 3.4fr; gap:40px; align-items:start; }
.ft-brand{ display:block; text-decoration:none; }
.ft-brand .mk{ width:62px; height:62px; transition:transform .6s var(--e3); }
.ft-brand:hover .mk{ transform:rotate(-4deg) scale(1.04); }
.ft-name{ font-weight:700; font-size:19px; letter-spacing:-.02em; color:#fff; margin:14px 0 6px; }
.ft-brand p{ margin:0; max-width:30ch; font-size:14px; line-height:1.55; color:#8EA6C6; }
.ft-map{ display:grid; grid-template-columns:repeat(5,minmax(0,1fr)); gap:24px 20px; }
.ft-col h3{ font-size:11px; font-weight:700; letter-spacing:.15em; text-transform:uppercase;
  color:#5F80AD; margin:0 0 10px; transition:color .32s var(--e2); }
.ft-col:hover h3{ color:#9FC0E6; }
.ft-col ul{ list-style:none; margin:0; padding:0; }
.ft-col li{ margin:0 0 5px; }
.ft-col a{ font-size:13.5px; line-height:1.4; display:inline-block; color:#B9CFEA;
  text-decoration:none; transition:color .24s var(--e2), transform .32s var(--e3); }
.ft-col a:hover{ color:#fff; transform:translateX(2px); text-decoration:none; }
.ft-demand{ margin-top:40px; padding:24px 26px; border-radius:14px;
  background:rgba(255,255,255,.045); border:1px solid rgba(255,255,255,.09);
  display:grid; grid-template-columns:1fr auto; gap:20px; align-items:center;
  transition:border-color .34s var(--e2), background-color .34s var(--e2); }
.ft-demand:hover{ border-color:rgba(34,221,249,.34); background:rgba(255,255,255,.06); }
.ft-demand b{ display:block; color:#fff; font-size:19px; letter-spacing:-.018em; }
.ft-demand span{ display:block; color:#8EA6C6; font-size:14px; margin-top:4px; }
.ft-form{ display:flex; gap:9px; }
.ft-form input{ width:min(330px,52vw); padding:11px 14px; border-radius:9px;
  border:1px solid rgba(255,255,255,.18); background:rgba(255,255,255,.06); color:#fff;
  font:inherit; font-size:14.5px;
  transition:border-color .26s var(--e2), background-color .26s var(--e2), box-shadow .26s var(--e2); }
.ft-form input::placeholder{ color:#7C93B4; }
.ft-form input:focus{ outline:0; border-color:var(--hl); background:rgba(255,255,255,.1);
  box-shadow:0 0 0 3px rgba(34,221,249,.16); }
.ft-form button{ padding:11px 20px; border-radius:9px; border:0; background:var(--cyan);
  color:#04223F; font-weight:700; cursor:pointer; white-space:nowrap;
  transition:background-color .26s var(--e2), transform .3s var(--e1), box-shadow .3s var(--e2); }
.ft-form button:hover{ background:var(--hl); transform:translateY(-1px);
  box-shadow:0 6px 18px rgba(34,221,249,.24); }
.ft-base{ margin-top:32px; padding-top:18px; border-top:1px solid rgba(255,255,255,.09);
  display:flex; flex-wrap:wrap; gap:8px 20px; align-items:center; font-size:13px; color:#7C93B4; }
.ft-base .pb{ margin-left:auto; }
@media (max-width:1180px){ .ft-map{ grid-template-columns:repeat(3,minmax(0,1fr)); } }
@media (max-width:900px){ .ft-top{ grid-template-columns:1fr; }
  .ft-map{ grid-template-columns:repeat(2,minmax(0,1fr)); }
  .ft-demand{ grid-template-columns:1fr; } .ft-form input{ width:100%; } }
@media (max-width:560px){ .ft-map{ grid-template-columns:1fr; } .ft-form{ flex-direction:column; } }

/* ---- prefers-reduced-motion. Every animated cluster gets its own guard, so a
   later edit to one cluster cannot silently escape the whole set. ---- */
@media (prefers-reduced-motion:reduce){ .fs-hd,.fs-hd-in,.fs-hd::after{ transition:none; } }
@media (prefers-reduced-motion:reduce){ .fs-brand .lk,.fs-brand:hover .lk{ transition:none; transform:none; } }
@media (prefers-reduced-motion:reduce){ .fs-lane>.t,.fs-lane>.t::after,.fs-lane>.t .cv{ transition:none; } }
@media (prefers-reduced-motion:reduce){ .fs-shelf,.fs-lane:hover>.fs-shelf,
  .fs-lane:focus-within>.fs-shelf,.fs-lane.is-open>.fs-shelf{
  transition:opacity .01ms linear; transform:none; } }
@media (prefers-reduced-motion:reduce){ .fs-col{ transition:none; transform:none; opacity:1; transition-delay:0s; } }
@media (prefers-reduced-motion:reduce){ .fs-col::before,.fs-col:hover::before{ transition:none; transform:none; opacity:0; } }
@media (prefers-reduced-motion:reduce){ .fs-col h3,.fs-col li a,.fs-col li a .ar{ transition:none; transform:none; } }
@media (prefers-reduced-motion:reduce){ .fs-cross,.fs-cross a,.fs-cross b,
  .fs-lane:hover>.fs-shelf .fs-cross,.fs-lane:focus-within>.fs-shelf .fs-cross,
  .fs-lane.is-open>.fs-shelf .fs-cross{ transition:none; transform:none; opacity:1; transition-delay:0s; } }
@media (prefers-reduced-motion:reduce){ .fs-srch-btn{ transition:none; } }
@media (prefers-reduced-motion:reduce){ .fs-search,.fs-hd.search-open .fs-search{
  transition:opacity .01ms linear; transform:none; } }
@media (prefers-reduced-motion:reduce){ .fs-search button,.fs-search button:hover{ transition:none; transform:none; } }
@media (prefers-reduced-motion:reduce){ .fs-lane-orgs>.t,.fs-lane-orgs:hover>.t,.fs-lane-orgs>.t .dot{ transition:none; transform:none; } }
@media (prefers-reduced-motion:reduce){ .hd-drawer a.dw-lane,.hd-drawer a.dw-sub,.hd-drawer h3{ transition:none; } }
@media (prefers-reduced-motion:reduce){ .ft-brand .mk,.ft-brand:hover .mk,.ft-col a,.ft-col h3{ transition:none; transform:none; } }
@media (prefers-reduced-motion:reduce){ .ft-demand,.ft-form input,.ft-form button,.ft-form button:hover{ transition:none; transform:none; } }

/* ---- the small deliberate motions. Class Sails runs 67 eased moves and 17
   reduced-motion guards; one hero effect is not the same thing as many quiet
   ones, and the quiet ones are what make a bar feel built. Draw-only. ---- */
.burger{ transition:border-color .26s var(--e2), background-color .26s var(--e2); }
.burger:hover{ border-color:var(--cyan); background:var(--pale); }
.burger span{ background:var(--navy);
  transition:transform .36s var(--e1), opacity .24s var(--e2), width .3s var(--e2); }
.burger[aria-expanded="true"] span:nth-child(1){ transform:translateY(5px) rotate(45deg); }
.burger[aria-expanded="true"] span:nth-child(2){ opacity:0; width:8px; }
.burger[aria-expanded="true"] span:nth-child(3){ transform:translateY(-5px) rotate(-45deg); }
.hd-drawer{ transition:box-shadow .34s var(--e2); }
.hd-drawer.open{ box-shadow:0 24px 50px rgba(2,43,131,.16); }
.fs-shelf > .fs-cols::before{ content:""; position:absolute; left:0; right:0; top:-14px; height:2px;
  background:linear-gradient(90deg,var(--cyan),var(--teal)); border-radius:2px;
  transform:scaleX(0); transform-origin:0 50%; opacity:0;
  transition:transform .55s var(--e3), opacity .3s var(--e2); }
.fs-lane:hover>.fs-shelf>.fs-cols::before,.fs-lane.is-open>.fs-shelf>.fs-cols::before{
  transform:scaleX(1); opacity:.5; }
.fs-shelf>.fs-cols{ position:relative; }
.ft-demand b{ transition:color .3s var(--e2); }
.ft-demand:hover b{ color:var(--hl); }
.ft-base .pb{ transition:color .3s var(--e2); }
.ft-base:hover .pb{ color:#B9CFEA; }
.fs-lane>.t:active{ transform:translateY(1px); }
.fs-lane>.t{ transition:color .26s var(--e2), transform .18s var(--e2); }
.fs-brand{ border-radius:8px; transition:box-shadow .3s var(--e2); }
.fs-brand:focus-visible{ box-shadow:0 0 0 3px rgba(2,162,238,.35); outline:0; }
@media (prefers-reduced-motion:reduce){ .burger,.burger span,.hd-drawer,.hd-drawer.open{ transition:none; } }
@media (prefers-reduced-motion:reduce){ .fs-shelf>.fs-cols::before{ transition:none; transform:none; opacity:0; } }
@media (prefers-reduced-motion:reduce){ .ft-demand b,.ft-base .pb,.fs-brand{ transition:none; } }

/* the profile control. LOCKED: in the top bar from day one, "Log in" when out. */
.fs-login{ display:inline-flex; align-items:center; gap:7px; padding:8px 13px; border-radius:999px;
  font-size:14px; font-weight:600; color:var(--ink-60); border:1px solid transparent;
  white-space:nowrap; text-decoration:none;
  transition:color .24s var(--e2), background-color .24s var(--e2), border-color .24s var(--e2); }
.fs-login:hover{ color:var(--navy); background:var(--pale); border-color:var(--line); text-decoration:none; }
.fs-login .av{ position:relative; width:19px; height:19px; border-radius:50%;
  background:linear-gradient(140deg,var(--cyan),var(--teal)); transition:transform .4s var(--e3); }
.fs-login:hover .av{ transform:scale(1.1) rotate(8deg); }
.fs-login .av::after{ content:""; position:absolute; inset:-4px; border-radius:50%;
  border:1px solid var(--cyan); opacity:0; transform:scale(.72);
  transition:opacity .34s var(--e2), transform .46s var(--e3); }
.fs-login:hover .av::after{ opacity:.55; transform:scale(1); }
@media (max-width:900px){ .fs-login .lb{ display:none; } }
@media (prefers-reduced-motion:reduce){ .fs-login,.fs-login .av,.fs-login .av::after{ transition:none; transform:none; } }

/* drawer sub-headings — the same fixed column vocabulary as the shelf */
.hd-drawer h4{ font-size:10px; font-weight:700; letter-spacing:.15em; text-transform:uppercase;
  color:var(--ink-25); margin:14px 22px 5px; }
/* Small screens: a bare coloured dot is not a control. Both the profile and the
   persistent For organisations button keep their words down to 360px. */
@media (max-width:900px){ .fs-login .lb{ display:inline; } .fs-login{ padding:7px 10px; } }
@media (max-width:560px){
  .fs-hd-in{ gap:7px; padding:0 14px; }
  .fs-brand .lk{ height:40px; }
  .fs-login{ padding:6px 8px; font-size:13px; gap:5px; }
  .fs-login .av{ width:16px; height:16px; }
  .fs-lane-orgs>.t .lb{ display:inline; }
  .fs-lane-orgs>.t{ padding:8px 12px; font-size:12.5px; gap:6px; }
  .fs-lane-orgs{ margin-left:2px; }
  .burger{ width:36px; height:34px; }
}
@media (max-width:400px){ .fs-login .lb{ display:none; } .fs-login{ padding:6px; } }

/* Below 400px the profile is an avatar with no word, so it must still read as a
   control and still be thumb-sized: a ring, and a 38px target. */
@media (max-width:400px){
  .fs-login{ width:38px; height:38px; padding:0; justify-content:center; border-radius:50%;
    border-color:var(--line); background:var(--pale); }
  .fs-login .av{ width:20px; height:20px; }
  .fs-login .av::after{ opacity:.4; transform:scale(1); }
}

/* ── profile · things you liked ─────────────────────────────────────────── */
.pf-saved-group{margin-bottom:22px}
.pf-saved-grid{display:grid;gap:8px;grid-template-columns:repeat(auto-fill,minmax(190px,1fr));margin-top:9px}
.pf-saved-row{display:flex;flex-direction:column;gap:3px;text-decoration:none;border:1px solid var(--line);
  border-radius:var(--r-s);padding:12px 14px;transition:border-color .15s,background .15s}
a.pf-saved-row:hover{border-color:var(--cyan);background:var(--pale)}
.pf-saved-row b{font-size:15.5px;color:var(--navy)}
.pf-saved-row span{font-size:13px;color:var(--ink-40)}
.pf-saved-img{display:block;height:84px;border-radius:6px;background-size:cover;background-position:center;margin-bottom:6px}
.mkt-ageing{color:var(--orange-text)}
.mkt-stale{color:var(--orange-text);font-weight:600}
.mkt-unchecked{color:var(--ink-25);font-style:italic}

/* ── "soon" — a menu item whose page is a pending build order. Kealan's rule,
   2026-08-22: his diagram is the spec, so an unbuilt page KEEPS its item and is
   flagged rather than dropped or quietly replaced. Not a link, not clickable,
   clearly not-yet — the structure stays his, the state stays honest. */
.fs-col li .soon{
  display:flex; align-items:center; justify-content:space-between; gap:16px;
  padding:7px 10px; border-radius:9px; font-size:14.5px; font-weight:500;
  color:var(--ink-25); line-height:1.3; cursor:default;
}
.fs-col li .soon em{
  font-style:normal; font-size:9.5px; font-weight:700; letter-spacing:.1em;
  text-transform:uppercase; color:var(--ink-40); background:var(--pale);
  border-radius:999px; padding:2px 7px; flex:0 0 auto;
}
.hd-drawer .dw-soon{
  display:flex; align-items:center; justify-content:space-between;
  color:rgba(255,255,255,.42); cursor:default;
}
.hd-drawer .dw-soon em{
  font-style:normal; font-size:9.5px; font-weight:700; letter-spacing:.1em;
  text-transform:uppercase; color:rgba(255,255,255,.55);
  background:rgba(255,255,255,.10); border-radius:999px; padding:2px 7px;
}
.ft-col li .ft-soon{ color:rgba(185,207,234,.45); font-size:14px; cursor:default; }
.ft-col li .ft-soon em{
  font-style:normal; font-size:9px; font-weight:700; letter-spacing:.1em;
  text-transform:uppercase; opacity:.8;
}
@media (prefers-reduced-motion:reduce){ .fs-col li .soon{ transition:none; } }

/* ═══ THE MORPH ═══ one card that slides and resizes between lanes.
   Ratified 2026-08-22 ("morphing panel + ⌘K as a second layer").

   WHY IT IS A SEPARATE ELEMENT, stated accurately — an earlier version of this
   comment claimed the menu survives with JS disabled, and that is FALSE here:
   shell.js injects the whole header, so with JS off there is no bar at all
   (measured, not assumed). The real guarantee is narrower and still worth
   having: the per-lane panels keep their own background, border and shadow
   until boot() has SUCCESSFULLY MEASURED a panel and added `.morph-on`. So if
   the morph code alone throws — a missing element, a layout race, an
   unsupported API — the panels keep their chrome and the menu still looks and
   works correctly. It degrades to the static menu, never to an invisible one. */
.fs-morph{
  position:absolute; z-index:65; top:0; left:0; width:0; height:0;
  background:#fff; border:1px solid var(--line); border-radius:16px;
  box-shadow:0 1px 2px rgba(2,43,131,.05), 0 12px 28px rgba(2,43,131,.10),
             0 44px 80px rgba(2,43,131,.11);
  opacity:0; pointer-events:none;
  transition:opacity .18s var(--e2),
             transform .42s var(--e3), width .42s var(--e3), height .42s var(--e3);
  will-change:transform,width,height;
}
.fs-hd.morph-on .fs-morph.is-on{ opacity:1; }
/* the panels hand their chrome to the morph surface, keeping only their content */
.fs-hd.morph-on .fs-shelf{
  background:transparent; border-color:transparent; box-shadow:none;
}
/* the content still fades in, but the CARD no longer scales — the morph owns
   that movement now, and two objects easing at once reads as jelly. */
.fs-hd.morph-on .fs-lane:hover>.fs-shelf,
.fs-hd.morph-on .fs-lane:focus-within>.fs-shelf,
.fs-hd.morph-on .fs-lane.is-open>.fs-shelf{ transform:none; }
.fs-hd.morph-on .fs-shelf{ transform:none; }

@media (prefers-reduced-motion:reduce){
  .fs-morph{ transition:opacity .01s linear; }
}

/* ═══ ⌘K — the command palette. The second layer, ALONGSIDE the menu.
   Opens on ⌘K / Ctrl+K or the magnifier. It indexes the same tree the menu is
   built from, so the two can never disagree about what exists. A "soon" entry
   is listed but flagged and not selectable — same honesty rule as the menu. */
html.fs-pal-open{ overflow:hidden; }
.fs-pal{
  position:fixed; inset:0; z-index:200; display:flex; justify-content:center;
  align-items:flex-start; padding:14vh 20px 20px;
  background:rgba(2,27,60,.34);
  -webkit-backdrop-filter:blur(3px); backdrop-filter:blur(3px);
  animation:fs-pal-in .16s var(--e2);
}
.fs-pal[hidden]{ display:none; }
@keyframes fs-pal-in{ from{opacity:0} to{opacity:1} }
.fs-pal-card{
  width:min(620px,100%); background:#fff; border:1px solid var(--line);
  border-radius:16px; overflow:hidden;
  box-shadow:0 8px 24px rgba(2,43,131,.14), 0 40px 90px rgba(2,43,131,.22);
  animation:fs-pal-rise .26s var(--e3);
}
@keyframes fs-pal-rise{ from{opacity:0;transform:translateY(-8px) scale(.985)} to{opacity:1;transform:none} }
.fs-pal-top{ display:flex; align-items:center; gap:10px; padding:14px 16px;
  border-bottom:1px solid var(--line-2); }
.fs-pal-top .ic{ display:flex; color:var(--ink-40); flex:0 0 auto; }
.fs-pal-top .ic svg{ width:17px; height:17px; display:block; }
.fs-pal-top input{ flex:1 1 auto; min-width:0; border:0; outline:none; background:none;
  font:inherit; font-size:16.5px; color:var(--ink); }
.fs-pal-top kbd{ flex:0 0 auto; font:inherit; font-size:10.5px; font-weight:600;
  letter-spacing:.06em; text-transform:uppercase; color:var(--ink-40);
  background:var(--pale); border:1px solid var(--line); border-radius:6px; padding:3px 7px; }
.fs-pal-list{ list-style:none; margin:0; padding:6px; max-height:min(52vh,420px); overflow:auto; }
.fs-pal-list li[role=option]{ display:flex; align-items:baseline; gap:10px;
  padding:9px 12px; border-radius:9px; cursor:pointer; }
.fs-pal-list li.is-active{ background:var(--pale); }
.fs-pal-list li .l{ font-size:15px; font-weight:500; color:var(--navy); }
.fs-pal-list li .t{ font-size:12.5px; color:var(--ink-25); margin-left:auto;
  white-space:nowrap; overflow:hidden; text-overflow:ellipsis; max-width:52%; }
.fs-pal-list li[data-soon] .l{ color:var(--ink-25); }
.fs-pal-list li[data-soon]{ cursor:default; }
.fs-pal-list li em{ font-style:normal; font-size:8.5px; font-weight:700; letter-spacing:.1em;
  text-transform:uppercase; color:var(--ink-25); background:var(--line-2);
  border-radius:999px; padding:2px 6px; }
.fs-pal-none{ padding:14px 12px; font-size:14px; color:var(--ink-25); }
@media (prefers-reduced-motion:reduce){
  .fs-pal,.fs-pal-card{ animation:none; }
}

/* ═══════════════════════════════════════════════════════════════════════
   NAV v5 — THE VISUAL LANGUAGE. Rebuilt 2026-08-22 on Kealan's critique.

   What he named, and what each answers:
   · "opaque white-card feeling"        -> the panel now shares the HEADER's own
       material (translucent, saturated, blurred) so the bar and the panel read
       as one continuous surface and the page stays faintly present beneath it.
       This is depth by material, not a glass pastiche — the reference was a
       level of finish, never an instruction to use glass.
   · "the cyan top line / underline I dislike" -> both deleted. The active lane
       is now a solid navy TAB, and the panel carries a matching notch, so the
       relationship is structural instead of decorative.
   · "generic three-column + vertical-divider grammar" -> every column rule is
       gone. Grouping is carried by whitespace and type, so a separator can
       never imply a hierarchy the taxonomy does not have.
   · "weak relationship between the active nav item and the panel it opens"
       -> the tab and the notch. The panel is visibly hanging off ITS lane.
   · "a sitemap rendered into a dropdown" -> larger rows, real leading, a
       quieter label, and the brand's own horizon tint at the panel's foot.
   ═══════════════════════════════════════════════════════════════════════ */

/* ---- the lane trigger: a tab, not an underline ---- */
.fs-lane>.t::after{ display:none; }          /* the cyan rule he disliked — gone */
.fs-lane>.t{
  border-radius:10px 10px 0 0; padding:9px 12px 10px;
  transition:color .2s var(--e2), background-color .24s var(--e2);
}
.fs-lane:hover>.t,.fs-lane:focus-within>.t,.fs-lane.is-open>.t{
  color:#fff; background:var(--navy);
}
.fs-lane.is-here>.t{ color:var(--navy); background:transparent; }
.fs-lane.is-here:hover>.t{ color:#fff; background:var(--navy); }
.fs-lane.is-here>.t .lb-dot{ background:var(--cyan); }
.fs-lane:hover>.t .cv,.fs-lane:focus-within>.t .cv{ opacity:.85; }

/* ---- the panel: the header's material, continued ---- */
.fs-shelf{
  /* SOLID, not translucent — Kealan 2026-08-22: "some dropdown/menu areas are
     still rendering see-through/transparently, visible especially around
     Tools." At .965 with a blur, ~3.5% of the page read through the card, and
     Tools is the widest panel so it sat over the most hero artwork. Depth now
     comes from the shadow and the horizon tint at the foot, not from the page
     bleeding through the text. */
  background:#fff;
  border:1px solid rgba(2,43,131,.10);
  border-radius:4px 16px 16px 16px;          /* squared into its own tab */
  box-shadow:0 1px 1px rgba(2,43,131,.04),
             0 10px 24px rgba(2,43,131,.09),
             0 40px 80px rgba(2,43,131,.13);
  padding:20px 22px 18px;
  margin-top:0;                               /* the tab and panel touch */
}
.fs-lane.is-right>.fs-shelf{ border-radius:16px 4px 16px 16px; }
.fs-shelf::before{ top:-10px; height:12px; }  /* keep the hover bridge */
/* the cyan rule that used to sit across the panel top — gone */
.fs-shelf > .fs-cols::before{ display:none; }
/* the brand's horizon, very faint, at the foot of the panel: opening the nav
   should extend Free Sailing's character, not replace it with a white box */
.fs-shelf::after{
  content:""; position:absolute; left:0; right:0; bottom:0; height:64px;
  border-radius:0 0 16px 16px; pointer-events:none;
  background:linear-gradient(180deg,rgba(2,162,238,0),rgba(1,185,186,.055));
}
.fs-hd.morph-on .fs-shelf::after{ display:none; }   /* the morph owns the card */

/* the morph surface takes the same material, so the card that travels between
   lanes is the same object the lane hands over */
.fs-morph{
  /* SOLID, not translucent — Kealan 2026-08-22: "some dropdown/menu areas are
     still rendering see-through/transparently, visible especially around
     Tools." At .965 with a blur, ~3.5% of the page read through the card, and
     Tools is the widest panel so it sat over the most hero artwork. Depth now
     comes from the shadow and the horizon tint at the foot, not from the page
     bleeding through the text. */
  background:#fff;
  border:1px solid rgba(2,43,131,.10);
  border-radius:4px 16px 16px 16px;
  box-shadow:0 1px 1px rgba(2,43,131,.04),
             0 10px 24px rgba(2,43,131,.09),
             0 40px 80px rgba(2,43,131,.13);
}
.fs-morph.is-right{ border-radius:16px 4px 16px 16px; }

/* ---- type and rows: give the menu presence ---- */
.fs-col{ padding:0; }
.fs-col + .fs-col{ border-left:0; }           /* every column divider — gone */
.fs-cols{ display:block; }

.fs-lay{ min-width:0; max-width:100%; }
.fs-sibs{ list-style:none; margin:0; padding:0; }
.fs-sibs.is-two{ columns:2; column-gap:34px; }
.fs-sibs.is-two > li{ break-inside:avoid; }
.fs-sibs.is-row{ display:flex; flex-wrap:wrap; gap:2px 6px; }

.fs-col li a,.fs-sibs li a,.fs-sub-l li a{
  display:flex; align-items:center; justify-content:space-between; gap:18px;
  padding:8px 10px; border-radius:9px;
  font-size:15px; font-weight:500; color:var(--ink-60); line-height:1.35;
  text-decoration:none;
  transition:color .18s var(--e2), background-color .18s var(--e2);
}
.fs-col li a:hover,.fs-sibs li a:hover,.fs-sub-l li a:hover{
  color:var(--navy); background:rgba(2,43,131,.055); text-decoration:none;
}
.fs-col li a .ar,.fs-sibs li a .ar,.fs-sub-l li a .ar{
  opacity:0; color:var(--cyan-text); font-size:13px; transform:translateX(-4px);
  flex:0 0 auto; transition:opacity .2s var(--e2), transform .28s var(--e3);
}
.fs-col li a:hover .ar,.fs-sibs li a:hover .ar,.fs-sub-l li a:hover .ar{
  opacity:1; transform:translateX(0);
}

/* ---- a real subtree. The ONE place nesting exists is the one place it shows:
   a contained block with its own quiet ground, not a column heading. ---- */
.fs-sub{
  border-radius:12px; padding:11px 12px 9px;
  background:rgba(2,43,131,.032);
}
.fs-sub-h{
  font-size:11px; font-weight:700; letter-spacing:.12em; text-transform:uppercase;
  color:var(--ink-40); padding:0 10px 7px;
}
.fs-sub-l{ list-style:none; margin:0; padding:0; }
.fs-sub-l.is-two{ columns:2; column-gap:26px; }
.fs-sub-l.is-two > li{ break-inside:avoid; }
.fs-sub-l li a{ font-size:14.5px; }

/* ---- per-lane layouts ---- */
/* DEFINITE WIDTHS, and the reason matters: the panel is width:max-content, and
   an auto-fit grid inside a max-content box has no width to fit against, so it
   collapsed to ONE column — Marketplace rendered 232px wide and 746px tall.
   Each layout therefore states the width its own shape needs; the panel then
   sizes to it. */
/* Tracks and width both follow the real group count, set by shell.js as
   --mk-cols / --mk-w. Hard-coding four tracks left an empty fourth beside
   "Free & cheap" once the lane had three groups, and stretched the two-group
   For-organisations panel across a four-group width. */
.fs-lay-grid{ display:grid; gap:14px; align-items:start;
  grid-template-columns:repeat(var(--mk-cols,4),minmax(0,1fr));
  width:min(var(--mk-w,760px),86vw); }
.fs-lay-map{ display:flex; flex-direction:column; gap:14px; }
/* 4 facets at 720px gave ~190px columns and 'Less than 10 kilometers'
   wrapped to three lines. 880 gives ~215px and the labels sit on one or two. */
.fs-lay-map{ width:min(880px,90vw); }
.fs-lay-map .fs-facets{ display:grid; grid-template-columns:repeat(4,minmax(0,1fr)); gap:14px;
  align-items:start; }
.fs-away{ display:flex; align-items:center; gap:12px; flex-wrap:wrap;
  padding-top:12px; border-top:1px solid rgba(2,43,131,.07); }
.fs-away-h{ font-size:10.5px; font-weight:700; letter-spacing:.13em;
  text-transform:uppercase; color:var(--ink-25); }
.fs-away .fs-sibs li a{ padding:6px 10px; font-size:14px; }

.fs-lay-tools{ display:grid; grid-template-columns:minmax(0,1.5fr) minmax(0,1fr); gap:18px;
  width:min(820px,88vw); }
.fs-lay-tools .fs-rail{ display:flex; flex-direction:column; gap:12px; }
.fs-sub.is-wide{ background:rgba(2,43,131,.032); }

.fs-lay-index{ display:flex; flex-direction:column; gap:16px; width:min(560px,84vw); }
.fs-lay-index .fs-subs{ display:grid; grid-template-columns:repeat(auto-fit,minmax(230px,1fr)); gap:14px; }

/* the "soon" row keeps its recessive treatment in the new type scale */
.fs-col li .soon,.fs-sibs li .soon,.fs-sub-l li .soon{
  display:flex; align-items:center; justify-content:space-between; gap:18px;
  padding:8px 10px; border-radius:9px; font-size:15px; font-weight:500;
  color:var(--ink-25); line-height:1.35; cursor:default;
}
.fs-sub-l li .soon{ font-size:14.5px; }

@media (prefers-reduced-motion:reduce){
  .fs-lane>.t{ transition:none; }
}

/* ── CASCADE FIX. The NAV v5 block above re-declares .fs-shelf's background,
   border and shadow, and it sits LATER in this file than the .morph-on rules —
   so the panel got its card back and rendered stacked on top of the morph
   surface: two overlapping white cards, visible immediately in a screenshot and
   invisible to every geometry check I had. Restated here, last, so the morph
   owns the card whenever it is running. */
.fs-hd.morph-on .fs-shelf{
  background:transparent; border-color:transparent; box-shadow:none;
  -webkit-backdrop-filter:none; backdrop-filter:none;
}

.fs-lay-tools .fs-main{ display:flex; flex-direction:column; gap:12px; }

/* ═══════════════════════════════════════════════════════════════════════
   THE DROPDOWN STATE BUG — one root cause, four symptoms.

   Kealan, 2026-08-22: "sometimes the dropdowns become see-through when i tap
   between tabs · they are not consistently white/opaque · old dropdowns do not
   always disappear cleanly · when I select another top navigation tab, the new
   and old dropdowns can overlap."

   CAUSE. Panels open on pure CSS `:hover`/`:focus-within` (deliberately, so
   the menu still works if the script dies) AND on `.is-open`, which the JS
   state machine sets. Those are two independent openers. Once the morph card
   is running, `.fs-hd.morph-on .fs-shelf` is TRANSPARENT because the morph is
   meant to be the only visible surface — so any panel opened by the CSS path
   alone renders its text with NO card behind it. That is the see-through.
   And because :hover and .is-open can be true on DIFFERENT lanes at the same
   moment, two panels can be up at once, over a single card. That is the
   overlap and the "old one didn't disappear".

   FIX. Once `.morph-on` is proven live, the CSS opener is switched off and the
   JS state machine becomes the ONLY thing that opens a panel — it owns
   `openLane`, so exactly one can be open and it always has a card under it.
   Nothing is lost if the script dies: `.morph-on` is only ever added after a
   successful measurement, so the hover-only fallback still governs.
   ═══════════════════════════════════════════════════════════════════════ */
.fs-hd.morph-on .fs-lane:hover > .fs-shelf,
.fs-hd.morph-on .fs-lane:focus-within > .fs-shelf{
  opacity:0; visibility:hidden; pointer-events:none;
  transform:translateY(-6px) scale(.99);
}
.fs-hd.morph-on .fs-lane.is-open > .fs-shelf{
  opacity:1; visibility:visible; pointer-events:auto; transform:none;
}
/* the per-column entrance staggers keyed off :hover must follow the same
   owner, or a hovered-but-not-open panel animates its columns in invisibly
   and then flashes them when it does open */
.fs-hd.morph-on .fs-lane:hover > .fs-shelf .fs-col,
.fs-hd.morph-on .fs-lane:focus-within > .fs-shelf .fs-col{ opacity:0; }
.fs-hd.morph-on .fs-lane.is-open > .fs-shelf .fs-col{ opacity:1; transform:none; }

/* ---- SEE ALSO / WSD-MAP / ODD-PAIR: horizontal strips at the foot ----
   Kealan 2026-08-22: "See Also should always be a horizontal strip at the
   bottom of the menu, not a right-hand column." A strip is a quiet full-width
   band, separated by a hairline rather than by a card, so it reads as an
   afterword to the panel instead of a fifth column competing with the real
   taxonomy. Three long grey rows is exactly the intended look. */
.fs-strip{
  display:flex; align-items:center; gap:14px; flex-wrap:wrap;
  margin-top:14px; padding-top:12px;
  border-top:1px solid rgba(2,43,131,.08);
}
.fs-strip.is-wide{ grid-column:1 / -1; }
.fs-strip-wrap{ grid-column:1 / -1; }
.fs-strip.is-solo{ border-top:0; padding-top:0; margin-top:12px; }
.fs-strip-h{
  font-size:10.5px; font-weight:700; letter-spacing:.13em; text-transform:uppercase;
  color:var(--ink-25); flex:0 0 auto;
}
.fs-strip-l{
  list-style:none; margin:0; padding:0;
  display:flex; flex-wrap:wrap; gap:6px; flex:1 1 auto; min-width:0;
}
.fs-strip-l li{ flex:1 1 auto; }
.fs-strip-l li a,.fs-strip-l li .soon{
  display:flex; align-items:center; justify-content:space-between; gap:12px;
  padding:9px 13px; border-radius:10px; background:rgba(2,43,131,.032);
  font-size:14.5px; font-weight:500; color:var(--ink-60); line-height:1.3;
  white-space:nowrap;
}
.fs-strip-l li a:hover{ background:rgba(2,43,131,.07); color:var(--navy); }
.fs-strip-l li .soon{ color:var(--ink-25); }
/* the solo strip (World Sailing Day map) is one full-width row, not chips */
.fs-strip.is-solo .fs-strip-l li{ flex:1 1 100%; }
.fs-lay-mk{ display:flex; flex-direction:column; }
.fs-lay-tools{ align-items:start; }

/* =========================================================================
   ⚠ TEMPORARY — NAV TREATMENT COMPARISON, 2026-08-24 (round 2).
   DELETE with the matching block in shell.js once Kealan picks — search
   "NAV TREATMENT COMPARISON".

   ROUND 1 IS DEAD AND WHY IT DIED IS THE USEFUL PART. Painting the whole
   .fs-hd navy gave a 133px navy SLAB, because this header is two rows
   (brand+utilities, then lanes) where classhub-site's was one. Kealan:
   "especially the huge blue ( since it colours two strips at the top) - so
   objectively its just not it". He is right, and there is a second, harder
   defect he spotted from the same screenshots: on Marketplace the navy
   header dissolves into the navy hero band with no edge at all. Several
   pages carry a navy/gradient .band hero, so ANY treatment whose bottom-most
   band is dark can merge into the page below it.

   THE STRUCTURAL RULE THIS ROUND IS BUILT ON:
   keep the header's LAST band light, and it can never merge into a hero,
   on any page, without needing a per-page exception. B and C obey that by
   construction. A obeys it only where the class bar exists, which is why A
   is the riskiest of the three and is labelled as such in the switcher.

   MEASURED, not assumed (1400px viewport, DevTools):
   usable 1236 · brand 111 + lanes 800 + utilities 206 = 1117, ~60px slack.
   So one row DOES fit — site.css's own note above ("Eight lanes never share
   a line with the mark and the utilities") is STALE: NAV holds six lanes
   now, not eight. It stops fitting near 1240px, so A falls back to B's
   two-band form below that rather than overflowing.

   THE LOGO IS NEVER RECOLOURED, in any treatment. classhub-site put the
   unmodified colour mark on a pale plate over its navy
   (`.lockup .mark{background:#EDF2F9}`, its site.css:71) — necessary, not
   decorative: the wordmark's own navy is #12379B against a #022B83 bar.
   ========================================================================= */

/* shared: the pale plate, wherever the mark sits on navy */
html[data-hd="thin"] .fs-brand,
html[data-hd="stair"] .fs-brand{
  background:#EDF2F9; border-radius:7px; padding:3px 9px;
  transition:background .3s var(--e2);
}
html[data-hd="thin"] .fs-brand:hover,
html[data-hd="stair"] .fs-brand:hover{ background:#fff; }
html[data-hd="thin"] .fs-brand:hover .lk,
html[data-hd="stair"] .fs-brand:hover .lk{ filter:none; }

/* shared: utilities on a navy band */
html[data-hd="thin"] .fs-srch-btn,
html[data-hd="stair"] .fs-srch-btn{
  background:rgba(255,255,255,.12); border-color:rgba(255,255,255,.22); color:#fff;
}
html[data-hd="thin"] .fs-srch-btn:hover,
html[data-hd="stair"] .fs-srch-btn:hover{ background:rgba(255,255,255,.2); }
html[data-hd="thin"] .fs-login,
html[data-hd="stair"] .fs-login{ color:#fff; border-color:rgba(255,255,255,.3); }
html[data-hd="thin"] .burger span,
html[data-hd="stair"] .burger span{ background:#fff; }

/* ── A · THIN MASTHEAD ─────────────────────────────────────────────────────
   classhub's actual proportion: ONE navy row carrying mark + lanes +
   utilities, then the white class bar. Navy mass drops 133px → ~62px, less
   than half of round 1. The truest reproduction of what he liked — and the
   one that can still touch a navy hero on pages with no class bar. */
@media (min-width:1240px){
  html[data-hd="thin"] .fs-hd{
    background:var(--navy);
    -webkit-backdrop-filter:none; backdrop-filter:none;
    border-bottom-color:rgba(255,255,255,.14);
  }
  html[data-hd="thin"] .fs-hd-in{ flex-wrap:nowrap; padding:7px 22px; gap:16px; }
  html[data-hd="thin"] .fs-hd.is-scrolled .fs-hd-in{ padding:4px 22px; }
  html[data-hd="thin"] .fs-brand .lk{ height:36px; }
  html[data-hd="thin"] .fs-hd.is-scrolled .fs-brand .lk{ height:32px; }
  html[data-hd="thin"] .fs-nav{
    order:2; flex:1 1 auto; margin:0; padding:0; border-top:0; gap:2px;
  }
  /* .fs-util carries no `order` of its own, so at the default 0 it sorted
     BEFORE the nav's order:2 — mark, utilities, then lanes. Reading order on
     one row has to be mark → lanes → utilities. */
  html[data-hd="thin"] .fs-util{ order:3; }
  /* LOCKED: "persistent right-hand For organisations". It is a direct child of
     .fs-hd-in at the default order 0, so on one row it sorted next to the mark,
     on the far LEFT — the opposite of the decision. Pinned last. */
  html[data-hd="thin"] .fs-lane-orgs{ order:4; margin-left:0; }
  html[data-hd="thin"] .fs-lane>.t{ color:rgba(255,255,255,.82); font-size:14px; padding:7px 3px; }
  html[data-hd="thin"] .fs-lane:hover>.t,
  html[data-hd="thin"] .fs-lane:focus-within>.t,
  html[data-hd="thin"] .fs-lane.is-here>.t{ color:#fff; }
}
/* below the measured fit, A degrades into B rather than overflowing */
@media (max-width:1239px){
  html[data-hd="thin"] .fs-hd{ background:var(--navy); -webkit-backdrop-filter:none; backdrop-filter:none; }
  html[data-hd="thin"] .fs-nav{ position:relative; border-top:0; margin-top:7px; }
  html[data-hd="thin"] .fs-nav::before{
    content:""; position:absolute; top:0; bottom:0; left:-50vw; right:-50vw;
    background:#EFF4FA; z-index:0;
  }
  html[data-hd="thin"] .fs-lane, html[data-hd="thin"] .fs-lane-orgs{ position:relative; z-index:1; }
}

/* ── B · TONAL STAIRCASE ───────────────────────────────────────────────────
   navy masthead (mark + utilities only, ~70px) → pale lane band → white
   class bar. Three descending tones, so the blue stays a masthead instead of
   a slab, and the header's last band is always light. Blue on top with
   smaller lighter bars beneath it — his description, taken literally. */
html[data-hd="stair"] .fs-hd{
  background:var(--navy);
  -webkit-backdrop-filter:none; backdrop-filter:none;
  border-bottom-color:transparent;
}
html[data-hd="stair"] .fs-hd-in{ padding-top:9px; }
html[data-hd="stair"] .fs-brand .lk{ height:clamp(40px,3.4vw,48px); }
html[data-hd="stair"] .fs-nav{
  position:relative; border-top:0; margin-top:8px; padding:5px 0 6px;
}
/* full-bleed pale band behind row two, without touching the DOM */
html[data-hd="stair"] .fs-nav::before{
  content:""; position:absolute; top:0; bottom:0; left:-50vw; right:-50vw;
  background:#EFF4FA; z-index:0;
}
html[data-hd="stair"] .fs-lane,
html[data-hd="stair"] .fs-lane-orgs{ position:relative; z-index:1; }

/* ── C · INVERTED ──────────────────────────────────────────────────────────
   Global chrome stays light and untouched; the CLASS bar is the navy one.
   Least blue of the three, and the only one that gives the class hub its own
   identity — you can see you are inside the Melges 24 hub, not on a page that
   happens to be about it. Trade: blue sits under white, not over it. */
html[data-hd="invert"] .classbar{
  background:var(--navy); border-bottom-color:transparent;
  box-shadow:0 1px 0 rgba(2,43,131,.16);
}
html[data-hd="invert"] .classbar .cb-name{ color:#fff; }
html[data-hd="invert"] .classbar .cb-name em{ color:rgba(255,255,255,.58); }
html[data-hd="invert"] .classbar a{ color:rgba(255,255,255,.76); }
html[data-hd="invert"] .classbar a:hover{ color:#fff; }
html[data-hd="invert"] .classbar a.is-active{ color:#fff; border-bottom-color:var(--cyan); }

/* ---- the switcher itself (temporary chrome, bottom-LEFT to clear the mascot) */
.navtry{
  position:fixed; left:14px; bottom:14px; z-index:400;
  background:#0B1B33; color:#fff; border-radius:12px; padding:9px 10px 10px;
  box-shadow:0 12px 34px rgba(2,20,50,.4); font-size:12px; max-width:300px;
}
.navtry b{ display:block; font-size:10.5px; letter-spacing:.1em; text-transform:uppercase;
  color:#8FB6DE; margin-bottom:7px; }
.navtry .row{ display:flex; gap:5px; flex-wrap:wrap; }
.navtry button{
  font:inherit; font-size:11.5px; cursor:pointer; padding:6px 9px; border-radius:7px;
  border:1px solid rgba(255,255,255,.24); background:rgba(255,255,255,.08); color:#fff;
}
.navtry button:hover{ background:rgba(255,255,255,.18); }
.navtry button.on{ background:#fff; color:#0B1B33; border-color:#fff; font-weight:700; }
.navtry p{ margin-top:8px; color:#9DBCDD; font-size:11px; line-height:1.45; }
.navtry p em{ color:#CFE2F5; font-style:normal; }
