/* ==========================================================================
   QSD — CORRECTIONS TO LEGACY BEHAVIOUR
   Loaded last. Deliberate bug fixes against css/legacy.css, kept separate
   from core/legacy so it stays obvious what v2 changed and why.
   Each fix documents the rule it overrides.
   ========================================================================== */


/* ── FIX 1: the About page could not scroll ───────────────────────────────
   SYMPTOM
     On large desktops the Founding Team was cut off at the bottom of the
     screen, and scrolling down jumped straight to Contact instead of
     revealing the rest of the page. On phones and tablets it was worse:
     only the first screenful of About was reachable at all.

   CAUSE
     legacy.css layers 02 (qsd-v4-about-rework) and 07 (qsd-v9-about-rebuild)
     both set, with no media query:

         #page-about { position:relative !important; overflow:hidden !important; }

     That was done so the decorative ::before / ::after starfield overlays
     had a positioned ancestor, but it broke the page-shell contract from
     core.css (.page { position:fixed; inset:0; overflow-y:auto }).

     With position:relative the element's height becomes its content height
     and no longer tracks the viewport, while overflow:hidden clips whatever
     does not fit — and body is height:100vh; overflow:hidden, so nothing
     scrolls. Measured before this fix:

         1920×1080 → #page-about 1281px tall, scrollable 0px  (201px lost)
          375×812  → #page-about 3437px tall, scrollable 0px  (2625px lost)

     Layer 24 later patched this, but only inside
     @media (min-width:1024px) and (max-width:1800px) — which is why the bug
     was invisible on laptops and only showed up on large monitors and phones.

     The dead knock-on effect: js/router.js advances to the next section when
     the current page is scrolled to its bottom. With scrollHeight equal to
     clientHeight the page reported "already at the bottom" on the very first
     wheel event, so About handed straight over to Contact.

   FIX
     Restore a viewport-bound, scrollable box at every width. position is
     deliberately left alone so the ::before / ::after overlays keep their
     containing block and so the ≤1023px `.page { position:absolute }` rule
     still applies as the author intended.
------------------------------------------------------------------------- */
#page-about {
  height: 100vh !important;              /* fallback for browsers without dvh */
  height: 100dvh !important;
  max-height: 100dvh !important;
  overflow-y: auto !important;
  overflow-x: hidden !important;
}

/* Clear the fixed bottom ticker so the last row of founder cards is not
   hidden behind it once the page scrolls to the end. */
#page-about > .page-inner {
  padding-bottom: 96px !important;
}

@media (max-width: 1023px) {
  #page-about > .page-inner {
    padding-bottom: 88px !important;
  }
}


/* ── THE QSD LOGO ASSET ───────────────────────────────────────────────────
   assets/logos/qsd-logo-circle-white.png — the vertical circle lockup:
   QSD monogram on top, then QUANTUM, then SAFE DYNAMICS, with the swoosh
   arcs framing the whole thing. Measured from the file itself:

     canvas        2000 × 1414 (RGBA, transparent padding on all sides)
     opaque box     879 ×  985  at (533, 180)   → only 4.4% of the canvas
     QSD monogram   505 ×  216  at (706, 437)   → letterforms only

   Scanning the alpha channel column-by-column inside the monogram's columns
   gives five separate bands, which is what makes a clean crop possible:

     180 –  333   swoosh, upper arc + dot
     437 –  652   QSD letterforms          ← the only band FIX 2 shows
     701 –  769   QUANTUM
     799 –  843   SAFE DYNAMICS
    1030 – 1164   swoosh, lower arc + dot

   The transparent padding is the reason both placements below use measured
   numbers rather than plain object-fit: dropping the file into a box would
   render the artwork at roughly half size and slightly off-centre.
------------------------------------------------------------------------- */


/* ── FIX 2: nav lockup (top left) ─────────────────────────────────────────
   This is the file the old note here was waiting for.

   The nav used to show a reconstruction: the QSD monogram cropped out of the
   circular lockup with background-size/position, set beside "QUANTUM" and
   "SAFE DYNAMICS" as live text. That existed only because the horizontal
   lockup v1 referenced — assets/images/qsd-logo-white.png — was never in the
   repository. The client has now supplied it, so the reconstruction is gone
   and Base.astro carries a plain <img> again.

   The artwork arrived as a JPEG, dark navy on a solid #F7F7F7 field, which
   is invisible on this nav. The two PNGs in assets/logos are derived from it:
   the background is knocked out by reading each pixel's darkness as alpha —
   a threshold would have left the diagonal strokes and the swoosh ragged —
   and the ink is recoloured. -white is the one used here; the navy original
   is kept beside it for light backgrounds such as print or a PDF.

   Height, not width, is what the nav constrains, and the nav is not one
   height: core.css sets 68px, and the laptop fit engine (legacy.css layer
   21) overrides it to var(--qsd-nav-h) = 56px between 1024 and 1800px, which
   is where most visitors are. So the lockup is set to ~62% of whichever
   height applies rather than to a fixed number — 42px in a 68px bar, 35px in
   a 56px one, about 13px and 11px of air.

   At 3.58:1 that is 150px / 125px wide, against the ~190px the mark and the
   two text lines used to take, so the Legal dropdown beside it gains room
   rather than losing it.
------------------------------------------------------------------------- */
.nlogo { cursor: pointer; }

.nlogo-lockup {
  display: block;
  flex: 0 0 auto;
  height: 42px;          /* the 68px bar: below 1024px and above 1800px */
  width: auto;
  filter: drop-shadow(0 0 8px rgba(255, 255, 255, .22));
  transition: filter .25s ease, transform .25s ease;
}

.nlogo:hover .nlogo-lockup {
  filter: drop-shadow(0 0 12px rgba(245, 208, 104, .5));
  transform: scale(1.04);
}

/* Follow the fit engine's shorter bar instead of keeping a height it no
   longer has room for. The variable is declared in the same range, so the
   calc() is only ever evaluated where it resolves. */
@media (min-width: 1024px) and (max-width: 1800px) {
  .nlogo-lockup { height: calc(var(--qsd-nav-h) * .62); }
}

/* Phones get the 68px bar back but only ~375px of width, and this lockup is
   wide. 34px keeps it to a third of the bar, leaving the burger its corner. */
@media (max-width: 768px) {
  .nlogo-lockup { height: 34px; }
}


/* ── FIX 3: hero sphere logo ──────────────────────────────────────────────
   The lockup sits inside the sphere painted on #qcv. The sphere's centre is
   cx = W×0.50, cy = H×0.343 (see js/effects.js), so the container is pinned
   to those coordinates rather than to the 35% / -47% v1 eyeballed.

   The translate is NOT -50%/-50%: the opaque artwork is off-centre inside
   its own canvas, sitting at 48.63% / 47.56% of the file. Translating by
   exactly those percentages puts the artwork — not the padding — on the
   sphere's centre.

   Width is set by js/hero-logo.js because the sphere radius depends on
   min(W,H), which CSS cannot express.
------------------------------------------------------------------------- */
.hero-qsd {
  left: 50% !important;
  top: 34.3% !important;
  transform: translate(-48.63%, -47.56%) !important;
}

.hero-qsd-logo {
  max-width: none !important;
  filter: drop-shadow(0 0 26px rgba(245, 208, 104, .30))
          drop-shadow(0 0 60px rgba(226, 184, 74, .16));
}


/* ── FIX 4: collapse the music control to a play button on small screens ──
   The control is a wide pill: play icon + "Quantum-Pulse" + "QSD Theme ·
   Click to play". On a 375px screen that pill is ~180px wide and floats over
   the content it is meant to sit beside.

   legacy.css already had the collapsed circle — but on the wrong range. It
   applies the 44px circle at 1024–1800px (the laptop fit engine, layer 21),
   and then the ≤1023px layer explicitly undoes it:

       #music-ctrl      { width:auto !important; height:auto !important; }
       #music-label,
       #music-sub       { display:block !important; }

   That reset looks accidental — it sits in a block that also clears the fit
   engine's transform/width, so the pill came back precisely on the screens
   with the least room for it. The result was a circle on laptops and a full
   pill on phones and tablets.

   This restores the intended behaviour and makes the circle contiguous from
   0 to 1800px, so the pill only appears on wide desktops that can carry it.
   46px rather than legacy's 44px: comfortable minimum touch target.

   The accessible name comes from aria-label on the element in index.html,
   since the visible text is hidden in this state.
------------------------------------------------------------------------- */
/* 1023.98 rather than 1023: on Windows at 125% display scaling the viewport
   lands on fractional CSS widths (e.g. 1279 device px ÷ 1.25 = 1023.2px), and
   1023.2 satisfies neither `max-width:1023px` nor the legacy circle rule's
   `min-width:1024px`. The control fell back to the full pill in that gap.
   The legacy breakpoints have the same hole; this closes it for FIX 4 so the
   circle is contiguous from 0 to 1800px. */
@media (max-width: 1023.98px) {
  #music-ctrl {
    width: 46px !important;
    height: 46px !important;
    min-width: 46px !important;
    padding: 0 !important;
    gap: 0 !important;
    border-radius: 50% !important;
    justify-content: center !important;
    /* No overflow:hidden here (legacy's collapsed rule had it). The labels
       are display:none so there is nothing to clip, and hiding overflow
       would cut off the .playing pulse, which animates box-shadow outward. */
    overflow: visible !important;
    /* The fixed ticker is 44px tall here; the old 42px offset left the
       button's edge sitting 2px over it. Clear it with a 12px gap. */
    bottom: 56px !important;
    right: 12px !important;
  }

  /* The label/sub wrapper carries no id of its own. */
  #music-ctrl > div:not(#music-icon) { display: none !important; }
  #music-label,
  #music-sub { display: none !important; }

  /* The collapsed control is itself a bordered circle, so the icon drops its
     own ring — two concentric rings read as a rendering mistake. */
  #music-icon {
    width: 32px !important;
    height: 32px !important;
    border: 0 !important;
    background: transparent !important;
  }

  /* ...but the playing state still needs its tint back, otherwise the only
     cue that audio is running is the pulse. */
  #music-ctrl.playing #music-icon {
    background: rgba(226, 184, 74, .25) !important;
  }
}


/* ── FIX 5: Legal dropdown in the nav ─────────────────────────────────────
   POSITION
     core.css gives .ntabs `margin-left:auto`, which pushes the tab strip
     right and leaves a wide empty band between the logo and the tabs. The
     Legal trigger goes in that band, centred in it: auto margins on both
     sides of .nlegal, and .ntabs' own auto margin removed so the free space
     splits evenly around the trigger rather than three ways.

   The menu is populated by js/legal-nav.js from QSD_CONTENT, and hidden
   below 769px, where the documents move into the hamburger panel instead.
------------------------------------------------------------------------- */
.nlegal {
  position: relative;
  margin-left: auto;
  margin-right: auto;
  flex-shrink: 0;
}

.ntabs { margin-left: 0 !important; }

/* core.css puts margin-right:16px on .nlogo. That 16px is consumed before
   the auto margins split the free space, so the band left of the trigger
   rendered 16px wider than the one on its right. Zeroing it makes the two
   gaps equal to within a rounding pixel. */
.nlogo { margin-right: 0 !important; }

.nlegal-btn {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  background: none;
  border: 0;
  padding: 8px 12px;
  cursor: pointer;
  /* Matches .nt so the trigger reads as a peer of the other nav items. */
  font-family: var(--font-heading);
  font-size: 11px;
  font-weight: 600;
  letter-spacing: .08em;
  text-transform: uppercase;
  color: var(--t3);
  white-space: nowrap;
  transition: color .2s, text-shadow .2s;
}

.nlegal-btn:hover,
.nlegal.open .nlegal-btn,
.nlegal.active .nlegal-btn {
  color: var(--gold);
  text-shadow: 0 0 10px rgba(226, 184, 74, .3);
}

.nlegal-caret { transition: transform .22s ease; }
.nlegal.open .nlegal-caret { transform: rotate(180deg); }

/* Underline for the active state, mirroring how .nt marks the current page. */
.nlegal.active .nlegal-btn::after {
  content: '';
  position: absolute;
  left: 12px;
  right: 12px;
  bottom: 2px;
  height: 1px;
  background: var(--gold);
  box-shadow: 0 0 8px rgba(226, 184, 74, .6);
}

/* ── Menu panel ───────────────────────────────────────────────────────── */
.nlegal-menu {
  position: absolute;
  top: calc(100% + 10px);
  left: 50%;
  transform: translateX(-50%);
  min-width: 268px;
  padding: 8px;
  z-index: 700;
  background: rgba(6, 18, 40, .97);
  backdrop-filter: blur(14px);
  border: 1px solid var(--bdr);
  border-top: 2px solid rgba(220, 175, 55, .85);
  border-radius: 10px;
  box-shadow: 0 18px 46px rgba(0, 6, 20, .55), 0 0 20px rgba(226, 184, 74, .08);
  animation: nlegalIn .18s ease-out;
}

@keyframes nlegalIn {
  from { opacity: 0; transform: translateX(-50%) translateY(-6px); }
  to   { opacity: 1; transform: translateX(-50%) translateY(0); }
}

.nlegal-item {
  display: block;
  width: 100%;
  text-align: left;
  background: none;
  border: 0;
  border-radius: 7px;
  padding: 10px 12px;
  cursor: pointer;
  transition: background .16s, transform .16s;
}

.nlegal-item:hover,
.nlegal-item:focus-visible {
  background: rgba(226, 184, 74, .10);
  transform: translateX(2px);
  outline: none;
}

.nlegal-item-t {
  display: block;
  font-family: var(--font-heading);
  font-size: 12.5px;
  font-weight: 600;
  letter-spacing: .04em;
  color: var(--t1);
  margin-bottom: 2px;
}

.nlegal-item:hover .nlegal-item-t { color: var(--gold-h); }

/* The German original, since the documents themselves are in German. */
.nlegal-item-s {
  display: block;
  font-family: var(--font-mono);
  font-size: 9.5px;
  letter-spacing: .06em;
  color: var(--t4);
}

/* ── Reclaim the width the trigger costs on narrow desktops ──────────────
   The nav does not wrap: logo 160 + tabs 754 + right 198 means it needs
   ~1149px, but the hamburger only takes over at ≤768px. So 769–1148px was
   already overflowing and clipping the last tabs before any of this — a
   pre-existing bug, not one introduced here.

   Adding a 79px trigger would have moved that break point up to ~1228px and
   clipped laptops that were previously fine. Tightening the tab padding in
   this band frees ~98px, more than the trigger costs, so the overflow point
   ends up slightly better than before rather than worse.

   This does NOT fix the underlying 769–1148px overflow — that needs the
   hamburger breakpoint raised, which is a visible product decision.
------------------------------------------------------------------------- */
@media (min-width: 769px) and (max-width: 1300px) {
  .nt {
    padding-left: 7px !important;
    padding-right: 7px !important;
  }
  .nlegal-btn { padding-left: 8px; padding-right: 8px; }
}

/* ── Mobile: trigger hides, documents live in the hamburger panel ─────── */
@media (max-width: 768px) {
  .nlegal { display: none; }
}

/* The hamburger panel was sized by its content with overflow:visible. Adding
   the Legal group took it to 15 entries / 783px, which overruns a 812px phone
   by 39px — the last document was clipped and unreachable, exactly the
   failure mode FIX 1 describes on the About page. Bound it to the viewport
   and let it scroll. */
.nmob {
  max-height: calc(100vh - 68px) !important;
  max-height: calc(100dvh - 68px) !important;
  overflow-y: auto !important;
  overscroll-behavior: contain;
  /* core.css gives the panel rgba(2,10,22,.97) but no backdrop-filter, unlike
     #nav and #music-ctrl which both blur. That last 3% let bright body text
     read through as ghosting behind the menu — very visible over a legal page,
     which is dense white text. Blurring the backdrop keeps the intended
     translucency while making anything behind it illegible. */
  backdrop-filter: blur(18px);
  -webkit-backdrop-filter: blur(18px);
}

.nmob-legal-head {
  color: var(--gold) !important;
  font-size: 11px !important;
  letter-spacing: .22em !important;
  opacity: .85;
  cursor: default !important;
  padding-top: 20px !important;
  border-bottom: 0 !important;
}

.nmob-legal {
  padding-left: 14px !important;
  font-size: 13.5px !important;
  letter-spacing: .06em !important;
  text-transform: none !important;
}


/* ── FIX 6: solid background on the standards ticker ──────────────────────
   The ticker was a 5% gold wash — effectively transparent — so page content
   scrolled visibly behind it. Two rules set it, and both need overriding:

     core.css                                    rgba(226,184,74,.05)
     legacy.css @media (1024px–1800px)           rgba(226,184,74,.043)

   The colour is the existing wash composited onto the nav's base tone, so
   the ticker reads as the bottom counterpart of the top bar and keeps its
   faint gold warmth:

     rgb(4,14,31) × 0.95  +  rgb(226,184,74) × 0.05  =  rgb(15,23,33)

   Adjust #0F1721 if you want it lighter or cooler; nothing else depends on
   the value.
------------------------------------------------------------------------- */
#global-ticker {
  background: #0F1721 !important;
}


/* ── FIX 7: R&D sector icons ──────────────────────────────────────────────
   The nine R&D cards used emoji (⚡ 🏥 🏦 📡 🚆 💧 🌱 🏛️ 🚑), which render in
   the OS emoji font — full colour, a different weight on every platform, and
   nothing like the drawn cyan line icons on Products & Solutions. They are
   now inline 24×24 stroke SVGs built the same way as the .sc-ico set.

   The icon *containers* were already shared and identical (54px tile, cyan
   border, navy gradient), so only the glyph treatment was missing: core.css
   styles `.sc-ico svg` but never `.rnd-card-icon svg`, because those slots
   only ever held text. This gives them the same stroke, weight and glow.
------------------------------------------------------------------------- */
/* ── FIX 8: EN/DE language toggle ─────────────────────────────────────────
   v1 shipped five language buttons (EN/DE/FR/TR/AR) but core.css hid all but
   the active one (`.nlangs .nlb:not(.on){display:none}`), so only "EN" was
   ever visible and clicking it re-selected English. They are replaced by a
   single toggle driven by js/lang-toggle.js.

   min-width keeps the nav from shifting a pixel as the label swaps, and
   cursor/hover make it read as an actionable control rather than a badge —
   the old one was effectively inert.
------------------------------------------------------------------------- */
#lang-toggle {
  min-width: 38px;
  cursor: pointer;
  transition: background .18s, color .18s;
}

#lang-toggle:hover {
  background: rgba(226, 184, 74, .22) !important;
  color: var(--gold3) !important;
}

#lang-toggle:focus-visible {
  outline: 2px solid var(--gold);
  outline-offset: 2px;
}

.rnd-card-icon svg,
.rnd-sector-icon svg {
  width: 25px !important;
  height: 25px !important;
  stroke: #64eaf6 !important;
  fill: none !important;
  stroke-width: 1.8 !important;
  stroke-linecap: round !important;
  stroke-linejoin: round !important;
  opacity: 1 !important;
  filter: drop-shadow(0 0 7px rgba(100, 234, 246, .50)) !important;
}
