/* ============================================================
   Alexander Kucera — Landing Page
   Design system: brutalist-web, committed cobalt, Concourse.
   See DESIGN.md. Tokens are normative; do not redefine in prose.
   ============================================================ */
/* ---------- Fonts — Concourse OT (licensed, MB Type), subset to latin.
   Weights present: Book(3), Medium(4), Semibold(6), Bold(7), Black(8).
   Fallback stack below is a neutral system grotesque. ---------- */
@font-face {
  font-family: "Concourse";
  font-weight: 400;
  font-style: normal;
  font-display: swap;
  src: url("../assets/fonts/concourse-book.woff2") format("woff2");
}
@font-face {
  font-family: "Concourse";
  font-weight: 500;
  font-style: normal;
  font-display: swap;
  src: url("../assets/fonts/concourse-medium.woff2") format("woff2");
}
@font-face {
  font-family: "Concourse";
  font-weight: 600;
  font-style: normal;
  font-display: swap;
  src: url("../assets/fonts/concourse-semibold.woff2") format("woff2");
}
@font-face {
  font-family: "Concourse";
  font-weight: 700;
  font-style: normal;
  font-display: swap;
  src: url("../assets/fonts/concourse-bold.woff2") format("woff2");
}
@font-face {
  font-family: "Concourse";
  font-weight: 800;
  font-style: normal;
  font-display: swap;
  src: url("../assets/fonts/concourse-black.woff2") format("woff2");
}

/* ---------- Tokens ---------- */
:root {
  /* Color — OKLCH. Committed cobalt carries 30-60% of the surface. */
  --cobalt:        oklch(0.6676 0.1348 235.31);  /* committed field: dusted blueprint blue */
  --cobalt-link:   oklch(0.42 0.16 235);          /* darker shade of the same hue for inline links/tags/focus on cream — the field token is too light to clear AA as text */
  --cream:         oklch(96% 0.014 250);  /* cool paper tinted toward cobalt — sole ground; DESIGN.md names no second */
  --ink:           oklch(18% 0.012 250);  /* DESIGN.md near-black ink; darkened to clear AA on the lighter cobalt field */
  --ink-soft:      oklch(40% 0.012 250);
  --rule:          oklch(72% 0.012 250);
  --rule-on-cobalt: oklch(18% 0.012 250 / 0.35);  /* ink rule at low alpha over the lighter committed field */

  /* Type — single licensed family, weight+tracking carries hierarchy. */
  --font: "Concourse", ui-sans-serif, system-ui, -apple-system,
          "Helvetica Neue", Arial, sans-serif;

  /* Modular scale, 1.333 ratio, fluid via clamp. */
  --display: clamp(3.5rem, 11vw, 9rem);
  --headline: clamp(2rem, 4.5vw, 3.25rem);
  --title: clamp(1.25rem, 2vw, 1.75rem);
  --body: 1.0625rem;
  --label: 0.8125rem;

  /* Easing — exponential ease-outs only, never bouncy. */
  --ease-out-quart: cubic-bezier(0.25, 1, 0.5, 1);
  --ease-out-expo:  cubic-bezier(0.16, 1, 0.3, 1);

  /* Band width: the committed-color anchor. */
  --band: clamp(260px, 24vw, 360px);
}

/* ---------- Reset ---------- */
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
html { -webkit-text-size-adjust: 100%; scroll-behavior: smooth; }
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
}
img { display: block; max-width: 100%; height: auto; }
a { color: inherit; }
ul, ol { list-style: none; }

/* ---------- Base ---------- */
body {
  font-family: var(--font);
  background: var(--cream);
  color: var(--ink);
  font-size: var(--body);
  line-height: 1.55;
  font-weight: 400;
  overflow-x: clip;   /* clip, not hidden: no scroll container, so sticky/positioned descendants in the cobalt band stay intact */
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

.skip-link {
  position: absolute;
  left: -9999px;
  top: 0;
  z-index: 100;
  background: var(--cobalt);
  color: var(--ink);
  padding: 0.75rem 1.25rem;
  font-size: var(--label);
  letter-spacing: 0.1em;
  text-transform: uppercase;
}
.skip-link:focus { left: 0; }

:focus-visible {
  outline: 3px solid var(--cobalt-link);
  outline-offset: 3px;
}

/* ============================================================
   Canvas: two columns. Main scrolls; cobalt band is sticky,
   full viewport height, content top-aligned so the form is
   reachable without scrolling to the page bottom.
   ============================================================ */
.canvas {
  display: grid;
  grid-template-columns: 1fr var(--band);
  align-items: start;
}

.main-col {
  grid-column: 1;
  grid-row: 1;            /* explicit row stops sparse auto-flow from dropping this column to row 2 when the cobalt aside is DOM-first */
  min-width: 0;            /* prevents grid blowout from child content */
}

.field--cobalt {
  grid-column: 2;
  grid-row: 1;            /* share row 1 with .main-col regardless of DOM order */
  position: sticky;
  top: 0;
  min-height: 100vh;       /* min-height + no overflow: band can grow past viewport, wheel passes to the page instead of being captured by the band */
}

/* ============================================================
   HERO FIELD: name lower-left, headshot mid-right, big air.
   ============================================================ */
.field--cream {
  position: relative;
  padding: clamp(2rem, 7vw, 6rem) clamp(1.5rem, 6vw, 6rem);
  min-height: 100vh;
  display: flex;
  flex-direction: column;
  justify-content: flex-end;   /* name pushed to the bottom */
  overflow: hidden;
}

  /* Reserve the portrait column so the name never collides with the photo. */
.hero { max-width: min(20ch, calc(100% - clamp(240px, 26vw, 420px))); }

.lede {
  font-size: 0.875rem;  /* 14px: lede is body-adjacent (the role line a recruiter scans); structural labels stay at --label (13px) */
  font-weight: 400;
  letter-spacing: 0.02em;
  color: var(--ink-soft);
  margin-top: 1.5rem;
  padding-left: 4px; /* optical: aligns with display's left bearing after -0.04em tracking */
  white-space: nowrap;   /* lede overflows the 20ch hero into the cream field on one line; the field is wide enough above ~480px. Below that the field itself goes narrow and the middots give clean break points, so the ≤480 block flips to normal. */
}

.display {
  font-weight: 800;
  font-size: var(--display);
  line-height: 0.88;
  letter-spacing: -0.04em;
  /* text-wrap: balance dropped: the manual <br> owns the break, balance would fight it at extreme widths. */
}

/* The verdict line: one decisive build-statement between name and lede.
   Headline weight, one scale-jump down from display, tight tracking.
   This is the 30-second scanner's verdict — Concourse semibold, not bold,
   so the display name still owns the top of the hierarchy. */
.verdict {
  font-weight: 600;
  font-size: clamp(1.3rem, 2.6vw, 1.9rem);
  line-height: 1.15;
  letter-spacing: -0.02em;
  text-wrap: balance;
  max-width: 16ch;
  margin-top: 1.25rem;
  padding-left: 4px; /* optical: matches .lede's bearing alignment */
  color: var(--ink);
}

/* Headshot: mid-right of the cream field, sat on a committed cobalt field that bleeds
   off the top and right edges; a strip of cobalt shows left and below the photo.
   Depth via color reversal, not a card or stripe. */
.portrait {
  position: absolute;
  top: 0;
  right: 0;
  width: clamp(220px, 26vw, 360px);
  background: var(--cobalt);
  padding: 0 0 clamp(1.5rem, 4vw, 3rem) clamp(1.5rem, 4vw, 3rem);
}
.portrait img {
  display: block;
  width: 100%;
  aspect-ratio: 3 / 4;
  object-fit: cover;
  filter: grayscale(0.9) contrast(1.05);
}

/* ---------- Hero contact door (mobile only).
   Above 860px the sticky cobalt band is always visible, so it is the door.
   On mobile the band collapses to the page bottom, so this compact cobalt CTA
   in the hero keeps the door above the fold. The email IS the door; this is
   the hero-CTA half of the hero-CTA + closing-band pair. ---------- */
.hero-door { display: none; }

/* ============================================================
   WORK FIELD: what I build, categorical lines with anchors.
   ============================================================ */
.field--work {
  padding: clamp(4rem, 10vw, 9rem) clamp(1.5rem, 6vw, 6rem) clamp(3rem, 7vw, 5rem);
  display: flex;
  flex-direction: column;
  gap: clamp(2rem, 5vw, 3.5rem);
}

.headline {
  font-weight: 700;
  font-size: var(--headline);
  line-height: 1.02;
  letter-spacing: -0.025em;
  max-width: 14ch;
}

.work-list {
  display: flex;
  flex-direction: column;
  max-width: 52ch;
  /* ponytail: no flex gap — each .work-item carries its own padding-bottom above
     its border-bottom rule. gap + padding-bottom double-spaced the rhythm; the rule
     is the separator (brutalist visible-structure voice, DESIGN.md §4). */
}

.work-item {
  display: grid;
  grid-template-columns: 4.5rem 1fr;
  gap: 1rem;
  align-items: start;   /* start, not baseline: the tag tops out with the proof line (the marquee), not the second prose line's baseline */
  padding-bottom: calc(clamp(1.25rem, 2.5vw, 2rem) + 0.5rem); /* extra inset above the rule */
  border-bottom: 1px solid var(--rule);
}
.work-item:last-child { border-bottom: none; }

.work-tag {
  font-size: var(--label);
  font-weight: 500;         /* medium: inline category metadata, DESIGN.md label spec.
                               Small-type voice ramp — lede 400 (prose) / tag 500 (metadata) /
                               kicker 600 (eyebrow). One size band, separated by weight, not rescaled. */
  letter-spacing: 0.12em;   /* DESIGN.md label band 0.08–0.12em */
  text-transform: uppercase;
  color: var(--cobalt-link);
}

.work-body { font-weight: 400; color: var(--ink); }

/* Proof line: the scannable marquee tokens. Sits above the prose,
   semibold so the eye lands on the named proof first. DESIGN.md forbids
   a logo wall; text tokens are what keeps this inside the rule. */
.work-proof {
  font-weight: 600;
  font-size: 1.0625rem;
  line-height: 1.4;
  margin-bottom: 0.35rem;
}
.work-prose { color: var(--ink-soft); }
.work-prose .link { color: var(--ink); text-decoration-color: var(--ink); text-decoration-thickness: 2px; }
.work-proof .link { color: var(--cobalt-link); }   /* link shade clears AA on cream */

/* ============================================================
   BABYLON DREAMS NOTE: its own moment, cobalt rule above.
   ============================================================ */
.field--note {
  padding: 0 clamp(1.5rem, 6vw, 6rem) clamp(4rem, 9vw, 8rem);
}

.rule--cobalt {
  border: none;
  border-top: 3px solid var(--cobalt);
  margin-bottom: clamp(2.25rem, 5vw, 3.5rem);   /* let the rule breathe before the note lands */
}

.note {
  font-size: var(--title);
  font-weight: 400;
  line-height: 1.4;
  max-width: 40ch;
  color: var(--ink);
}
.note strong { font-weight: 700; }

/* Forward closer: ends the page on the door, not the elegy (peak-end).
   Statement weight, ink not cobalt — the email link carries the accent role. */
.closer {
  font-size: var(--title);
  font-weight: 600;
  line-height: 1.2;
  letter-spacing: -0.01em;
  margin-top: clamp(2rem, 5vw, 3rem);
  color: var(--ink);
  max-width: 40ch;
}
.closer .link { color: var(--cobalt-link); }

/* ============================================================
   COBALT BAND: the one obvious door. Ink-on-cobalt (field lightened, so dark text reads).
   ============================================================ */
.field--cobalt {
  background: var(--cobalt);
  color: var(--ink);
  padding: clamp(2.5rem, 6vw, 5rem) clamp(1.75rem, 3vw, 2.75rem);
  display: flex;
  flex-direction: column;
  gap: clamp(1.5rem, 3vw, 2.5rem);
  container-type: inline-size;   /* email scales with band width, not viewport */
}

/* The email IS the door: poster-scale, horizontal, dominant in the band.
   Kicker is a tight eyebrow + rule; the email owns the full column width. */
.contact-vert {
  display: flex;
  flex-direction: column;
  gap: 0.85rem;
  margin-bottom: auto;          /* push the link list to the band bottom */
}

.contact-kicker {
  font-size: var(--label);
  font-weight: 600;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--ink);
  padding-bottom: 0.6rem;
  border-bottom: 2px solid var(--ink);
  align-self: flex-start;        /* rule hugs the label, doesn't span the band */
}

.contact-primary {
  font-size: clamp(1.875rem, 14cqi, 3rem);  /* cqi: tracks band width so the address never reflows mid-token */
  font-weight: 700;
  line-height: 1.02;
  letter-spacing: -0.01em;
  text-decoration: none;
  color: var(--ink);
  transition: opacity 0.2s var(--ease-out-quart);
}
.contact-primary span { display: inline-block; width: 100%; white-space: nowrap; }  /* hand-stacked lines; each token stays whole. inline-block (not block) so selecting the address copies as one line — block spans inject newlines between tokens on copy */
.contact-primary:hover { opacity: 0.85; }
.contact-primary:focus-visible { outline-color: var(--ink); }

.contact-links {
  display: flex;
  flex-direction: column;
}

/* Secondary doors: a ruled list, ink-on-cobalt. Exposed structure, not cards.
   Each row is a 44px+ touch target (WCAG 2.5.5) and carries its own rule line. */
.contact-link {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  min-height: 44px;
  padding: 0.65rem 0;
  font-size: var(--body);
  font-weight: 500;
  letter-spacing: 0.005em;
  text-decoration: none;
  color: var(--ink);
  border-top: 1px solid var(--rule-on-cobalt);   /* rule stays put: hover nudges the label via transform, not padding, so this line never shifts */
}
.contact-link:last-child { border-bottom: 1px solid var(--rule-on-cobalt); }
.contact-link-text { transition: transform 0.18s var(--ease-out-quart); }   /* translateX, not padding-left: avoids animating a layout property and keeps the border-top rule anchored */
.contact-link .arrow { font-size: 0.85em; opacity: 0.85; }
.contact-link:hover .contact-link-text { transform: translateX(0.45rem); }   /* nudge-only hover: the label slides, the field stays. Opacity dim is SaaS hover; the brutalist move is the visible nudge */
.contact-link:focus-visible { outline-color: var(--ink); }

/* (merged into the main 860px block below) */

/* ============================================================
   Links — cobalt-link inline links, ink links in band.
   ============================================================ */
.link {
  color: var(--cobalt-link);
  font-weight: 600;
  text-decoration: underline;
  text-decoration-color: var(--cobalt-link);
  text-decoration-thickness: 1.5px;
  text-underline-offset: 2px;
  text-decoration-skip-ink: auto;
  transition: text-decoration-thickness 0.25s var(--ease-out-quart);
}
.link:hover { text-decoration-thickness: 2.5px; }

.field--cobalt a { color: var(--ink); }

/* ============================================================
   Responsive: band folds to a full-bleed section below ~860px.
   ============================================================ */
@media (max-width: 860px) {
  /* Band is no longer sticky-full-height stacked; cap the email block's bottom gap. */
  .contact-vert { margin-bottom: 1.5rem; }

  .canvas {
    grid-template-columns: 1fr;

  .main-col { grid-row: auto; }   /* same release; desktop pins row 1 for the two-col layout, mobile lets flow take over */
  }
  .field--cobalt {
    grid-column: 1;
    grid-row: auto;          /* release desktop's explicit row 1 so auto-flow + order can sequence; otherwise it collides with .main-col in the same cell */
    order: 1;                /* DOM-first for tab order, but visually last on mobile (single-column grid paints by order, not grid-column) */
    position: static;        /* disable sticky on mobile */
    height: auto;
    min-height: auto;
    padding: clamp(3rem, 12vw, 5rem) clamp(1.5rem, 6vw, 2rem);
  }

  .field--cream {
    min-height: auto;
    padding-top: clamp(1.5rem, 12vw, 3rem);
    padding-bottom: clamp(2.5rem, 14vw, 5rem);
    justify-content: flex-end;
  }

  /* Headshot: cobalt block breaks out of the cream padding to full-bleed top/sides */
  .portrait {
    position: static;
    width: auto;
    margin-inline: calc(-1 * clamp(1.5rem, 6vw, 2rem));
    padding: clamp(1rem, 4vw, 1.5rem) clamp(1.25rem, 5vw, 2rem)
             clamp(1.5rem, 5vw, 2.25rem);
    margin-bottom: clamp(2rem, 10vw, 3.5rem);
  }

  .display { font-size: clamp(3.5rem, 18vw, 7rem); }
  .lede { margin-bottom: clamp(1rem, 4vw, 1.75rem); }

  /* Hero contact door: flat cobalt field, cream type, no radius. A 44px+ touch
     target (WCAG 2.5.5) and the same opacity hover as the closing band's email. */
  .hero-door {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 1rem;
    margin-top: clamp(1.5rem, 5vw, 2.25rem);
    margin-inline: calc(-1 * clamp(1.5rem, 6vw, 2rem));   /* break out full-bleed, same as .portrait, so the cobalt door spans the same width as the portrait block below */
    padding: clamp(0.95rem, 3vw, 1.15rem) clamp(1.25rem, 5vw, 2rem);   /* horizontal padding matches .portrait's image inset, so the email text aligns with the portrait edges */

    background: var(--cobalt);
    color: var(--ink);
    text-decoration: none;
    font-weight: 600;
    font-size: clamp(1rem, 4.3vw, 1.1875rem);
    letter-spacing: 0.005em;
    line-height: 1.2;
    transition: opacity 0.2s var(--ease-out-quart);
  }
  .hero-door-email { overflow-wrap: anywhere; }   /* long address wraps on narrow viewports instead of overflowing */
  .hero-door-arrow { font-size: 0.9em; opacity: 0.9; flex-shrink: 0; }
  .hero-door:hover { opacity: 0.85; }
  .hero-door:focus-visible { outline-color: var(--ink); outline-offset: -3px; }   /* inset ink outline reads on the cobalt field; outset would vanish into the cream page */

  .work-item {
    grid-template-columns: 1fr;
    gap: 0.35rem;
  }
}

@media (max-width: 480px) {
  .field--work,
  .field--note,
  .field--cream {
    padding-left: 1.25rem;
    padding-right: 1.25rem;
  }
  .note { font-size: 1.125rem; }
  .portrait { margin-inline: -1.25rem; }
  .lede { white-space: normal; } /* field content < ~440px here: nowrap would clip; middots give clean break points */
}

/* ============================================================
   Motion: choreographed reveals, reduced-motion safe.
   reveal.js toggles .is-visible; CSS owns the transition.
   ============================================================ */
.reveal {
  opacity: 0;
  transform: translateY(18px);
  transition: opacity 0.7s var(--ease-out-expo),
              transform 0.7s var(--ease-out-expo);
}
.reveal.is-visible {
  opacity: 1;
  transform: none;
}

@media (prefers-reduced-motion: reduce) {
  .reveal {
    opacity: 1;
    transform: none;
    transition: none;
  }
  /* contact-link's padding-left nudge is the only spatial hover transition;
     kill it so reduced-motion users get an instant state change, not a slide. */
  .contact-link, .contact-link-text { transition: none; }   /* gate the transform nudge too, not just the anchor's opacity */
  /* Link underline-draw, contact-primary opacity, hero-door opacity: every
     remaining transition degrades to an instant state change. */
  .link, .contact-primary, .hero-door { transition: none; }
}

/* ============================================================
   LEGAL PAGES: Impressum & Datenschutzerklärung.
   Same committed-cobalt identity as the landing page. The sticky band
   carries a section TOC instead of the contact door; the main column
   holds a short cobalt title fold and the numbered legal sections.
   ============================================================ */

/* TOC band: same .field--cobalt base, but the contact block is replaced
   by a navigation list. Vertically centered so the committed cobalt reads
   as deliberate field rather than empty space below a top-pinned list. */
.toc-band {
  justify-content: center;   /* override the contact band's default top flow; distributes the field evenly top and bottom */
}

.toc {
  /* No own sticky: the parent .field--cobalt is already position:sticky
     with min-height:100vh, so the band pins to the viewport while this
     list stays centered inside it. A second sticky here would fight the
     flex centering. */
  display: flex;
  flex-direction: column;
  gap: 0.6rem;
  max-height: 100vh;          /* guard: if a future page has many sections, center without clipping */
  padding: clamp(1rem, 3vw, 2rem) 0;   /* breathing room so a centered TOC never kisses the band's edges */
}

.toc-title {
  font-size: var(--label);
  font-weight: 600;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--ink);
  padding-bottom: 0.6rem;
  border-bottom: 2px solid var(--ink);
  align-self: flex-start;
  margin-bottom: 0.3rem;
}

.toc-list {
  display: flex;
  flex-direction: column;
}

/* Each TOC row mirrors the contact-link affordance: full-width, 44px+
   touch target, rule-line divider, nudge-on-hover. Active section gets
   a hard underscore bar instead of a tint; the bar is structure, not
   a side-stripe accent (DESIGN.md bans side-stripes). */
.toc-link {
  display: grid;
  grid-template-columns: 3rem 1fr;
  gap: 0.5rem;
  align-items: baseline;
  min-height: 44px;
  padding: 0.65rem 0;
  text-decoration: none;
  color: var(--ink);
  border-top: 1px solid var(--rule-on-cobalt);
  position: relative;          /* the active bar hangs off this, not off a border that would shift on hover */
}
.toc-list li:last-child .toc-link { border-bottom: 1px solid var(--rule-on-cobalt); }

.toc-num {
  font-size: var(--label);
  font-weight: 600;
  letter-spacing: 0.12em;
  text-transform: uppercase;
}
.toc-text {
  font-size: var(--body);
  font-weight: 500;
  line-height: 1.3;
  transition: transform 0.18s var(--ease-out-quart);
}
.toc-link:hover .toc-text { transform: translateX(0.3rem); }
.toc-link:focus-visible { outline-color: var(--ink); }

/* Active section: ink bar drawn under the full row via an absolutely
   positioned pseudo-element, so adding it never changes layout. */
.toc-link[aria-current="true"]::after {
  content: "";
  position: absolute;
  left: 0; right: 0; bottom: -1px;
  height: 3px;
  background: var(--ink);
  z-index: 1;                  /* sits above the row's border-top rule */
}
.toc-link[aria-current="true"] .toc-text { font-weight: 700; }

/* ---------- Legal header fold: cobalt title block atop the main column. ---------- */
.legal-header {
  background: var(--cobalt);
  color: var(--ink);
  padding: clamp(2.5rem, 6vw, 4.5rem) clamp(1.5rem, 6vw, 6rem) clamp(2rem, 5vw, 3.5rem);
}

.legal-kicker {
  font-size: var(--label);
  font-weight: 600;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  margin-bottom: 0.85rem;
  /* opacity dropped: 0.8 over cobalt failed WCAG AA (~2.2:1) for small tracked text */
}

.legal-title {
  font-weight: 800;
  font-size: var(--display);
  line-height: 0.9;
  letter-spacing: -0.04em;
  text-wrap: balance;
}

/* ---------- Legal body: numbered sections on cream. ---------- */
.legal-body {
  padding: clamp(3rem, 7vw, 6rem) clamp(1.5rem, 6vw, 6rem) clamp(3rem, 7vw, 5rem);
  display: flex;
  flex-direction: column;
}

.legal-section {
  padding-bottom: clamp(2.5rem, 5vw, 4rem);
  border-bottom: 1px solid var(--rule);
  scroll-margin-top: 1.5rem;   /* smooth-scroll lands the section head clear of the viewport top */
}
.legal-section:last-child { border-bottom: none; padding-bottom: 0; }
.legal-section + .legal-section { padding-top: clamp(2.5rem, 5vw, 4rem); }

.legal-section__head {
  display: grid;
  grid-template-columns: 4.5rem 1fr;
  gap: 1rem;
  align-items: baseline;
  margin-bottom: 1.5rem;
}

.legal-section__num {
  font-size: var(--label);
  font-weight: 600;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--cobalt-link);
}

.legal-section__title {
  font-weight: 700;
  font-size: var(--headline);
  line-height: 1.05;
  letter-spacing: -0.02em;
  color: var(--ink);
  text-wrap: balance;
}

/* Legal prose: tighter than the landing page's marketing body — this is
   reference text meant to be scanned, not sold. */
.legal-section p {
  font-size: var(--body);
  line-height: 1.6;
  max-width: 68ch;
  color: var(--ink);
}
.legal-section p + p { margin-top: 1rem; }
.legal-section strong { font-weight: 700; }
.legal-section ul {
  margin: 0;
  padding-left: 0;
  list-style: none;
  max-width: 68ch;
}
/* ponytail: custom marker keeps the cobalt label rhythm of the section heads */
.legal-list li {
  position: relative;
  padding-left: 1.5rem;
  font-size: var(--body);
  line-height: 1.6;
  color: var(--ink);
}
.legal-list li + li { margin-top: 0.6rem; }
.legal-list li::before {
  content: '—';
  position: absolute;
  left: 0;
  color: var(--cobalt-link);
}
.legal-list em { font-style: italic; }
.legal-section ul + p, .legal-section p + ul { margin-top: 1rem; }}

/* Definition list for the responsible-party / TMG contact block.
   Same label-column rhythm as the work-item grid on the landing page. */
.legal-meta {
  display: grid;
  grid-template-columns: 4.5rem 1fr;
  gap: 0.5rem 1rem;
  margin: 0.5rem 0 1rem;
  max-width: 52ch;
}
.legal-meta dt {
  font-size: var(--label);
  font-weight: 500;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--cobalt-link);
  padding-top: 0.15em;
}
.legal-meta dd {
  font-weight: 400;
  color: var(--ink);
  line-height: 1.5;
}

/* Bulleted lists (rights, server-log items). Square markers read
   brutalist-spec; the default disc reads corporate-stock. */
.legal-list {
  list-style: none;
  margin: 0.75rem 0 1rem;
  max-width: 68ch;
}
.legal-list li {
  position: relative;
  padding-left: 1.4rem;
  line-height: 1.6;
  color: var(--ink);
}
.legal-list li + li { margin-top: 0.3rem; }
.legal-list li::before {
  content: "";
  position: absolute;
  left: 0;
  top: 0.62em;
  width: 0.5rem;
  height: 0.5rem;
  background: var(--cobalt-link);
}

/* Inline links inside legal prose: the band's cobalt-ink override
   (.field--cobalt a) doesn't reach in here, so .link stays cobalt-link. */
.legal-section .link { color: var(--cobalt-link); }

/* ============================================================
   SITE FOOTER: on all three pages. Rule-divided, ink-on-cream,
   name left, links right. No cards, no side-stripes.
   ============================================================ */
.site-footer {
  background: var(--cream);
  border-top: 3px solid var(--cobalt);   /* matches the Babylon Dreams note's cobalt rule on the landing page */
}
.footer-inner {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1.5rem;
  flex-wrap: wrap;
  padding: clamp(2rem, 5vw, 3rem) clamp(1.5rem, 6vw, 6rem);
}
.footer-name {
  font-size: var(--body);
  font-weight: 700;
  letter-spacing: -0.01em;
  color: var(--ink);
}
.footer-links {
  display: flex;
  flex-wrap: wrap;
  gap: clamp(1rem, 3vw, 2rem);
}
.footer-link {
  font-size: var(--label);
  font-weight: 500;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  text-decoration: none;
  color: var(--ink-soft);
  display: inline-flex;     /* 44px touch target (WCAG 2.5.5) — matches .contact-link / .toc-link */
  align-items: center;
  min-height: 44px;
  padding-bottom: 2px;
  border-bottom: 1.5px solid transparent;
  transition: color 0.2s var(--ease-out-quart),
              border-color 0.2s var(--ease-out-quart);
}
.footer-link:hover,
.footer-link:focus-visible { color: var(--cobalt-link); border-bottom-color: var(--cobalt-link); }
.footer-link[aria-current="page"] { color: var(--ink); border-bottom-color: var(--ink); }
.footer-link:focus-visible { outline-color: var(--cobalt-link); outline-offset: 3px; }

/* ============================================================
   LEGAL PAGES — Responsive: TOC band collapses on mobile.
   Sections are short and scannable; a pinned TOC would eat the top
   of a phone screen and fight reading. The footer anchors cover navigation.
   ============================================================ */
@media (max-width: 860px) {
  .toc-band { display: none; }

  .canvas--legal { grid-template-columns: 1fr; }
  .canvas--legal .main-col { grid-row: auto; }

  .legal-header { padding: clamp(2rem, 8vw, 3rem) clamp(1.25rem, 6vw, 2rem); }
  .legal-body { padding: clamp(2.5rem, 8vw, 4rem) clamp(1.25rem, 6vw, 2rem) clamp(2.5rem, 6vw, 4rem); }

  .legal-section__head {
    grid-template-columns: 1fr;
    gap: 0.3rem;
    margin-bottom: 1.25rem;
  }
  .legal-meta { grid-template-columns: 1fr; gap: 0.15rem 0; }
  .legal-meta dt { padding-top: 0.6rem; }
}

@media (max-width: 480px) {
  .footer-inner { flex-direction: column; align-items: flex-start; gap: 1rem; }
}

@media (prefers-reduced-motion: reduce) {
  .toc-text { transition: none; }
  .toc-link:hover .toc-text { transform: none; }
}

/* ============================================================
   Visually-hidden — accessible heading/label for screen + heading nav,
   removed from the visual layout. (Brutalist restraint: the cobalt rule
   already separates the Babylon Dreams note visually, so its heading
   stays sight-hidden but still reaches heading-nav users.)
   ============================================================ */
.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;
}

/* ============================================================
   Print — recruiters save-as-PDF. Sticky band and 100vh folds paginate
   badly; flatten to a single document flow, keep the cobalt block legible
   on paper as a bordered cell, and inline external URLs so printed proof
   links are readable.
   ============================================================ */
@page {
  size: A4;
  margin: 8mm;
}
@media print {
  /* The cobalt field IS the brand — force browsers to print it instead of
     bleaching to white. Free for save-as-PDF (the common recruiter move). */
  *, *::before, *::after {
    print-color-adjust: exact;
    -webkit-print-color-adjust: exact;
  }

  /* One-page compaction: flatten grid, tighten padding + type. */
  .canvas { display: block; }
  .main-col { grid-column: auto; grid-row: auto; }

  .field--cobalt {
    grid-column: auto;
    grid-row: auto;
    position: static;
    min-height: 0;
    padding: 3mm 8mm;
    break-inside: avoid;
  }
  /* The four external links (GitHub, DialysePal, LinkedIn, Blog) resolve to
     nothing on paper — drop the whole row, keep just the email. */
  .contact-links { display: none; }
  .contact-vert { margin-bottom: 0; }
  .contact-primary { font-size: 14pt; }
  .contact-kicker { font-size: 7pt; }

  .field--cream,
  .field--work,
  .field--note {
    min-height: 0;
    padding: 3mm 8mm;
    justify-content: flex-start;
  }
  /* Cream field: name on the left, portrait top-right beside it. */
  .field--cream {
    display: flex;
    flex-direction: row;
    gap: 4mm;
    align-items: flex-start;
  }
  .field--cream .hero { flex: 1; min-width: 0; }

  .display { font-size: 24pt; line-height: 0.95; margin-bottom: 0; }
  .verdict { font-size: 11pt; margin-bottom: 0; }
  .lede { font-size: 8pt; }

  /* Hero CTA is redundant with the contact band up top on paper. */
  .hero-door { display: none; }

  /* Portrait: thumbnail top-right next to the name. */
  .portrait {
    position: static;
    width: 22mm;
    padding: 0;
    margin: 0;
    break-inside: avoid;
  }

  .headline { font-size: 11pt; margin-bottom: 2mm; }
  .work-list { gap: 2mm; }
  .work-tag { font-size: 7pt; }
  .work-proof, .work-prose { font-size: 8pt; line-height: 1.25; }

  .rule--cobalt { margin: 2mm 0; }
  .note, .closer { font-size: 8pt; line-height: 1.3; }

  /* ---- Legal pages (Impressum / Datenschutz) ----
     Same lessons: flatten the two-col grid to a single flow, compact the
     clamp() paddings (up to 6rem on screen), scale type to pt. Legal docs
     are genuinely long — these don't target one page, just clean print. */
  .toc-band {
    position: static;
    min-height: 0;
    height: auto;
    padding: 3mm 8mm;
    break-inside: avoid;
  }
  .toc { max-height: none; gap: 1mm; }
  .toc-title { font-size: 7pt; margin-bottom: 1mm; }
  .toc-link { padding: 0.8mm 0; font-size: 8pt; }
  .toc-num { font-size: 7pt; }

  /* Cobalt title band: compact the 4.5rem screen padding. */
  .legal-header { padding: 4mm 8mm; break-inside: avoid; }
  .legal-kicker { font-size: 7pt; margin-bottom: 1mm; }
  .legal-title { font-size: 18pt; line-height: 0.9; }

  .legal-body { padding: 4mm 8mm; }

  .legal-section {
    padding-bottom: 3mm;
    border-bottom: 1px solid #999;
    break-inside: avoid;
  }
  .legal-section + .legal-section { padding-top: 3mm; }

  .legal-section__head {
    grid-template-columns: 14mm 1fr;
    gap: 2mm;
    margin-bottom: 2mm;
  }
  .legal-section__num { font-size: 8pt; }
  .legal-section__title { font-size: 11pt; }

  .legal-section p { font-size: 8pt; line-height: 1.3; }
  .legal-section p + p { margin-top: 1.5mm; }

  .legal-meta { gap: 0.5mm 4mm; }
  .legal-meta dt { font-size: 7pt; }
  .legal-meta dd { font-size: 8pt; }

  .legal-list { padding-left: 4mm; }
  .legal-list li { font-size: 8pt; line-height: 1.3; }
  .legal-list li + li { margin-top: 1mm; }

  /* Entrance reveals: force visible. */
  .reveal { opacity: 1 !important; transform: none !important; transition: none !important; }

  /* Print external proof destinations next to their links so a paper/PDF
     copy stays verifiable. */
  .main-col .link[href^="http"]::after {
    content: " (" attr(href) ")";
    font-size: 0.85em;
    color: #444;
    text-decoration: none;
  }

  .site-footer {
    break-inside: avoid;
    border-top: 1px solid #999;
    padding: 3mm 8mm 0;
  }
  .footer-link { min-height: 0; font-size: 8pt; }
}
