/* ==========================================================================
   Base · reset, global typography, layout primitives, motion system
   ========================================================================== */

/* — Reset — */
*,
*::before,
*::after {
  box-sizing: border-box;
}

* {
  margin: 0;
}

html {
  -webkit-text-size-adjust: 100%;
  text-size-adjust: 100%;
  color-scheme: dark;
  scroll-padding-top: calc(var(--header-h) + 1rem);
}

@media (prefers-reduced-motion: no-preference) {
  html {
    scroll-behavior: smooth;
  }
}

/* Taps get explicit press states (see "Press" below and .btn), so the grey system
   flash would only double them. iOS needs the touch listener in main.js for :active;
   if the modules never load, `.js` is removed and the system flash returns. */
.js {
  -webkit-tap-highlight-color: transparent;
}

body {
  min-height: 100svh;
  background: var(--c-bg);
  color: var(--c-fg);
  font-family: var(--font-sans);
  font-size: var(--fs-body);
  font-weight: var(--fw-regular);
  line-height: var(--lh-normal);
  font-synthesis: none;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-rendering: optimizeLegibility;
  overflow-x: clip;
}

img,
picture,
svg,
video {
  display: block;
  max-width: 100%;
}

img {
  height: auto;
}

input,
button,
textarea,
select {
  font: inherit;
  color: inherit;
}

button {
  cursor: pointer;
  background: none;
  border: 0;
  padding: 0;
}

a {
  color: inherit;
  text-decoration: none;
}

a[href^="tel:"] {
  white-space: nowrap;
}

ul[role="list"],
ol[role="list"] {
  list-style: none;
  padding: 0;
}

h1,
h2,
h3,
h4 {
  font-weight: var(--fw-medium);
  line-height: var(--lh-snug);
  text-wrap: balance;
}

p,
li,
dd {
  text-wrap: pretty;
}

/* Long German compounds in small headings may hyphenate instead of overflowing. */
h3,
h4 {
  hyphens: auto;
  overflow-wrap: break-word;
}

address {
  font-style: normal;
}

strong {
  font-weight: var(--fw-semibold);
}

::selection {
  background: var(--c-mint);
  color: var(--c-black);
}

/* — Focus — */
:focus-visible {
  outline: 2px solid var(--c-focus);
  outline-offset: 3px;
  border-radius: 2px;
}

.on-light :focus-visible,
.on-mint :focus-visible,
.on-lavender :focus-visible {
  outline-color: var(--c-black);
}

/* — Press —
   Hover effects only exist where a pointer can hover (`@media (hover: hover)`).
   On touch screens every tap is confirmed instead; .btn has its own, stronger state. */
@media (hover: none) {
  a:not(.btn):active,
  button:not(.btn):active {
    opacity: 0.6;
  }
}

/* — Accessibility helpers — */
.visually-hidden {
  position: absolute !important;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
  border: 0;
}

.skip-link {
  position: fixed;
  left: var(--gutter);
  top: var(--sp-3);
  z-index: var(--z-skip);
  padding: var(--sp-3) var(--sp-5);
  border-radius: var(--r-sm);
  background: var(--c-mint);
  color: var(--c-black);
  font-weight: var(--fw-semibold);
  transform: translateY(-200%);
  transition: transform var(--dur-base) var(--ease-out);
}

.skip-link:focus-visible {
  transform: none;
  outline-color: var(--c-black);
}

/* — Surfaces — */
.on-dark {
  background: var(--c-black);
  color: var(--c-ink-on-dark);
}

.on-light {
  background: var(--c-chalk);
  color: var(--c-ink-on-light);
  color-scheme: light;
}

.on-mint {
  background: var(--c-mint);
  color: var(--c-black);
  color-scheme: light;
}

.on-lavender {
  background: var(--c-lavender);
  color: var(--c-black);
  color-scheme: light;
}

/* — Layout primitives — */
.container {
  width: min(100% - 2 * var(--gutter), var(--container));
  margin-inline: auto;
}

.section {
  padding-block: var(--section-y);
}

.section--flush-top {
  padding-top: 0;
}

.section--flush-bottom {
  padding-bottom: 0;
}

.stack {
  display: flex;
  flex-direction: column;
  gap: var(--stack-gap, var(--sp-5));
}

/* Chapter layout: index label column + content (design: 280px | 1fr). */
.chapter {
  display: grid;
  gap: var(--sp-5) var(--col-gap);
}

@media (min-width: 64em) {
  .chapter {
    grid-template-columns: var(--label-col) minmax(0, 1fr);
  }

  .chapter--end {
    align-items: end;
  }

  .chapter > .chapter__body {
    grid-column: 2;
  }
}

.rule-top {
  border-top: var(--hairline-strong);
  padding-top: var(--sp-5);
}

.on-light .rule-top,
.on-light.rule-top {
  border-top-color: var(--c-chalk-line);
}

/* — Typography primitives — */
.t-label {
  font-size: var(--fs-label);
  line-height: 1.4;
  color: var(--c-ink-on-dark-muted);
  letter-spacing: 0.005em;
}

.on-light .t-label,
.on-light.t-label {
  color: var(--c-ink-on-light-muted);
}

.on-mint .t-label,
.on-lavender .t-label {
  color: inherit;
}

.t-h2 {
  font-size: var(--fs-h2);
  line-height: 1;
  letter-spacing: var(--tracking-heading);
  font-weight: var(--fw-medium);
}

.t-h3 {
  font-size: var(--fs-h3);
  line-height: 1.1;
  letter-spacing: -0.02em;
  font-weight: var(--fw-medium);
}

.t-h4 {
  font-size: var(--fs-h4);
  line-height: 1.25;
  font-weight: var(--fw-semibold);
}

.t-statement {
  font-size: var(--fs-statement);
  line-height: var(--lh-snug);
  letter-spacing: var(--tracking-statement);
  font-weight: var(--fw-medium);
}

.t-lead {
  font-size: var(--fs-lead);
  line-height: var(--lh-normal);
  color: var(--c-ink-on-dark-soft);
  max-width: 46ch;
}

.on-light .t-lead {
  color: var(--c-ink-on-light-soft);
}

.on-mint .t-lead,
.on-lavender .t-lead {
  color: inherit;
}

.t-muted {
  color: var(--c-ink-on-dark-faint);
}

.on-light .t-muted {
  color: var(--c-ink-on-light-muted);
}

.t-mint {
  color: var(--c-mint);
}

.t-index {
  font-variant-numeric: tabular-nums;
}

.prose {
  max-width: var(--container-text);
}

.prose > * + * {
  margin-top: 1em;
}

.prose h2 {
  font-size: var(--fs-h3);
  letter-spacing: -0.02em;
  margin-top: 2.2em;
}

.prose h3 {
  font-size: var(--fs-h4);
  font-weight: var(--fw-semibold);
  margin-top: 1.8em;
}

.prose ul {
  padding-left: 1.2em;
}

.prose li + li {
  margin-top: 0.35em;
}

.prose a {
  text-decoration: underline;
  text-decoration-thickness: 1px;
  text-underline-offset: 0.2em;
}

@media (hover: hover) {
  .prose a:hover {
    color: var(--c-mint);
  }

  .on-light .prose a:hover {
    color: inherit;
    text-decoration-thickness: 2px;
  }
}

/* Masked line: text slides up from behind its own baseline. */
.mask {
  display: block;
  overflow: hidden;
  padding-bottom: 0.08em;
  margin-bottom: -0.08em;
}

.mask > span {
  display: block;
}

/* ==========================================================================
   Motion system
   `html.fx` is set by an inline head script only when the visitor allows
   motion; it is removed again if the JS modules fail to load, so content
   is never hidden without a way back.
   ========================================================================== */

/* Page-load sequence (CSS only, independent of JS so it never delays LCP). */
@keyframes fx-up {
  from { transform: translateY(105%); }
  to { transform: none; }
}

@keyframes fx-rise {
  from { opacity: 0; transform: translateY(2.5rem); }
  to { opacity: 1; transform: none; }
}

@keyframes fx-fade {
  from { opacity: 0; }
  to { opacity: 1; }
}

@keyframes fx-scale {
  from { opacity: 0; transform: scale(0.2); }
  to { opacity: 1; transform: none; }
}

.fx [data-load="up"] {
  animation: fx-up var(--dur-mask) var(--ease-out) var(--d, 0ms) both;
}

.fx [data-load="rise"] {
  animation: fx-rise var(--dur-slow) var(--ease-out) var(--d, 0ms) both;
}

.fx [data-load="fade"] {
  animation: fx-fade var(--dur-reveal) linear var(--d, 0ms) both;
}

.fx [data-load="scale"] {
  animation: fx-scale var(--dur-reveal) var(--ease-out) var(--d, 0ms) both;
}

/* Scroll reveals (classes toggled by js/motion.js via IntersectionObserver). */
.fx [data-reveal] {
  transition:
    opacity var(--dur-slow) var(--ease-out) var(--d, 0ms),
    transform var(--dur-slow) var(--ease-out) var(--d, 0ms);
}

.fx [data-reveal="rise"]:not(.is-in) {
  opacity: 0;
  transform: translateY(3rem);
}

.fx [data-reveal="fade"] {
  transition-duration: var(--dur-reveal);
}

.fx [data-reveal="fade"]:not(.is-in) {
  opacity: 0;
}

.fx [data-reveal="up"] > span {
  transition: transform var(--dur-mask) var(--ease-out) var(--d, 0ms);
}

.fx [data-reveal="up"]:not(.is-in) > span {
  transform: translateY(105%);
}

@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    animation-duration: 1ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 1ms !important;
    scroll-behavior: auto !important;
  }
}
