/* ═══════════════════════════════════════════════════════════════════════════
   CHROME. The quiet layer.

   Everything in this file is what the visitor operates: nav, buttons, the
   language switch, the menu, chips, the toast. It is deliberately calmer than
   the story behind it. Nothing here runs longer than 260ms and nothing here
   uses ease-in. That contrast between a loud stage and still controls is the
   whole difference between a page that reads as built and one that reads as
   generated.
   ═══════════════════════════════════════════════════════════════════════════ */

/* ───────────────────────────────  RESET  ─────────────────────────────── */

*, *::before, *::after { box-sizing: border-box; }
* { margin: 0; padding: 0; }

html {
  -webkit-text-size-adjust: 100%;
  scroll-behavior: smooth;
  scroll-padding-top: 92px;
}

body {
  background: var(--bg);
  color: var(--ink);
  font-family: var(--font-body);
  font-size: var(--fs-body);
  line-height: var(--lh-body);
  letter-spacing: var(--tr-body);
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-rendering: optimizeLegibility;
  overflow-x: hidden;
}

img, svg, video { display: block; max-width: 100%; }
[hidden] { display: none !important; }
button, input { font: inherit; color: inherit; }
button { background: none; border: 0; cursor: pointer; }
a { color: inherit; text-decoration: none; }
fieldset { border: 0; }
ol, ul { list-style: none; }

:focus-visible {
  outline: 2px solid var(--focus);
  outline-offset: 3px;
  border-radius: 3px;
}

.sr-only {
  position: absolute;
  width: 1px; height: 1px;
  padding: 0; margin: -1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}

.skip {
  position: fixed; top: 12px; left: 12px; z-index: 300;
  padding: 11px 18px;
  border-radius: var(--r-pill);
  background: var(--ink); color: var(--bg);
  font-weight: 600;
  transform: translateY(-180%);
  transition: transform var(--t-panel) var(--ease-out);
}
.skip:focus-visible { transform: translateY(0); }

/* ───────────────────────────────  TYPE  ─────────────────────────────── */

/* The cqi cap is what keeps German inside its column. "eine Entscheidung." is
   eighteen characters where the English line is eleven, and a viewport-based
   size has no idea that happened. Sized against the column, the type simply
   fits, in both languages, at every width. */
.display {
  font-family: var(--font-display);
  font-size: min(var(--fs-display), 10.5cqi);
  font-weight: 600;
  line-height: var(--lh-display);
  letter-spacing: var(--tr-display);
  text-wrap: balance;
}

.h2 {
  font-family: var(--font-display);
  font-size: min(var(--fs-h2), 9cqi);
  font-weight: 600;
  line-height: var(--lh-h2);
  letter-spacing: var(--tr-h2);
  text-wrap: balance;
  max-width: 18ch;
}

h3 {
  font-family: var(--font-display);
  font-size: var(--fs-h3);
  font-weight: 600;
  line-height: 1.2;
  letter-spacing: -0.015em;
}

.lead {
  font-size: var(--fs-lead);
  color: var(--ink-2);
  text-wrap: pretty;
}

.measure { max-width: 54ch; }

.mono {
  font-family: var(--font-mono);
  font-variant-numeric: tabular-nums;
  font-size: var(--fs-micro);
  letter-spacing: 0.01em;
}

/* Rationed to four across the page. See the pre-flight check in the README. */
.eyebrow {
  font-family: var(--font-mono);
  font-size: 0.6875rem;
  font-weight: 500;
  text-transform: uppercase;
  letter-spacing: var(--tr-micro);
  color: var(--accent-ink);
}

.beat {
  font-size: 1.0625rem;
  font-weight: 500;
  color: var(--ink);
  max-width: 46ch;
  padding-left: 1.1rem;
  border-left: 2px solid var(--accent);
}

.wordmark {
  font-family: var(--font-display);
  font-weight: 600;
  font-size: 1.0625rem;
  letter-spacing: -0.02em;
}
.wordmark--sm { font-size: 0.95rem; }
/* the second half of the name, one tone quieter. Same family, same size:
   the seam is carried by colour and weight alone, never by a second font. */
.wordmark__lite { color: var(--ink-2); font-weight: 500; }

/* ───────────────────────────────  LAYOUT  ─────────────────────────────── */

.wrap {
  width: 100%;
  max-width: var(--maxw);
  margin-inline: auto;
  padding-inline: var(--gutter);
}

/* ───────────────────────────────  BUTTONS  ─────────────────────────────── */

.btn {
  --btn-y: 0.85rem;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.5rem;
  padding: var(--btn-y) 1.5rem;
  border-radius: var(--r-pill);
  font-weight: 600;
  font-size: 0.9375rem;
  letter-spacing: -0.008em;
  white-space: nowrap;
  transition:
    transform var(--t-press) var(--ease-out),
    background-color var(--t-nav) var(--ease-out),
    border-color var(--t-nav) var(--ease-out),
    color var(--t-nav) var(--ease-out);
}
.btn:active { transform: scale(0.97); }

/* ── the lit surface ───────────────────────────────────────────────────────
   A button filled with one hex value is the most recognisable tell of a
   generated page. Nothing on this page is a flat fill: every lit surface has
   a gradient down the face, one hairline of near-white along the top edge as
   the specular, and a bloom underneath so it sits ON the page instead of in
   it.

   ── the hover ──────────────────────────────────────────────────────────
   This is what replaced the cat. Coming near it, the button does what a lit
   object does: it gets brighter, its bloom widens, and a soft band of light
   travels once across its face. Three separate things, and all three are
   free: brightness is a filter, the bloom is a box-shadow, and the sweep is a
   transform on a pseudo-element, so not one of them repaints the button.

   The sweep runs once per hover rather than on a loop. A looping shine is a
   "buy now" banner; a single pass reads as light catching a surface as you
   move past it.
   ───────────────────────────────────────────────────────────────────────── */
.btn--primary {
  position: relative;
  overflow: hidden;
  background: var(--metal);
  color: var(--on-accent);
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, 0.55),
    inset 0 -1px 0 rgba(0, 0, 0, 0.2),
    0 8px 22px rgba(0, 0, 0, 0.45),
    0 0 0 0.5px rgba(0, 0, 0, 0.28),
    0 0 0 0 var(--accent-soft);
  /* the bloom eases over half a second on purpose: at 260ms a cursor
     swept quickly left-right strobed the glow against the dark sky beside
     the button - a flashing light where nothing is. Slow both ways, the
     rapid passes average into one soft breath. */
  transition:
    transform var(--t-press) var(--ease-out),
    filter 420ms var(--ease-out),
    box-shadow 560ms var(--ease-out);
}
/* the travelling band of light. Off screen to the left until hovered. */
.btn--primary::after {
  content: "";
  position: absolute;
  inset: -40% -10%;
  pointer-events: none;
  background: linear-gradient(100deg,
    transparent 34%,
    rgba(255, 255, 255, 0.55) 50%,
    transparent 66%);
  transform: translateX(-130%);
}

@media (hover: hover) and (pointer: fine) {
  .btn--primary:hover {
    filter: brightness(1.22) saturate(1.06);
    box-shadow:
      inset 0 1px 0 rgba(255, 255, 255, 0.8),
      inset 0 -1px 0 rgba(0, 0, 0, 0.2),
      0 12px 34px rgba(0, 0, 0, 0.5),
      0 0 0 0.5px rgba(0, 0, 0, 0.28),
      0 0 34px -2px color-mix(in srgb, var(--accent) 62%, transparent);
  }
  .btn--primary:hover::after {
    transform: translateX(130%);
    /* the 140ms delay is the whole fix: a cursor merely passing through
       never starts the sweep, so fast passes cannot flicker a band of
       light at the button's left edge. A real hover never notices it. */
    transition: transform 720ms var(--ease-out) 140ms;
  }
  .btn--ghost:hover {
    border-color: var(--accent);
    background: var(--surface);
    box-shadow: 0 0 22px -6px color-mix(in srgb, var(--accent) 45%, transparent);
  }
}

/* ───────────────────────────────  NAV  ─────────────────────────────── */

.nav {
  position: fixed;
  inset: 0 0 auto 0;
  z-index: 120;
  height: 68px;
  display: flex;
  align-items: center;
  /* Declared, not inherited. The bar carries its own data-chapter, so colour
     has to be resolved here or the wordmark keeps the body's night ink while
     the bar itself turns to paper. */
  color: var(--ink);
  transition: background-color var(--t-nav) var(--ease-out),
              border-color var(--t-nav) var(--ease-out),
              color var(--t-nav) var(--ease-out);
  /* the bar is a BAR from the first frame (v15): it used to sit glass-less
     over the hero and only put its background on once the hero was behind
     it, which read as the bar not existing until you scrolled. Same glass,
     always; .is-stuck still toggles but no longer changes anything. */
  background: var(--glass);
  -webkit-backdrop-filter: blur(18px) saturate(170%);
  backdrop-filter: blur(18px) saturate(170%);
  border-bottom: 1px solid var(--line);
}
.nav.is-stuck {
  background: var(--glass);
  -webkit-backdrop-filter: blur(18px) saturate(170%);
  backdrop-filter: blur(18px) saturate(170%);
  border-bottom-color: var(--line);
}

.nav__in {
  width: 100%;
  max-width: var(--maxw);
  margin-inline: auto;
  padding-inline: var(--gutter);
  display: flex;
  align-items: center;
  gap: 1.5rem;
}

.nav__brand { display: flex; align-items: center; gap: 0.6rem; }
.nav__mark {
  width: 13px; height: 22px;
  border: 1.5px solid var(--accent);
  border-radius: 3px;
}

.nav__links {
  display: flex;
  gap: 1.6rem;
  margin-inline: auto;
  font-size: 0.9rem;
}
.nav__links a {
  color: var(--ink-2);
  position: relative;
  padding-block: 0.35rem;
  transition: color var(--t-nav) var(--ease-out);
}
.nav__links a::after {
  content: "";
  position: absolute;
  left: 0; right: 0; bottom: 0;
  height: 1.5px;
  background: var(--accent);
  transform: scaleX(0);
  transform-origin: left;
  transition: transform var(--t-nav) var(--ease-out);
}
.nav__links a.is-here { color: var(--ink); }
.nav__links a.is-here::after { transform: scaleX(1); }
@media (hover: hover) and (pointer: fine) {
  .nav__links a:hover { color: var(--ink); }
}

.nav__right { display: flex; align-items: center; gap: 0.75rem; margin-left: auto; }

/* language switch. 160ms, and the pill is the only thing that moves. */
.lang {
  position: relative;
  display: flex;
  padding: 3px;
  border: 1px solid var(--line);
  border-radius: var(--r-pill);
}
.lang__pill {
  position: absolute;
  top: 3px; left: 3px;
  width: 42px; height: calc(100% - 6px);
  border-radius: var(--r-pill);
  background: var(--surface-2);
  transition: transform var(--t-lang) var(--ease-out);
}
.lang[data-on="de"] .lang__pill { transform: translateX(42px); }
.lang__btn {
  position: relative;
  width: 42px;
  padding-block: 0.3rem;
  font-family: var(--font-mono);
  font-size: 0.6875rem;
  font-weight: 500;
  letter-spacing: 0.06em;
  color: var(--ink-3);
  transition: color var(--t-lang) var(--ease-out);
}
.lang__btn.is-on { color: var(--ink); }
.lang__btn:active { transform: scale(0.97); }

.nav__burger {
  display: none;
  width: 40px; height: 40px;
  border-radius: var(--r-sm);
  padding: 12px 10px;
  flex-direction: column;
  justify-content: space-between;
}
.nav__burger span {
  display: block;
  height: 1.5px;
  background: var(--ink);
  transition: transform var(--t-menu) var(--ease-out);
}
.nav__burger[aria-expanded="true"] span:first-child { transform: translateY(7px) rotate(45deg); }
.nav__burger[aria-expanded="true"] span:last-child  { transform: translateY(-7px) rotate(-45deg); }

/* mobile sheet. 220ms, drawer curve, translate only. */
.sheet {
  position: fixed;
  inset: 68px 0 auto 0;
  z-index: 110;
  padding: 1.25rem var(--gutter) 1.75rem;
  background: var(--glass);
  -webkit-backdrop-filter: blur(20px) saturate(170%);
  backdrop-filter: blur(20px) saturate(170%);
  border-bottom: 1px solid var(--line);
  transform: translateY(-102%);
  transition: transform var(--t-menu) var(--ease-drawer);
}
.sheet.is-open { transform: translateY(0); }
.sheet__nav { display: grid; gap: 0.35rem; }
.sheet__nav a {
  padding: 0.65rem 0;
  font-family: var(--font-display);
  font-size: 1.2rem;
  font-weight: 500;
  border-bottom: 1px solid var(--line);
}

@media (max-width: 900px) {
  .nav__links { display: none; }
  .nav__burger { display: flex; }
  .nav .btn--primary { display: none; }
}

/* ───────────────────────────────  CHIPS  ─────────────────────────────── */

.chip {
  display: inline-flex;
  align-items: center;
  padding: 0.5rem 0.95rem;
  border: 1px solid var(--line-2);
  border-radius: var(--r-pill);
  font-size: 0.875rem;
  font-weight: 500;
  color: var(--ink-2);
  transition:
    transform var(--t-press) var(--ease-out),
    border-color var(--t-nav) var(--ease-out),
    background-color var(--t-nav) var(--ease-out),
    color var(--t-nav) var(--ease-out);
}
button.chip:active { transform: scale(0.97); }
.chip.is-on {
  background: var(--accent-soft);
  border-color: var(--accent);
  color: var(--ink);
}
@media (hover: hover) and (pointer: fine) {
  button.chip:hover { border-color: var(--ink-3); color: var(--ink); }
}

/* ───────────────────────────────  AI LABEL  ─────────────────────────────
   Sits inside the same box as its media so it can never exist without the
   image it is labelling. Same badge the product stamps on publish, which is
   why it is also a line in the dossier.
   ───────────────────────────────────────────────────────────────────────── */

.ai-tag {
  position: absolute;
  top: 8px; right: 8px;
  z-index: 2;
  padding: 0.3rem 0.65rem;
  border-radius: var(--r-pill);
  background: rgba(10, 10, 12, 0.74);
  -webkit-backdrop-filter: blur(8px);
  backdrop-filter: blur(8px);
  color: #FFFFFF;
  font-family: var(--font-body);
  font-size: 0.6875rem;
  font-weight: 600;
  letter-spacing: -0.005em;
  line-height: 1.25;
  white-space: nowrap;
  pointer-events: none;
}
.ai-tag--lg { top: 12px; right: 12px; font-size: 0.8125rem; padding: 0.38rem 0.85rem; }

/* ───────────────────────────────  TOAST  ─────────────────────────────── */

.toast {
  position: fixed;
  left: 50%; bottom: 22px;
  z-index: 200;
  display: flex;
  align-items: center;
  gap: 0.9rem;
  padding: 0.7rem 0.7rem 0.7rem 1.15rem;
  border: 1px solid var(--line);
  border-radius: var(--r-pill);
  background: var(--glass);
  -webkit-backdrop-filter: blur(18px);
  backdrop-filter: blur(18px);
  box-shadow: var(--shadow-s);
  font-size: 0.875rem;
  /* percentages are relative to the toast's own size, so this works at any width */
  transform: translate(-50%, 0);
  /* on the token system like everything else in the chrome: the drawer curve,
     because a toast is a small sheet, and inside the 300ms budget */
  transition: transform var(--t-panel) var(--ease-drawer), opacity var(--t-panel) var(--ease-out);
}
@starting-style {
  .toast { transform: translate(-50%, 140%); opacity: 0; }
}
.toast.is-out { transform: translate(-50%, 140%); opacity: 0; }
.toast button {
  padding: 0.42rem 0.9rem;
  border-radius: var(--r-pill);
  background: var(--surface-2);
  font-size: 0.8125rem;
  font-weight: 600;
  transition: transform var(--t-press) var(--ease-out), background-color var(--t-nav) var(--ease-out);
}
.toast button:active { transform: scale(0.97); }

/* ───────────────────────────────  FOOTER  ─────────────────────────────── */

/* Positioned on purpose. The backdrop is a fixed layer at z-index 0, and a
   positioned element beats an unpositioned one's background no matter where it
   sits in the source. Without this the footer is painted over by the gradient
   and the legal links are invisible while being perfectly present in the DOM. */
.foot {
  position: relative;
  z-index: 3;
  background: var(--bg);
  border-top: 1px solid var(--line);
}
.foot__in { display: grid; gap: 0.5rem; }
.foot__line { color: var(--ink-2); }

/* Small, last, and underlined. Legal links that look like body text are the
   ones nobody finds; these are quiet but obviously clickable. */
.foot__links {
  display: flex;
  flex-wrap: wrap;
  gap: 0.35rem 1.35rem;
  margin-top: 1.4rem;
  padding-top: 1.1rem;
  border-top: 1px solid var(--line);
}
.foot__links a {
  color: var(--ink-3);
  font-size: 0.8125rem;
  text-decoration: underline;
  text-decoration-color: var(--line-2);
  text-underline-offset: 3px;
  transition: color var(--t-nav) var(--ease-out), text-decoration-color var(--t-nav) var(--ease-out);
}
@media (hover: hover) and (pointer: fine) {
  .foot__links a:hover { color: var(--ink); text-decoration-color: var(--accent); }
}

/* the bottom bar. The legal links were present and effectively invisible:
   dim, small, and floating in a large empty footer. Now they sit on their own
   rule at the very bottom with the copyright, which is where people look. */
.foot { padding-block: 3.5rem 2rem; }
.foot__top { display: grid; gap: 0.4rem; }
.foot__bar {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.6rem 1.5rem;
  margin-top: 2.25rem;
  padding-top: 1.25rem;
  border-top: 1px solid var(--line);
}
.foot__copy { color: var(--ink-3); }
.foot__links { margin: 0; padding: 0; border: 0; margin-left: auto; }
.foot__links a { color: var(--ink-2); }
