/* ==========================================================================
   QSD v3 — rules that only apply to the new markup

   Kept separate from core/legacy/detail/fixes so those four stay byte-identical
   to v2 and the parity comparison stays meaningful. Loaded last.
   ========================================================================== */


/* ── Cards are anchors now ────────────────────────────────────────────────
   v2 wrote them as <div data-detail> and navigated by script. They are real
   <a href> elements here so a crawler can follow them and Astro's
   ClientRouter can intercept them.

   Four of the six classes never declared a display of their own — they were
   block only because <div> is. As anchors they would collapse to inline and
   drop out of the grid, so the value they had is restated explicitly.
   .rnd-card and .rnd-sector-card already set display:flex in core.css and
   are left alone.

   core.css line 652 already resets `a` to inherit colour and drop underline,
   so nothing more is needed for the text.
------------------------------------------------------------------------- */
a.sc,
a.con-card,
a.proj-card,
a.blog-card {
  display: block;
}

/* Same story for a founder card that carries a LinkedIn address: core.css
   never gives .fdr a display of its own, so as an anchor it would go inline
   and fall out of the three-across grid. A founder without a link is still a
   <div> and is untouched by any of this. */
a.fdr {
  display: block;
  cursor: pointer;
}

/* .fdr already animates border-color and box-shadow on hover in core.css.
   The only addition is the photo ring, so it is visible that the picture —
   the part a visitor aims at — is what leads somewhere. */
a.fdr .fdr-photo-wrap {
  transition: box-shadow .22s, transform .22s;
}

a.fdr:hover .fdr-photo-wrap {
  transform: translateY(-2px);
  box-shadow: 0 12px 28px rgba(0, 0, 0, .22), 0 0 0 3px rgba(226, 184, 74, .35);
}

@media (prefers-reduced-motion: reduce) {
  a.fdr:hover .fdr-photo-wrap { transform: none; }
}

/* ── Card images come from the content, not from position ─────────────────
   legacy.css binds each card's ::before image with :nth-child(), one rule per
   grid position. That was fine when the markup was hand-written and fixed,
   but the blog grid is generated from the CMS now — adding, removing or
   reordering a post would shift every image onto the wrong card.

   Cards rendered from content carry their own --card-visual, which wins here.
   !important is needed because the legacy nth-child rules use it too.
   Scoped to .blog-grid for now; each grid joins as its section moves.
------------------------------------------------------------------------- */
.svc-grid .sc::before,
.cons-grid .con-card::before,
.rnd-feature-grid .rnd-card::before,
.rnd-sector-grid .rnd-sector-card::before,
.proj-grid .proj-card::before,
.blog-grid .blog-card::before {
  background-image: var(--card-visual) !important;
}


/* ── Rich text from the CMS ───────────────────────────────────────────────
   detail.css styles the block renderer's output, which carries .dt-h, .dt-p
   and so on. Markdoc emits bare <h2>, <p>, <ul>… so the same treatment is
   restated for unclassed elements inside .dt-body.

   The values mirror detail.css deliberately rather than being refactored
   into shared rules: detail.css has to stay byte-identical to v2, which
   still renders the classed markup in the browser.
------------------------------------------------------------------------- */
.dt-body > h2 {
  font-family: var(--font-heading);
  font-size: 22px;
  font-weight: 700;
  letter-spacing: -.01em;
  color: var(--gold-h);
  margin: 48px 0 18px;
  padding-left: 16px;
  border-left: 2px solid var(--gold);
}

.dt-body > h2:first-child { margin-top: 0; }

.dt-body > h3 {
  font-family: var(--font-heading);
  font-size: 17px;
  font-weight: 700;
  color: var(--t0);
  margin: 32px 0 12px;
}

.dt-body > h4 {
  font-family: var(--font-mono);
  font-size: 14.5px;
  font-weight: 600;
  letter-spacing: .06em;
  color: var(--gold);
  margin: 26px 0 10px;
}

.dt-body > p {
  font-family: var(--font-body);
  font-size: 15.5px;
  line-height: 1.86;
  font-weight: 300;
  color: var(--t2);
  margin-bottom: 18px;
}

.dt-body > ul,
.dt-body > ol {
  margin: 4px 0 18px;
  padding-left: 0;
  list-style: none;
}

.dt-body > ul > li,
.dt-body > ol > li {
  position: relative;
  padding-left: 30px;
  margin-bottom: 13px;
  font-family: var(--font-body);
  font-size: 15px;
  line-height: 1.76;
  font-weight: 300;
  color: var(--t2);
}

.dt-body > ul > li::before {
  content: '';
  position: absolute;
  left: 4px;
  top: .62em;
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: var(--gold);
  box-shadow: 0 0 9px rgba(226, 184, 74, .6);
}

/* Numbered lists keep their numbers, in the gold mono used elsewhere. */
.dt-body > ol { counter-reset: dtol; }

.dt-body > ol > li { counter-increment: dtol; }

.dt-body > ol > li::before {
  content: counter(dtol, decimal-leading-zero);
  position: absolute;
  left: 0;
  top: .1em;
  font-family: var(--font-mono);
  font-size: 13px;
  color: var(--gold);
  opacity: .72;
}

.dt-body > blockquote {
  margin: 36px 0;
  padding: 26px 30px;
  border-left: 2px solid var(--gold);
  background: linear-gradient(90deg, rgba(226, 184, 74, .07), rgba(226, 184, 74, 0));
  border-radius: 0 10px 10px 0;
  font-family: var(--font-heading);
  font-size: 18px;
  line-height: 1.62;
  font-weight: 500;
  font-style: italic;
  color: var(--pearl);
}

.dt-body > blockquote p { margin: 0 0 8px; }
.dt-body > blockquote p:last-child { margin-bottom: 0; }

.dt-body > table {
  width: 100%;
  border-collapse: collapse;
  margin: 26px 0;
  border: 1px solid var(--bdr);
  border-radius: 10px;
  overflow: hidden;
  font-family: var(--font-body);
  font-size: 13.5px;
  line-height: 1.65;
}

.dt-body > table th,
.dt-body > table td {
  text-align: left;
  padding: 12px 16px;
  border-bottom: 1px solid rgba(226, 184, 74, .14);
  vertical-align: top;
}

.dt-body > table th {
  font-family: var(--font-mono);
  font-size: 10px;
  font-weight: 600;
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--gold);
  background: rgba(226, 184, 74, .06);
  white-space: nowrap;
}

.dt-body > table td { color: var(--t2); font-weight: 300; }
.dt-body > table tr:last-child td { border-bottom: 0; }

.dt-body strong { color: var(--t0); font-weight: 600; }


/* The cards were reachable by keyboard in v2 through role="link" +
   tabindex="0"; as anchors that is native, but the focus ring needs to be
   visible against a dark page. */
a.sc:focus-visible,
a.con-card:focus-visible,
a.rnd-card:focus-visible,
a.rnd-sector-card:focus-visible,
a.proj-card:focus-visible,
a.blog-card:focus-visible,
a.fdr:focus-visible {
  outline: 2px solid var(--gold);
  outline-offset: 3px;
}


/* ── Page transitions ─────────────────────────────────────────────────────
   v2 slid between sections because all nine lived in one document and the
   router toggled `.active`. Each section is its own URL now, so the same
   feel comes from Astro's ClientRouter and the view-transition pseudo
   elements it drives.

   The timings started as the ones in core.css — .page used a 0.5s ease for
   entry, .exit-up / .exit-down a 0.38s ease with a 44px offset — and were
   then softened on the client's request. Two things make a transition read
   as hard: how far the page travels, and how sharply it starts.

   The travel is now roughly a third of what it was (44px in / 28px out
   became 18px / 12px), which is enough to give the eye a direction without
   the content visibly sliding. The extra duration is what keeps that small
   movement from looking like a jump cut.

   The curves changed with it. cubic-bezier(.4, 0, .2, 1) is Material's
   standard easing: it holds still, then accelerates hard out of rest, which
   is the part that felt abrupt. The outgoing page now uses a sine-shaped
   ease-in-out and the incoming one a pure decelerate, so neither end of the
   navigation has a sudden edge.

   Only the page body animates. Everything in the layout carries
   transition:persist and is excluded below, so the nav, ticker and starfield
   stay put instead of sliding with the content.
------------------------------------------------------------------------- */
/* No `@view-transition { navigation: auto }` here on purpose. That at-rule
   turns on the browser's own cross-document transitions, and ClientRouter
   already drives same-document ones — declaring both makes the browser start
   a transition ClientRouter then takes over, which throws
   "Transition was aborted because of invalid state" on every navigation.
   The pseudo-element styling below is all ClientRouter needs. */
::view-transition-old(root) {
  animation: qsdPageOut .34s cubic-bezier(.37, 0, .63, 1) both;
}

::view-transition-new(root) {
  animation: qsdPageIn .52s cubic-bezier(.22, .61, .36, 1) both;
}

@keyframes qsdPageOut {
  to { opacity: 0; transform: translateY(-12px); }
}

@keyframes qsdPageIn {
  from { opacity: 0; transform: translateY(18px); }
  to   { opacity: 1; transform: translateY(0); }
}

/* A visitor who has asked for less motion gets a plain cross-fade. */
@media (prefers-reduced-motion: reduce) {
  ::view-transition-old(root),
  ::view-transition-new(root) {
    animation-duration: .12s;
    animation-name: qsdFade;
  }
  @keyframes qsdFade { from { opacity: 0; } to { opacity: 1; } }
}


/* ── Mobile menu entries are links now ────────────────────────────────────
   core.css styles them as `.nmob span`, a tag-scoped selector, so turning
   them into <a> for ClientRouter dropped the styling entirely. The same
   treatment is restated for anchors; the span rule is left alone so v2 is
   unaffected.
------------------------------------------------------------------------- */
.nmob a {
  font-family: var(--font-heading);
  font-size: 15px;
  font-weight: 600;
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--t3);
  padding: 12px 0;
  border-bottom: 1px solid rgba(255, 255, 255, .04);
  cursor: pointer;
  transition: color .18s;
}

.nmob a:hover { color: var(--gold); }

/* The Legal group inside the panel keeps its own smaller, indented look. */
.nmob a.nmob-legal {
  padding-left: 14px;
  font-size: 13.5px;
  letter-spacing: .06em;
  text-transform: none;
}


/* ── Cookie bar ───────────────────────────────────────────────────────────
   core.css parks the bar off-screen with transform:translateY(100%), and a
   transformed element is still rendered, still focusable and still read by a
   screen reader — so its two policy links and both buttons sat in the tab
   order at the bottom of every page, reachable by tabbing to nothing visible.

   That is fixed with the `inert` attribute, toggled in ui.js, not here. The
   CSS way is `visibility: hidden` transitioned with a delay so the slide-out
   still plays, and it is the usual answer — but a delayed transition only
   resolves once the frame clock runs, so a backgrounded or interrupted tab
   can leave the bar visible-and-focusable indefinitely. `inert` applies the
   instant the class changes and needs no clock. core.css keeps the transform
   animation untouched either way.
------------------------------------------------------------------------- */

/* The policy links were gold text and nothing else. Colour alone is not a
   link affordance (WCAG 1.4.1), and this site publishes an Accessibility
   Statement — so they are underlined, faintly at rest and fully on hover. */
#cookie p a {
  text-decoration: underline;
  text-underline-offset: 3px;
  text-decoration-thickness: 1px;
  text-decoration-color: rgba(226, 184, 74, .45);
  transition: text-decoration-color .18s;
}

#cookie p a:hover { text-decoration-color: var(--gold); }

#cookie p a:focus-visible,
#cookie .ck-btn:focus-visible {
  outline: 2px solid var(--gold);
  outline-offset: 2px;
}


/* ── "Cookie Settings" in the Legal menu ──────────────────────────────────
   The entry is a <button> because it reopens the consent bar instead of
   navigating. .nlegal-item already declares background:none, border:0,
   width:100% and text-align:left, so only the inherited font and colour a
   button does not take from the page are restated.

   It is separated from the five documents by a rule: those five are pages,
   this one is a control, and they should not read as one list.
------------------------------------------------------------------------- */
button.nlegal-item {
  font: inherit;
  color: inherit;
  margin-top: 4px;
  padding-top: 12px;
  border-top: 1px solid rgba(226, 184, 74, .12);
  border-radius: 0 0 7px 7px;
}

/* The mobile panel styles its entries as `.nmob a` (v3.css above), which a
   button does not match — the same tag-scoped trap the Legal links hit when
   they became anchors. */
.nmob button.nmob-legal {
  display: block;
  width: 100%;
  text-align: left;
  background: none;
  border: 0;
  font-family: var(--font-heading);
  font-weight: 600;
  /* A button does not inherit line-height, and `normal` made this entry 6px
     shorter than the five links beside it. */
  line-height: inherit;
  color: var(--t3);
  padding: 12px 0;
  border-bottom: 1px solid rgba(255, 255, 255, .04);
  cursor: pointer;
  transition: color .18s;
  margin-top: 4px;
  border-top: 1px solid rgba(226, 184, 74, .12);
}

.nmob button.nmob-legal:hover { color: var(--gold); }


/* ── The language control is two links, not one badge ─────────────────────
   core.css line 1021 hides every .nlb that is not the active one:

       .nlangs .nlb:not(.on){display:none!important}

   That rule comes from v1's five language buttons, and fixes.css FIX 8
   records what it did there: exactly one chip was ever visible, and clicking
   it re-selected the language you were already reading — the control was
   inert. Splitting the toggle into one real link per language brought the
   same rule straight back into play. "DE" was display:none, "EN" pointed at
   the page already open, and pressing it did nothing.

   Both are shown now. The .nlangs pill in core.css already has the border,
   radius and overflow:hidden of a segmented control, and .nlb.on already
   carries the gold active state, so EN | DE lands in a container that was
   drawn for exactly this. !important is required to beat the rule above.

   This supersedes FIX 8's #lang-toggle block, which no longer matches
   anything — there is no single toggle button any more. Its rules are left
   in fixes.css rather than deleted, so that file stays comparable with v2.
------------------------------------------------------------------------- */
/* The override has to out-specify core's rule, not just match its
   !important: `.nlangs .nlb:not(.on)` is (0,3,0) because :not() counts the
   class inside it, so a plain `.nlangs a.nlb` at (0,2,1) still loses and DE
   stayed hidden. Repeating :not(.on) here makes it (0,3,1). */
.nlangs a.nlb:not(.on) {
  display: inline-flex !important;
}

.nlangs a.nlb {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 38px;
  cursor: pointer;
  text-decoration: none;
  transition: background .18s, color .18s;
}

.nlangs a.nlb:not(.on):hover {
  background: rgba(226, 184, 74, .14);
  color: var(--gold3);
}

.nlangs a.nlb:focus-visible {
  outline: 2px solid var(--gold);
  outline-offset: 2px;
}


/* ── …and it exists on mobile ─────────────────────────────────────────────
   core.css hides the whole .nlangs pill below 769px, where the nav collapses
   to the hamburger. In v2 that cost nothing, because the control did not do
   anything. With two languages actually published it meant a phone could not
   reach the German site at all except by typing the URL, so the switch is
   repeated in the panel that replaces the nav.
------------------------------------------------------------------------- */
.nmob-lang-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 a.nmob-lang {
  padding-left: 14px !important;
  font-size: 13.5px !important;
  letter-spacing: .06em !important;
  text-transform: none !important;
}

.nmob a.nmob-lang.on {
  color: var(--gold) !important;
}
