/* sandrodegen.swiss — quiet, typographically led, warm neutral.
   Palette derived from the portrait backdrop #8C837E. */

:root {
  color-scheme: light;

  --paper:     #F7F5F2;
  --paper-alt: #EFEBE6;
  --ink:       #24211F;
  /* On --paper-alt this is 4.74:1 — AA with almost no headroom.
     Do not lighten it; anything paler fails the hero role line. */
  --ink-soft:  #6E6660;
  --rule:      #DFD8D1;
  --backdrop:  #8C837E;

  --serif: ui-serif, "Iowan Old Style", "Palatino Linotype", Palatino, Georgia, "Times New Roman", serif;
  --sans: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;

  /* Type ramp — one constant ratio of 1.2 (6:5), anchored at --text-base.
     390px is the reference viewport: that is where each fluid step evaluates
     to its own rung. The ratio is not a convention, it is the largest one this
     page survives — at 1.25 the claim reaches 25px at 390px and breaks
     "Technologieentscheidungen vor." onto a third line, the defect S2-11
     removed. Never insert a value between two steps: a rung that exists in one
     place only is how the previous nine sizes came about. */
  --text-meta:    0.8333rem;  /* 13.33px — labels, dates, secondary lines */
  --text-base:    1rem;       /* 16.00px — running text */
  --text-heading: 1.2rem;     /* 19.20px — entry headings */

  /* Each fluid step's vw coefficient is derived from the rung it must hit at
     390px (23.04/3.9 and 33.18/3.9), so the fluid term is actually engaged
     there instead of resting on a bound. The bounds are rungs of the same
     ladder (1.2^3 and 1.2^6), and --text-lead's ceiling is --text-display's
     floor, so the two can never cross. --text-display sits two rungs above
     --text-lead, not one: a single step would put the name within 4px of the
     claim and read as a mistake rather than a hierarchy. */
  --text-lead:    clamp(1.125rem, 5.908vw, 1.728rem);  /* 18.00 · 23.04 · 27.65 */
  --text-display: clamp(1.728rem, 8.507vw, 2.986rem);  /* 27.65 · 33.18 · 47.78 */

  --measure: 34rem;
  --page: 62rem;
  --gutter: 1.5rem;
}

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

html {
  -webkit-text-size-adjust: 100%;
  scroll-behavior: auto;
}

body {
  margin: 0;
  background: var(--paper);
  color: var(--ink);
  font-family: var(--sans);
  font-size: var(--text-base);
  line-height: 1.6;
  overflow-wrap: anywhere;
}

h1, h2, h3 { font-weight: 600; margin: 0; }
p, ul { margin: 0; }
ul { padding: 0; list-style: none; }

/* Emphasis budget: one verifiable number that evidences order of magnitude
   or tempo, four page-wide, hero excluded — it already carries its own
   typographic levels (S2-11). Weight only, nothing else: body text is sans
   at 400, so 600 is the contrast. */
strong { font-weight: 600; }

a { color: inherit; }

/* Must outrank the display declarations below, or the JS-only mail row
   stays visible as an empty label when JavaScript does not run. */
[hidden] { display: none !important; }

.link {
  color: var(--ink);
  text-decoration: underline;
  text-decoration-color: var(--backdrop);
  text-underline-offset: 0.22em;
  text-decoration-thickness: 1px;
}

.link:hover,
.link:focus-visible { text-decoration-color: var(--ink); }

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

/* ---------- Hero ---------- */

.hero {
  background: var(--paper-alt);
  border-bottom: 1px solid var(--rule);
  padding: 1.5rem var(--gutter);
}

.hero__inner {
  max-width: var(--page);
  margin: 0 auto;
}

.hero__figure { display: block; }

.hero__portrait {
  display: block;
  width: min(9rem, 38vw);
  height: auto;
  background: var(--backdrop);
}

.hero__text { margin-top: 1.375rem; }

.hero__eyebrow {
  font-size: var(--text-meta);
  line-height: 1;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--ink-soft);
  margin-bottom: 0.5rem;
}

.hero__name {
  font-family: var(--serif);
  font-size: var(--text-display);
  line-height: 1.08;
  letter-spacing: -0.015em;
}

/* --- Hero claim and proof (S2-11, sized by the ramp in S2-08) ---
   The local literals that stood here until the ramp existed are gone. The
   claim takes --text-lead and the proof --text-base, so the hero adds no rung
   of its own: the two levels are told apart by family and colour, not by a
   size that exists nowhere else on the page. */

/* Hyphenation stays off across the whole hero: the previous .hero__lead used
   hyphens:auto and produced two-letter remnants (S2-10). overflow-wrap:normal
   overrides the body-level `anywhere` so no German compound is ever broken
   mid-word without a hyphen; the claim is sized to fit "Technologie-
   entscheidungen" on one line down to a 320px viewport. */
.hero__claim,
.hero__proof {
  hyphens: manual;
  overflow-wrap: normal;
}

/* "Länder-CTOs" carries a real hyphen, and a real hyphen is a line-break
   opportunity: at 390px the proof broke it into "Länder-" / "CTOs" and left a
   four-character line. Held together here rather than with a non-breaking
   hyphen character, which would risk a missing glyph on non-Apple systems. */
.hero__nobr { white-space: nowrap; }

.hero__claim {
  font-family: var(--serif);
  /* --text-lead carries the 1.125rem floor that keeps "Technologie-
     entscheidungen vor." on one line at 320px, and a ceiling that keeps it on
     one line in the narrow 896–930px column too. Both are stated once, in
     :root, so this rule needs no size of its own. Verified by render. */
  font-size: var(--text-lead);
  line-height: 1.25;
  letter-spacing: -0.01em;
  margin-top: 0.875rem;
  text-wrap: balance;
}

/* Separated from the claim by colour and family, not by a near-identical
   size, so it does not add a rung to the ramp. */
.hero__proof {
  font-size: var(--text-base);
  line-height: 1.55;
  margin-top: 0.75rem;
  text-wrap: pretty;
}

.hero__role {
  font-size: var(--text-meta);
  line-height: 1.5;
  color: var(--ink-soft);
  max-width: var(--measure);
  margin-top: 1rem;
}

.hero__actions {
  display: flex;
  flex-wrap: wrap;
  gap: 1.5rem;
  margin-top: 1.375rem;
  /* --text-base, not --text-meta, and not for typographic reasons: the tap
     target here is line box plus 0.6875rem of padding either side. At the meta
     rung that comes to ~43px and drops under the 44px minimum; at the base
     rung it measures 47.6px. */
  font-size: var(--text-base);
}

.hero__actions .link {
  display: inline-block;
  padding: 0.6875rem 0;
}

@media (min-width: 56rem) {
  .hero { padding: 5rem var(--gutter) 4.5rem; }

  .hero__inner {
    display: grid;
    grid-template-columns: 22rem 1fr;
    gap: 4rem;
    align-items: center;
  }

  .hero__portrait { width: 22rem; }
  .hero__text { margin-top: 0; }
  /* 28ch, not the 20ch the old four-line lead used: at 20ch the claim breaks
     after "Technologieentscheidungen" and orphans "vor." onto a third line.
     No size override any more. Entering this breakpoint makes the text column
     *narrower* (432px at a 896px viewport, because the 22rem portrait and the
     4rem gap come out of it), which used to orphan "vor." in the 896–930px
     band because the old clamp was already at its 2rem ceiling. --text-lead
     tops out at 1.728rem instead, which clears the narrowest column on its
     own — so the ramp replaces the override rather than fighting it. */
  .hero__claim {
    max-width: 28ch;
    margin-top: 1.25rem;
  }

  /* The text column runs to 36rem here, far wider than the mobile container,
     so the proof needs a measure of its own. Mobile sets none: there the
     container is already the measure. */
  .hero__proof { margin-top: 1rem; max-width: 38ch; }

  .hero__role { margin-top: 1.75rem; }
  .hero__actions { margin-top: 2rem; }
  .hero__actions .link { padding: 0; }
}

/* ---------- Sections ---------- */

.section {
  max-width: var(--page);
  margin: 0 auto;
  padding: 3.25rem var(--gutter);
  border-bottom: 1px solid var(--rule);
}

.section--contact { border-bottom: 0; }

/* This label used to be smaller *and* paler than the .entry__role it heads —
   0.9375rem in --ink-soft over a 1.1875rem --ink heading. It stays nominally
   smaller than the role (16px against 19.2px) because the 12rem desktop label
   column caps it: "Schwerpunkte" measures 177px at --text-base and would need
   ~211px at --text-heading, wrapping to two lines. The rank is restored
   optically and by contrast instead. All-caps in this serif stands at a cap
   height of ~0.70em = 11.2px, while the role's mixed-case word shapes are
   carried by lowercase at ~0.45em = 8.6px, so the label's letterforms are the
   taller ones; 0.16em of tracking adds the width. --ink rather than --ink-soft
   takes it from 5.17:1 to 14.70:1 on --paper, level with the role. */
.section__title {
  font-family: var(--serif);
  font-size: var(--text-base);
  font-weight: 600;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--ink);
  margin-bottom: 1.75rem;
}

@media (min-width: 56rem) {
  .section {
    display: grid;
    grid-template-columns: 12rem 1fr;
    gap: 4rem;
    padding: 4.5rem var(--gutter);
  }

  .section__title { margin-bottom: 0; padding-top: 0.4rem; }
}

/* ---------- Prose ---------- */

.prose {
  max-width: var(--measure);
  font-size: var(--text-base);
  line-height: 1.7;
}

/* Collapsing the old 1.0625rem onto the base rung rewraps the Profil text and
   left "Länder." alone on a 54px last line. Same remedy as .hero__proof, but
   note it only softens: measured, the last line goes 54px -> 90px ("acht
   Länder."), still shorter than the 234px the old 1.0625rem happened to give.
   pretty balances the last few lines, it does not guarantee a full one. */
.prose p { text-wrap: pretty; }

.prose p + p { margin-top: 1.125rem; }

/* ---------- Entries (Werdegang, Engagement) ---------- */

.entries > .entry + .entry {
  margin-top: 2.5rem;
  padding-top: 2.5rem;
  border-top: 1px solid var(--rule);
}

.entry__role {
  font-family: var(--serif);
  font-size: var(--text-heading);
  line-height: 1.3;
}

.entry__period {
  font-size: var(--text-meta);
  letter-spacing: 0.06em;
  color: var(--ink-soft);
  margin-top: 0.25rem;
}

/* text-wrap: pretty for the same reason as .prose p — dropping 0.9375rem onto
   the meta rung left "Steering" alone on a 52px last line. Measured effect is
   again partial: 52px -> 65px ("& Steering"), two lines either way. The one
   that clearly benefits is the KPMG row, 60px -> 84px. */
.entry__org {
  font-size: var(--text-meta);
  color: var(--ink-soft);
  margin-top: 0.375rem;
  text-wrap: pretty;
}

.entry__text {
  max-width: var(--measure);
  margin-top: 0.875rem;
  line-height: 1.65;
}

.points {
  max-width: var(--measure);
  margin-top: 1rem;
}

.points > li {
  position: relative;
  padding-left: 1.125rem;
  line-height: 1.6;
}

.points > li + li { margin-top: 0.5rem; }

.points > li::before {
  content: "";
  position: absolute;
  left: 0;
  top: 0.7em;
  width: 0.375rem;
  height: 1px;
  background: var(--backdrop);
}

.points--plain > li { padding-left: 0; }
.points--plain > li::before { content: none; }

/* ---------- Key / value rows (Ausbildung, Schwerpunkte, Kontakt) ---------- */

/* :not([hidden]) so the JS-only mail row leaves no orphan rule behind it. */
.rows > .row:not([hidden]) + .row {
  margin-top: 1.25rem;
  padding-top: 1.25rem;
  border-top: 1px solid var(--rule);
}

.row {
  display: grid;
  gap: 0.25rem;
}

.row__key { font-weight: 600; }

.row__val {
  color: var(--ink-soft);
  max-width: var(--measure);
}

@media (min-width: 40rem) {
  .row {
    grid-template-columns: 18rem 1fr;
    gap: 2rem;
    align-items: baseline;
  }
}

.rows--contact .row__val { color: var(--ink); }

/* ---------- Footer ---------- */

.footer {
  max-width: var(--page);
  margin: 0 auto;
  padding: 2.5rem var(--gutter) 3.5rem;
  border-top: 1px solid var(--rule);
  font-size: var(--text-meta);
  color: var(--ink-soft);
}

.footer__owner { color: var(--ink); }

.footer__note {
  max-width: var(--measure);
  margin-top: 0.5rem;
}

/* ---------- Print ---------- */

@media print {
  :root { --paper: #fff; --paper-alt: #fff; --ink: #000; --ink-soft: #333; --rule: #bbb; }

  html { font-size: 10.5pt; }
  body { line-height: 1.45; }

  .hero {
    border-bottom: 1px solid var(--rule);
    padding: 0 0 1.25rem;
  }

  .hero__portrait { width: 5rem; }
  .hero__actions { display: none; }

  .section,
  .footer { padding-left: 0; padding-right: 0; }

  .section { padding-top: 1.25rem; padding-bottom: 1.25rem; }

  .entry,
  .row { break-inside: avoid; }

  .section { break-inside: auto; }

  .link { text-decoration: none; }

  /* Keep this URL in sync with the footer LinkedIn link in index.html —
     there is no build step, so nothing checks it for you. */
  .footer__note .link::after { content: " (linkedin.com/in/sandro-degen)"; }
}
