/* ─────────────────────────────────────────────────────────────
   CometFare Sky Header — edge-to-edge TRANSPARENT top nav.

   Design language (rebuild, 2026-07-28):
   - The bar itself is not a surface. No background, no border, no
     radius, no margins: it spans the full viewport width and sits
     flush against the top edge. The only thing painting behind it
     is a black scrim that fades out downward, so the controls stay
     readable over whatever the page puts up there.
   - Every *control* is the surface: solid black with a sky-blue
     border. The brand icon is a black circle, the "Open app" CTA is
     a black pill, and the Explore/App/Policy triggers are invisible
     until hover, when they take the same black + blue treatment.
   - Menus follow the controls: black panels, blue border.

   ⚠️ SINGLE SOURCE OF TRUTH (2026-08-04). index.html's nav is the canonical
   one; blog, discover, releases, support and voyager carry byte-identical
   markup (only `aria-current="page"` differs) and this file is the only
   place any of it is styled. Page-level and dark-pages.css nav overrides were
   deleted — do not reintroduce them. A change made here is meant to land on
   every page at once; that is the point.

   Canonical markup:
   <nav class="sky-nav">
     <a class="sky-brand" href="./index.html" aria-label="CometFare home">
       <span class="sky-brand-mark">
         <svg class="sky-brand-svg sky-brand-svg-right" viewBox="0 0 30 25" …>
           <g class="sky-brand-ear sky-brand-ear-right">…two paths…</g>
         </svg>
         <svg class="sky-brand-svg sky-brand-svg-left" viewBox="0 0 30 25" …>
           <g class="sky-brand-ear sky-brand-ear-left">…two paths…</g>
         </svg>
       </span>
       <span class="sky-brand-word"></span>   <!-- NOT on index.html -->
     </a>
     <div class="sky-nav-links">
       <div class="sky-nav-group">
         <span class="sky-nav-trigger">Explore</span>
         <div class="sky-nav-menu"><div class="sky-nav-menu-inner">…links…</div></div>
       </div>
       …
     </div>
     <a class="sky-nav-cta" id="sky-nav-cta" href="./releases.html" data-state="download">
       <svg class="sky-nav-cta-glyph">…windows mark…</svg>
       <img class="sky-nav-cta-avatar" src="…" alt="" hidden>
       <span class="sky-nav-cta-label">Download<span class="sky-nav-cta-label-rest"> for Windows</span></span>
     </a>

   The Windows mark and label in that markup are only the fallback: on load
   cometfare-sky-header.js swaps in the visitor's own OS (Windows / Mac /
   Linux) and records it on the pill as `data-platform`.
   </nav>
   <div class="sky-nav-dim"></div>

   The wordmark <span> is on all 7 non-index pages and on none of the home
   page — see the .sky-brand-word block for why, before you "fix" the
   inconsistency. cometfare-sky-header.js flips the CTA between its
   `download` and `app` states once it knows whether the visitor is signed in.

   ⚠️ The mark is INLINE SVG, not an <img>, and it has to stay that way: the
   hover glow and the click flutter both address the two ear <g>s
   individually, which nothing outside the document can do. The source of
   truth for the path data is BrandedSVG/Fareicon1.svg — if you re-export it,
   re-inline it on all 8 pages and keep the two `sky-brand-ear-*` classes,
   because the SVG's own `.cls-1` / `.cls-2` fills are deliberately stripped
   in favour of the custom properties on .sky-brand-mark.
   ───────────────────────────────────────────────────────────── */

:root {
    --skyui-blue: #3fa4f6;
    --skyui-blue-deep: #1f7fd6;
    /* soft darker-blue wash layered over flat blue surfaces (shared with
       the footer and the page-level --sky-shade so all blue matches) */
    --skyui-shade: linear-gradient(160deg, rgba(8, 48, 100, 0) 0%, rgba(8, 48, 100, 0.14) 40%, rgba(8, 48, 100, 0.42) 100%);
    --skyui-ink: #000000;
    --skyui-soft-ink: rgba(0, 0, 0, 0.6);
    --skyui-white: #ffffff;
    --skyui-radius: 26px;

    /* ── new core tokens ── */
    /* ⚠️ --skyui-black IS NO LONGER BLACK (2026-07-29). Every control's
       surface used to be flat #000000, which next to the pale blue type
       read as a dead hole in the page. It is now the top step of the site
       grey ramp — the chat's Classic/no-image grey (#222222) lifted twice,
       with one value added to blue. It must stay equal to --cf-nav-slab in
       cometfare-dark-pages.css. The name is historical, like
       --skyui-beige below. */
    --skyui-black: #1a1a1a;          /* every control's surface: top of the grey ramp */
    --skyui-bar-h: 52px;             /* nav content height, flush to the top edge */

    /* ── RESTING vs SELECTED (2026-07-28) ──
       One rule across the whole header, matching the hero's download CTA:
       type and edges are PALE BLUE at rest, and turn BLUE the moment a control is
       engaged — hovered, focused, or holding an open menu. The vivid blue is
       the selection signal only; it is no longer the resting colour of anything.
       --skyui-white is kept because other rules still reference it, but it is
       no longer what nav labels are painted with.

       ⚠️ --skyui-beige IS NOT BEIGE. The name is historical: this token has
       held the resting colour through beige → periwinkle → (2026-07-29) the
       pale blue below, and it is read by five rules in this file. Read it as
       "the resting colour", and change the value here — not the name. Its
       partner --skyui-blue is the engaged colour. */
    --skyui-beige: #e9edf0;      /* resting: industrial white (2026-07-29 test; was pale blue #b3d6ff, was periwinkle #c9b3ff) */
    /* the resting edge is the resting COLOUR at half strength — it tracks
       --skyui-beige (industrial white), not the pale blue it used to be */
    --skyui-edge: 2px solid rgba(233, 237, 240, 0.5);       /* resting border */
    --skyui-edge-active: 2px solid var(--skyui-blue);       /* engaged border */

    /* ── ENGAGED SURFACE (2026-08-04) ──
       Hover/focus on any control now inverts to a WHITE plate with blue type
       and blue icons, instead of the grey plate with blue type it used to be.
       One pair of tokens so the triggers, the CTA and the menu rows all move
       together. */
    --skyui-engaged-surface: #ffffff;
    --skyui-engaged-ink: var(--skyui-blue-deep);

    /* ── POPUP DRAWERS (2026-08-04) ──
       The menus used to sit a step BRIGHTER than the bar (grey plate, 2px
       pale edge), which made them read as the loudest thing on screen while
       being the most transient. Inverted: they now sit a step DARKER than the
       controls, so the drawer recedes and the hovered row is what carries.
       Borderless — the panel is held off the bar by its drop shadow. The
       --skyui-menu-edge hem (1px #050505) was dropped the same day: against
       a dark bar it read as a hard black outline, not an edge. */
    --skyui-menu-surface: #101010;
}

.sky-nav {
    position: fixed;
    top: 0;
    left: 0;
    right: 0;
    z-index: 100;
    width: 100%;
    min-height: var(--skyui-bar-h);
    display: flex;
    align-items: center;
    gap: 14px;
    padding: 5px clamp(14px, 2.4vw, 28px);
    /* no surface: the bar is a layout container only */
    background: none;
    border-radius: 0;
    box-shadow: none;
    transition: padding 0.35s cubic-bezier(0.22, 1, 0.36, 1);
}

/* ── the top shadow ──
   The bar's only paint. A scrim that starts dark at the very top edge
   and dissolves before it reaches page content, so the nav reads as
   "floating over" rather than "sitting on" anything. It's a
   pseudo-element rather than a background so it can overhang the bar's
   own height and fade past it.

   Tinted to the same grey as --skyui-black rather than pure black, so the
   scrim and the controls sitting in it are the same colour family. */
.sky-nav::before {
    content: "";
    position: absolute;
    left: 0;
    right: 0;
    top: 0;
    height: 190%;
    pointer-events: none;
    z-index: -1;
    background: linear-gradient(180deg,
        rgba(26, 26, 26, 0.55) 0%,
        rgba(26, 26, 26, 0.34) 34%,
        rgba(26, 26, 26, 0.12) 66%,
        rgba(26, 26, 26, 0) 100%);
    opacity: 0.85;
    transition: opacity 0.35s ease;
}

/* The bar no longer collapses in width on scroll — there is no bar to
   collapse. It tightens its padding instead, and the scrim deepens. */
.sky-nav.scrolled {
    padding-top: 3px;
    padding-bottom: 3px;
}

.sky-nav.scrolled::before { opacity: 1; }

.sky-brand {
    align-self: center;
    display: inline-flex;
    align-items: center;
    gap: 10px;
    font-weight: 800;
    font-size: 1.08rem;
    color: var(--skyui-beige);
    white-space: nowrap;
    text-decoration: none;
    cursor: pointer;
}

/* ── brand mark: bare logo, no surface ──
   The logo sits directly on the scrim — no plate, no fill, no radius, and
   as of 2026-08-09 no hover surface either. The dark squircle that used to
   fade in behind it is gone: the mark is now an inline two-colour SVG that
   answers hover with its own ink (see the colour swap below), so a plate
   behind it would be a second, competing hover state on one control.

   ── the mark hangs to the bar's floor (2026-07-29) ──
   The bar was thinned to 52px, so a vertically-centered mark had to shrink
   with it. Instead it is bottom-anchored and kept LARGER than the space the
   bar actually gives it: `align-self: flex-end` drops it to the bottom of the
   flex line, and the -5px bottom margin makes it contribute only 42px of
   layout height (47 - 5) while still painting 47px tall. That negative margin
   is what stops the bigger mark from pushing the bar back open — the numbers
   are paired, so if you change `height`, change the margin by the same amount.
   Result: the mark spans the full bar, top padding edge (y=5) to floor (y=52).

   .sky-brand-mark is a wrapper (2026-08-04) that carries that geometry so it
   stays a fixed 47px box regardless of what's inside — kept even without the
   frame that originally motivated it, since the CTA markup and JS already
   reference it.

   The two custom properties below are the mark's ink, lifted from
   BrandedSVG/Fareicon1.svg (.cls-1 #6c74b7 → left ear, .cls-2 #e083b6 →
   right ear). They are stored as bare `r g b` channel triples, not hex, so
   the same one value can serve both the solid `fill` and the translucent
   glow below via `rgb(… / alpha)` — one source of truth per ear. Change a
   brand colour here, once. */
.sky-brand-mark {
    position: relative;
    display: block;
    height: 47px;
    width: 47px;
    align-self: flex-end;
    margin-bottom: -5px;
    flex-shrink: 0;
    --sky-brand-ink-left: 108 116 183;
    --sky-brand-ink-right: 224 131 182;
}

/* ⚠️ TWO <svg> roots, one per ear — not one SVG holding both (2026-08-09).
   The glow below is a CSS `filter`, and Safari does not render a CSS filter
   applied to an element *inside* an <svg> (a <g>, a <path>): on macOS the
   hover produced no glow at all while Chrome and Firefox drew it fine. A
   filter on the <svg> ROOT is an ordinary element filter and works
   everywhere — so each ear gets its own root to hang its own colour on.
   Both roots carry the same `0 0 30 25` viewBox and are stacked in the same
   box, which is what keeps the two ears in the exact positions they had when
   they shared one viewport. Merge them back into one <svg> and the glow dies
   on every WebKit browser again.

   ⚠️ overflow: visible is load-bearing, not tidy-up. Two things spill past
   the viewBox, which is a tight crop of the artwork: the flutter overshoots
   scale(1), and the hover glow blooms ~10px outside each ear's silhouette.
   The default `overflow: hidden` on <svg> would clip both to a hard edge. */
.sky-brand-svg {
    position: absolute;
    inset: 0;
    z-index: 1;
    display: block;
    height: 100%;
    width: 100%;
    overflow: visible;
    filter:
        drop-shadow(0 0 0 rgb(var(--sky-brand-glow) / 0))
        drop-shadow(0 0 0 rgb(var(--sky-brand-glow) / 0))
        drop-shadow(0 0 0 rgb(var(--sky-brand-glow) / 0));
    transition: filter 0.28s ease;
}

/* the ink never changes — hover is a glow, not a recolour (see below) */
.sky-brand-ear-left path { fill: rgb(var(--sky-brand-ink-left)); }
.sky-brand-ear-right path { fill: rgb(var(--sky-brand-ink-right)); }

/* ── hover: each ear warms up its own glow ──
   Each ear blooms in ITS OWN colour — indigo on the left, pink on the right —
   rather than the two trading inks. The logo stays the logo; only the air
   around it lights up.

   The soft gradient falloff is three stacked drop-shadows at widening radii
   (2 → 5 → 11px) with dropping alpha. One shadow at 11px gives a flat, muddy
   halo; three nested give the light an actual curve to it. drop-shadow reads
   each <g>'s rendered alpha, so the glow traces the ear's real silhouette
   instead of a box — the reason this is a filter and not a background.

   ── "startup", not a state ──
   Both ears carry the same three-shadow filter at rest with alpha 0 and
   radius 0, so hover interpolates the whole list rather than snapping a new
   one in. The easing overshoots (y = 1.32 on the curve) so the light
   overshoots its resting brightness and settles back — reading as something
   powering on. The right ear is 90ms behind the left, which turns two
   simultaneous glows into a sequence. Leaving is deliberately plainer and
   quicker: 0.28s ease, no stagger, no overshoot — a warm-up that also
   dramatised its own exit would look like a fault light.

   ⚠️ The resting filter lives on .sky-brand-svg itself (the ROOT of each
   ear's own SVG, merged into the base rule above), never on the <g> — see
   that rule for why. Each root holds exactly one ear, so a root-level
   drop-shadow still traces that one ear's real silhouette. */
.sky-brand-svg-left { --sky-brand-glow: var(--sky-brand-ink-left); }
.sky-brand-svg-right { --sky-brand-glow: var(--sky-brand-ink-right); }

.sky-brand:hover .sky-brand-svg,
.sky-brand:focus-visible .sky-brand-svg {
    filter:
        drop-shadow(0 0 2px rgb(var(--sky-brand-glow) / 0.75))
        drop-shadow(0 0 5px rgb(var(--sky-brand-glow) / 0.45))
        drop-shadow(0 0 11px rgb(var(--sky-brand-glow) / 0.28));
    transition: filter 0.55s cubic-bezier(0.22, 1.32, 0.36, 1);
}

.sky-brand:hover .sky-brand-svg-right,
.sky-brand:focus-visible .sky-brand-svg-right {
    transition-delay: 0.09s;
}

/* ── click: both ears flutter ──
   transform-box: fill-box re-bases the percentage origin onto each <g>'s own
   ink instead of the shared SVG viewport, which is the only way the two ears
   can pivot from their own bases rather than both swinging around the middle
   of the logo. 50% 100% puts that pivot where each ear meets the head.
   The right ear runs 80ms late so the pair reads as a flutter and not as one
   symmetrical pulse.

   (Second .sky-brand-ear block on purpose — the glow above owns `filter`,
   on the <svg> root; this one owns the transform, on the <g>. The flutter
   stays on the <g> because transforms on SVG children work everywhere; only
   filters had to move out.) */
.sky-brand-ear {
    transform-box: fill-box;
    transform-origin: 50% 100%;
}

.sky-brand-mark.is-fluttering .sky-brand-ear-left {
    animation: sky-brand-flutter 0.6s cubic-bezier(0.34, 1.4, 0.64, 1) both;
}

.sky-brand-mark.is-fluttering .sky-brand-ear-right {
    animation: sky-brand-flutter 0.6s cubic-bezier(0.34, 1.4, 0.64, 1) 0.08s both;
}

@keyframes sky-brand-flutter {
    0%   { transform: scale(1, 1); }
    22%  { transform: scale(0.88, 1.2); }
    48%  { transform: scale(1.1, 0.9); }
    74%  { transform: scale(0.96, 1.06); }
    100% { transform: scale(1, 1); }
}

/* The glow itself survives reduced-motion — it is light, not movement, and
   removing it would leave the mark with no hover feedback at all. What goes
   is the theatre around it: the ramp, the overshoot and the 90ms stagger, so
   the glow is simply on or off. The flutter goes entirely; there is no
   non-moving version of it to keep. */
@media (prefers-reduced-motion: reduce) {
    .sky-brand-mark.is-fluttering .sky-brand-ear-left,
    .sky-brand-mark.is-fluttering .sky-brand-ear-right { animation: none; }

    .sky-brand-svg,
    .sky-brand:hover .sky-brand-svg,
    .sky-brand:focus-visible .sky-brand-svg {
        transition: none;
    }

    .sky-brand:hover .sky-brand-svg-right,
    .sky-brand:focus-visible .sky-brand-svg-right { transition-delay: 0s; }
}

/* ── the wordmark, on every page EXCEPT the home page (2026-08-09) ──
   BrandedSVG/FareText.svg set beside the mark. It ships in the markup of the
   7 non-index pages and is deliberately absent from index.html: the home page
   already spells the name out in the 3D hero a few hundred pixels below, and
   two wordmarks in one viewport read as a mistake. There is no `display:none`
   for the home case — the element simply is not there, which is why nothing
   here is scoped to a body class.

   It sits INSIDE <a class="sky-brand">, so it points at index.html for free,
   lights the ears' glow on hover for free, and flutters them on click for
   free. Do not give it its own <a> — a second link to the same place next to
   the first is a duplicate stop for anyone tabbing or using a screen reader.

   ── why a mask and not an <img> or inline paths ──
   The whole glyph run is painted by CSS: `background` is the ink, and the
   SVG is used only as a MASK, so the wordmark takes `currentColor` from
   .sky-brand and stays in step with the bar's beige instead of hardcoding
   the #231f20 the artwork ships with (a near-black, invisible on this nav).
   It also means the shine below can be an ordinary element sweeping behind
   the mask rather than anything SVG-specific.

   ── why it is nudged down (2026-08-09) ──
   .sky-brand-mark is bottom-anchored and paints 5px taller than the layout
   height it reports (see that block), so the mark's optical centre sits
   ~2.5px BELOW the flex line's centre. A word centred on the line therefore
   rides visibly high against the logo. `top: 3px` drops it onto the mark's
   own centre; it is `top`, not a margin, so the nudge costs the bar no
   height and cannot reopen it. */
.sky-brand-word {
    position: relative;
    top: 3px;
    display: block;
    width: 102px;
    height: 15.3px;           /* the artwork's 100 × 15 viewBox, scaled 1.02 */
    flex-shrink: 0;
    overflow: hidden;
    background-color: currentColor;
    -webkit-mask: url('./BrandedSVG/FareText.svg') no-repeat center / contain;
    mask: url('./BrandedSVG/FareText.svg') no-repeat center / contain;
}

/* ── the shine: a band travelling right → left inside the glyphs ──
   This is a plain rectangle sliding across the box. What makes it read as
   light moving *through the letters* rather than a highlight passing over
   them is that the mask on the parent clips it — CSS masks apply to the
   whole subtree, so the band only ever paints where there is glyph.

   It rests off the right edge at translateX(180%) and is only ever animated,
   never transitioned, so an interrupted hover leaves it parked off-canvas
   instead of stranded mid-letter. */
.sky-brand-word::after {
    content: '';
    position: absolute;
    top: 0;
    bottom: 0;
    left: 0;
    width: 55%;
    transform: translateX(180%);
    background: linear-gradient(
        100deg,
        rgba(255, 255, 255, 0) 0%,
        rgba(255, 255, 255, 0.95) 50%,
        rgba(255, 255, 255, 0) 100%
    );
}

.sky-brand:hover .sky-brand-word::after,
.sky-brand:focus-visible .sky-brand-word::after {
    animation: sky-brand-shine 0.85s cubic-bezier(0.4, 0, 0.2, 1);
}

/* ends past the left edge rather than at it, so the band leaves the last
   glyph completely instead of fading out on top of it */
@keyframes sky-brand-shine {
    from { transform: translateX(180%); }
    to   { transform: translateX(-180%); }
}

@media (prefers-reduced-motion: reduce) {
    .sky-brand:hover .sky-brand-word::after,
    .sky-brand:focus-visible .sky-brand-word::after { animation: none; }
}

/* The version chip that used to sit beside the mark is gone (2026-08-05).
   Even outlined it read as a second control next to the logo; the version
   now lives in the footer next to the status pill, styled and filled by
   cometfare-footer.js (.cf-footer-version). Do not add it back here. */

/* pinned to the bar's true midpoint — flex auto-margins would center
   in the leftover space, which drifts because brand ≠ CTA width.
   cometfare-sky-header.js overwrites `left` with a px value when the
   true midpoint would run the links into the brand or the CTA; this
   50% is the uncramped default. */
.sky-nav-links {
    position: absolute;
    left: 50%;
    top: 50%;
    transform: translate(-50%, -50%);
    display: flex;
    align-items: center;
    gap: 4px;
}

.sky-nav-group { position: relative; }

/* ── middle triggers: no surface until hover ──
   Transparent by default (text only). The border is declared
   transparent rather than added on hover so the label never shifts by
   the 2px when the surface appears. */
.sky-nav-trigger {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    padding: 6px 13px;
    border: 2px solid transparent;
    border-radius: 16px;
    background: none;
    font-weight: 700;
    font-size: 0.92rem;
    color: var(--skyui-beige);
    cursor: default;
    transition: color 0.18s ease, background 0.18s ease, border-color 0.18s ease;
}

.sky-nav-trigger::after {
    content: "";
    width: 8px;
    height: 8px;
    border-right: 2.2px solid currentColor;
    border-bottom: 2.2px solid currentColor;
    transform: rotate(45deg) translateY(-2px);
    transition: transform 0.2s ease;
}

/* engaged: the group is holding its menu open. White plate, blue label —
   the chevron is drawn from currentColor, so it turns blue with the text. */
.sky-nav-group:hover .sky-nav-trigger,
.sky-nav-group:focus-within .sky-nav-trigger {
    color: var(--skyui-engaged-ink);
    background: var(--skyui-engaged-surface);
    border-color: var(--skyui-engaged-surface);
}

.sky-nav-group:hover .sky-nav-trigger::after {
    transform: rotate(225deg) translateY(-2px);
}

.sky-nav-menu {
    position: absolute;
    top: 100%;
    left: 50%;
    transform: translateX(-50%);
    padding-top: 12px;
    opacity: 0;
    pointer-events: none;
    transition: opacity 0.18s ease;
    z-index: 5;
}

.sky-nav-group:hover .sky-nav-menu {
    opacity: 1;
    pointer-events: auto;
}

/* no border: the drawer is separated from the bar by its drop shadow alone.
   It used to carry a 1px #050505 hem, which on the dark bar read as a hard
   black outline around the panel rather than as an edge. */
.sky-nav-menu-inner {
    min-width: 190px;
    background: var(--skyui-menu-surface);
    border-radius: 12px;
    box-shadow: 0 20px 50px rgba(0, 0, 0, 0.55);
    padding: 10px;
    display: grid;
    gap: 2px;
}

.sky-nav-menu-inner a {
    display: block;
    padding: 10px 14px;
    border-radius: 8px;
    font-weight: 700;
    font-size: 0.9rem;
    color: var(--skyui-beige);
    text-decoration: none;
    transition: background 0.15s ease, color 0.15s ease;
}

/* rows follow the controls: white plate, blue label */
.sky-nav-menu-inner a:hover,
.sky-nav-menu-inner a:focus-visible {
    background: var(--skyui-engaged-surface);
    color: var(--skyui-engaged-ink);
}

.sky-nav-dim {
    position: fixed;
    inset: 0;
    z-index: 90;
    background: rgba(0, 0, 0, 0.25);
    opacity: 0;
    pointer-events: none;
    transition: opacity 0.25s ease;
}

body:has(.sky-nav-group:hover) .sky-nav-dim { opacity: 1; }

/* ─────────────────────────────────────────────────────────────
   ── THE CTA: two states, one pill (2026-08-04) ──
   This slot used to be a bare "Open app" link pointing at ./home.html for
   everyone, signed in or not, which sent first-time visitors to a login wall
   from the loudest control on the page. It is now the download button by
   default and only becomes "Open app" once cometfare-sky-header.js has
   confirmed a session. Both states share the pill, so nothing jumps when the
   swap lands.

   `data-state` is the switch:
     download (the HTML default) — Windows glyph + "Download for Windows"
     app                        — character mark + "Open app"

   The height is DECLARED rather than derived from padding. The signed-in
   mark is sized off it (height: 100% + the border) so it can sit flush with
   the pill's top and bottom edge; a padding-derived height would leave that
   percentage with nothing to resolve against.
   ───────────────────────────────────────────────────────────── */
.sky-nav-cta {
    margin-left: auto;
    display: inline-flex;
    align-items: center;
    gap: 7px;
    height: 34px;
    box-sizing: border-box;
    padding: 0 14px;
    border-radius: 999px;
    font-weight: 800;
    font-size: 0.86rem;
    white-space: nowrap; /* stops the label folding into two lines */
    overflow: hidden;    /* clips the flush mark back to the pill's curve */
    color: var(--skyui-beige);
    background: var(--skyui-black);
    /* Resting edge is the SURFACE colour, not --skyui-edge's pale hem: at rest
       the pill reads as one solid plate with no outline. The 2px border still
       exists (the avatar's `100% + 4px` height is measured against it) — it is
       only invisible, and the hover rule below repaints it. */
    border: var(--skyui-edge);
    border-color: var(--skyui-black);
    text-decoration: none;
    transition: color 0.18s ease, border-color 0.18s ease, background 0.18s ease;
}

/* ── hidden on the releases page ──
   The download pill's href is ./releases.html, so on that page it is a link
   to the page you are already on — and the page's own per-platform download
   buttons say it better anyway. releases.html marks its <nav data-page>.

   ⚠️ `visibility`, deliberately NOT `display: none`. layoutLinks() in
   cometfare-sky-header.js centres .sky-nav-links between the brand and
   `cta.getBoundingClientRect().left`; a display:none CTA reports a zero
   rect, which collapses that right edge to 0, makes the clamp impossible
   and drops the links into the `is-cramped` fallback. Keeping the layout
   box means the links sit exactly where they do on every other page. */
.sky-nav[data-page="releases"] .sky-nav-cta {
    visibility: hidden;
    pointer-events: none;
}

/* the glyph is drawn from currentColor, so it turns blue with the label */
.sky-nav-cta-glyph {
    flex-shrink: 0;
    display: block;
}

/* ── signed-in mark ──
   Flush to the pill's floor and ceiling: 100% of the content box is
   (34 - 2 - 2) = 30px, and the -2px vertical margins push it back out over
   the border to the full 34. Those two numbers are paired with the border
   width — change one, change the other. */
.sky-nav-cta-avatar {
    flex-shrink: 0;
    display: block;
    height: calc(100% + 4px);
    width: 34px;
    margin: -2px 0;
    object-fit: cover;
    /* The source is a square 1000px render with the character's face in the
       middle third, so a plain square crop lands mostly on empty headroom —
       cover cannot zoom a square into a square. The scale does the zooming
       and the origin puts the eyes in the middle of the 34px window; the
       pill's own overflow:hidden is what trims the overflow back to the
       curve. Nudge the origin, not the object-position, if it drifts. */
    transform: scale(1.9);
    transform-origin: 50% 57%;
}

/* each state shows exactly one of the two marks */
.sky-nav-cta[data-state="download"] .sky-nav-cta-avatar,
.sky-nav-cta[data-state="app"] .sky-nav-cta-glyph { display: none; }

/* the mark replaces the left padding rather than sitting inside it, which
   is what lets it reach the pill's edge */
.sky-nav-cta[data-state="app"] { padding-left: 0; gap: 9px; }

/* the label sheds its qualifier before the pill starts crowding the bar —
   "Download" alone still says what the button does */
@media (max-width: 620px) {
    .sky-nav-cta-label-rest { display: none; }
}

.sky-nav-cta:hover,
.sky-nav-cta:focus-visible {
    color: var(--skyui-engaged-ink);
    background: var(--skyui-engaged-surface);
    border-color: var(--skyui-engaged-surface);
}

/* The links hide only when the bar genuinely can't fit them between the
   brand and the CTA — cometfare-sky-header.js measures that and toggles
   this class. Hidden via opacity, not display, so the width stays
   measurable and the script can bring them back. */
.sky-nav-links.is-cramped {
    opacity: 0;
    pointer-events: none;
    visibility: hidden;
}

/* The wordmark costs the brand ~112px (102 + the 10px gap), which is spent
   directly out of the room .sky-nav-links has to centre itself in. On a wide
   bar that is free; by 760px it is the difference between the links sitting
   centred and the JS flagging them `is-cramped` and hiding them outright.
   The mark alone still says CometFare, so the wordmark is what gives way. */
@media (max-width: 760px) {
    .sky-brand-word { display: none; }
}

/* below 420px, shrink brand + CTA instead of letting them wrap/overflow */
@media (max-width: 420px) {
    .sky-nav { gap: 8px; padding: 5px 12px; }
    .sky-brand { gap: 8px; font-size: clamp(1rem, 4.8vw, 1.08rem); }
    /* still floor-anchored; the -5px pairing from the base rule carries over,
       so the mark only ever contributes (height - 5px) to the bar */
    .sky-brand-mark { height: clamp(40px, 12vw, 47px); width: clamp(40px, 12vw, 47px); }
    .sky-nav-cta { height: 32px; padding: 0 clamp(10px, 3.4vw, 14px); font-size: clamp(0.78rem, 3.1vw, 0.86rem); }
    .sky-nav-cta[data-state="app"] { padding-left: 0; }
    .sky-nav-cta-avatar { width: 32px; }
}
