/* ══════════════════════════════════════════════════════════════
   sales_essentially - the simplicity rebuild
   Written 03.09.2026 from salesessentially-website_Brief_v1.md

   This file is the whole site. styles.css is the OLD stylesheet and
   is still referenced by the legacy /de/ twins, so it stays on disk
   and is not touched. Nothing here depends on it.

   The rule the brief sets, and the rule this file follows: when two
   options are both defensible, take the one with fewer parts.

   There are exactly two animations in here:
     1. the entry sequence          (§ ENTRY)
     2. the three messages on /why  (§ MESSAGES)
   Both are armed from JS and both scope every moving rule under the
   armed class, so no-JS and prefers-reduced-motion land on the
   finished, static page with nothing to reset.
   ══════════════════════════════════════════════════════════════ */

:root {
  /* The tokens that survive the rebuild. Teal and the greys only. */
  --teal:        #117b7a;
  --teal-bright: #19a3a2;
  --teal-light:  #e8f4f4;
  --teal-bg:     #f4fafa;
  --teal-dark:   #0d5f5e;

  /* Present, unused, and staying that way. */
  --green:       #117b45;
  --purple:      #45117b;
  --magenta:     #7a117b;

  --text:        #1a1a1a;
  --text-body:   #333333;
  --text-muted:  #666666;

  --bg:          #ffffff;
  --bg-alt:      #f8fafa;
  --border:      #e2ecec;

  --radius-sm:   10px;
  --radius-md:   14px;
  --radius-lg:   20px;
  --radius-xl:   28px;

  /* The gradient. One declaration, used by the entry page and by the
     first screen of /why, which the brief says share a treatment. */
  --grad: linear-gradient(158deg, var(--teal-dark) 0%, var(--teal) 46%, var(--teal-bright) 100%);

  /* Layout. These two numbers are a deliberate port of zen360.consulting,
     which Lorenz gave as the reference on 03.09.2026 ("exactly like that").
     Read off their live stylesheet, not guessed:

       .container { width:100%; max-width:1440px; margin-inline:auto;
                    padding-inline: clamp(1.25rem, 4vw, 2.5rem) }
       html { font-size: 17.5px }   * { box-sizing: border-box }

     Their rem gutter resolves to clamp(21.9px, 4vw, 43.75px); ours is set in
     px so it matches in absolute terms at our 17px root rather than drifting
     with it. The 1440 cap INCLUDES the gutter, because border-box.

     It went 1120 (too narrow, the wordmark sat ~456px inside a 1920 window
     and read as a centred document) then uncapped (too wide) before landing
     here. Do not change it without a new reference: the number is not taste,
     it is a measurement.

     Consequence worth knowing: on a ~1520px window this reads as edge to
     edge, which is what Lorenz is looking at. On a 1920 screen the wordmark
     sits ~284px in and the page is visibly centred. That is what zen360 does
     too, and it is the behaviour that was asked for. */
  /* One sentence, alone on a screen. Read by the entry page's sentence,
     the wordmark that sentence morphs into, and the /why headline - which
     the brief says shares the entry page's treatment and, until
     04.09.2026, did not: it was 68px at weight 600 against the entry
     page's 44px at weight 300.

     ⚠️ The entry sentence and the flying wordmark MUST stay the same
     size or the morph becomes a visible zoom. That is why this is one
     token and not three numbers. */
  --statement: clamp(1.25rem, 3.4vw, 2.6rem);

  --wrap:   1440px;
  --gutter: clamp(22px, 4vw, 44px);
  --band:   clamp(64px, 9vw, 128px);
}

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

html {
  font-size: 17px;
  -webkit-text-size-adjust: 100%;
  /* Reserve the scrollbar's width whether or not the page scrolls, so a
     short page and a long one put the wordmark in the same place. Without
     it a page that fits the viewport sits 15px wider than one that does
     not, and the logo shifts on every navigation between the two. */
  scrollbar-gutter: stable;
}

body {
  font-family: 'Open Sans', -apple-system, BlinkMacSystemFont, sans-serif;
  font-size: 1rem;
  line-height: 1.65;
  color: var(--text-body);
  background: var(--bg);
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  overflow-x: hidden;
}

img, svg, video { display: block; max-width: 100%; }
a { color: inherit; }

:focus-visible {
  outline: 2px solid var(--teal);
  outline-offset: 3px;
  border-radius: 3px;
}
.on-teal :focus-visible { outline-color: #ffffff; }

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

/* ── The wordmark ──────────────────────────────────────────────
   One element, used at three sizes: the header, the entry sentence
   (where it is the thing the word `sales` becomes), and the guide
   cover. It is real text next to an inline SVG mark, NOT an image,
   which is what makes the entry morph possible without a path
   asset. The mark takes currentColor so it inverts on the gradient.

   Everything inside is sized in `em`, so the whole lockup scales by
   changing one font-size. The entry travel relies on that: it scales
   the flying copy by the ratio of the two elements' widths, and that
   ratio is only exact because the proportions are identical. */
.wm {
  display: inline-block;
  white-space: nowrap;
  font-weight: 700;
  letter-spacing: -0.015em;
  line-height: 1.1;
  color: var(--teal);
  text-decoration: none;
}
.on-teal .wm { color: #ffffff; }
/* Generic, so any section that goes on teal gets readable headings
   rather than each one re-declaring it. */
.on-teal .h1,
.on-teal .h2 { color: #ffffff; }
.wm-mark {
  display: inline-block;
  width: 1.5em; height: 1.5em;
  vertical-align: -0.42em;
  margin-right: 0.2em;
}
.wm-text { display: inline; }

/* ══════════════════════════════════════════════════════════════
   § ENTRY - the entry page, index.html
   height:100dvh, no scroll, no nav. The only page on the site that
   behaves this way.
   ══════════════════════════════════════════════════════════════ */

/* ⚠️ The entry page opts OUT of the reserved scrollbar gutter, and must.
   It cannot scroll, so there is no scrollbar to reserve for, and the
   reservation is not paintable: .entry is a block inside body, so it stopped
   at 1905 of a 1920 window and left a 15px strip of white canvas down the
   right of the gradient. Measured, not assumed.

   The cost is that the wordmark sits ~7px further right here than in the
   header of a scrolling page. That is the smaller of the two faults, and it
   is the one nobody can see. */
.entry-html { scrollbar-gutter: auto; }
.entry-html, .entry-html body { height: 100%; overflow: hidden; }

.entry {
  position: relative;
  height: 100dvh;
  min-height: 100svh;
  overflow: hidden;
  display: flex;
  flex-direction: column;
  background: var(--grad);
  color: #ffffff;
  padding-block: var(--gutter);
}

/* ⚠️ The entry page reads the container too, and it has to.
   The brief's whole reason for the shared resting position is that moving
   from here into any page should feel like the same page. If .entry kept a
   flat gutter while every other page capped at 1440, the wordmark would jump
   233px sideways on a 1920 screen the moment a door was clicked. Measured
   before this rule existed: entry 44px, /why 277px.

   .entry-mid centring inside 1440 lands in the same place as centring inside
   the viewport, so the sentence and the doors do not move. */
.entry-top,
.entry-mid,
.entry-foot {
  width: 100%;
  max-width: var(--wrap);
  margin-inline: auto;
  padding-inline: var(--gutter);
}

.entry-top   { flex: none; }
.entry-top .wm { font-size: clamp(1rem, 1.15vw, 1.18rem); }

/* ⚠️ Two ROWS since 08.09.2026, and it used to be one cell.
   `.entry-line` and `.entry-doors` both sat in `grid-area: 1 / 1`, stacked
   on top of each other, which was safe only because they never coexisted:
   the sentence was gone before the doors arrived. The sentence is permanent
   now, so they are a column - sentence, gap, doors - and the gap is the
   only thing separating the statement from the ask.

   `align-content` centres the PAIR in the free height; the items are left
   to stretch, because `.entry-line` centres its own text and `.entry-doors`
   centres its own pills. Do not put `place-items: center` back: with
   `width: 100%` on the doors it makes the column width resolve against
   itself. */
.entry-mid {
  flex: 1 1 auto;
  display: grid;
  align-content: center;
  gap: clamp(34px, 5vw, 68px);
  min-height: 0;
}

/* ⚠️ PRESENT on the finished page since 08.09.2026, and it used to be
   `display: none` outside the sequence. The sentence was spent by the
   animation - the words around `sales` faded out, `sales` flew away, and
   nothing was left - so no-JS and reduced-motion visitors never saw it at
   all. It stays now, above the doors, which is why it is the page's `<h1>`
   and no longer aria-hidden. The armed state only takes its opacity to 0
   and brings it back; the finished state is still the default. */
/* Softened 03.09.2026 on Lorenz's note: it was 4rem at weight 600 with
   -0.025em tracking, which is a shouted statement rather than a spoken one.
   Three things carry the change together, and it is the combination that
   does it, not the size alone: down to 2.6rem, down to weight 300 (Open Sans
   Light, self-hosted, so no new file), and the negative tracking off. Tight
   tracking is a display-type device; at this size it just looked clenched.

   Weight 300 is the reason it can be this small and still hold the screen
   on its own. Do not put the weight back up to "fix" legibility - take the
   size up instead, or it reads as on-the-nose again. */
.entry-line {
  font-size: var(--statement);
  font-weight: 300;
  line-height: 1.12;
  letter-spacing: 0;
  text-align: center;
  text-wrap: balance;
  /* No measure cap. Widening this is fine; capping it is not.
     ⚠️ It is no longer one line on desktop, and that changed with the
     sentence on 08.09.2026. Measured: ONE line at 1920 and 1440 (1258px in
     a 1352px column, so it only just holds), TWO from 1024 down. The old
     five-word sentence held one line to 600. Nothing depends on the count -
     the flying copy measures the word's own rectangle, so it lifts off
     correctly from either line - but do not read "one line on desktop" as
     still true. */
  max-width: none;
}

/* The flying COPY. Absolutely positioned, placed by JS directly over the
   word `sales`, then travelled to the resting wordmark's measured position.
   It is aria-hidden: the real wordmark in .entry-top carries the text for
   assistive tech, and the sentence underneath is the h1.

   ⚠️ It stopped being a hand-off on 08.09.2026. The sentence's `sales`
   used to fade OUT as this faded IN - one word becoming the other. The
   sentence is permanent now, so this lifts off the word and the original
   is still there when it has gone. */
.wm-fly {
  display: none;
  position: absolute;
  left: 0; top: 0;
  transform-origin: left top;
  /* Same token as .entry-line, deliberately. The weight is NOT shared: this
     one stays at .wm's 700, because it is the logo. The word thickening as
     it cross-fades is the transformation, and now that the sentence is
     weight 300 that change is the whole point of the moment. */
  font-size: var(--statement);
  color: #ffffff;
  will-change: transform, opacity;
  pointer-events: none;
}

.entry-doors {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 14px;
  width: 100%;
}
.door {
  display: inline-block;
  padding: 15px 26px;
  background: #ffffff;
  color: var(--teal-dark);
  font-weight: 600;
  font-size: clamp(0.95rem, 1.1vw, 1.06rem);
  text-decoration: none;
  border-radius: 999px;
  transition: background 180ms ease, color 180ms ease;
}
.door:hover { background: var(--teal-light); }

.entry-foot {
  flex: none;
  text-align: center;
  font-size: 0.8rem;
  color: var(--teal-light);
  opacity: 0.7;
}
.entry-foot a { text-decoration: none; }
.entry-foot a:hover { text-decoration: underline; }
.entry-foot .sep { margin: 0 0.55em; }

/* ── The sequence ──────────────────────────────────────────────
   Every rule below is scoped under html.ea, which JS adds only when
   it is actually going to run the sequence. Removing that one class
   is therefore a complete, instant skip: there are no transitions
   left to animate the snap, and nothing to reset. That is the whole
   skip implementation.

   Default state, with .ea absent, IS the end state: sentence gone,
   wordmark top left, doors and legal line visible. So no-JS,
   reduced motion and a second load in the same session all render a
   finished page on first paint. */
/* The sentence takes 1400ms to arrive. It was 600ms and read as a cut
   rather than a fade: it is the first thing on the site and the only thing
   on the screen, so it has to look like it is settling into place, not
   switching on. ease-in-out because a slow fade wants a soft start AND a
   soft finish; `ease` front-loads and undoes most of the extra duration.

   It lands at 1.7s and holds for 0.9s before step 3 takes the other words
   away. That hold is the point of slowing it down, so if this duration goes
   up again, move step 2 (2600ms) out with it rather than eating the hold. */
html.ea .entry-line { opacity: 0; transition: opacity 1400ms cubic-bezier(0.4, 0, 0.6, 1); }
html.ea.e1 .entry-line { opacity: 1; }

/* ⚠️ NOTHING IN THE SENTENCE MOVES, and two rules were deleted here on
   08.09.2026 to make that true:

     html.ea.e2 .e-rest  { opacity: 0 }   the words either side, 900ms
     html.ea.e3 .e-sales { opacity: 0 }   the word itself, cross-fading out

   The first took the sentence apart so `sales` was left alone on screen;
   the second handed that word over to the wordmark. Both are gone. `.e2`
   does not exist any more - JS never adds it - and `.e-rest` has no rule at
   all, it only names the two halves for the split.

   What was lost with them: the beat where the visitor watched the other
   words leave and worked out that `sales` was being KEPT. The transformation
   is now carried entirely by the copy lifting off. */

/* ⚠️ The copy fades in ON the word, and the travel starts only when that
   fade is done. That is safe ONLY because place() centres the copy on the
   word rather than aligning it left: the copy is weight 700 against the
   sentence's 300, so its `sales` is 8.2% wider (8.1px at 1440, measured),
   and left aligned the overlap rendered as `salkes` - the light word's last
   letter falling past the bold one. Screenshotted, not guessed.

   Centred, the bold envelope contains the light word and the frame reads as
   the word thickening. That frame is the point: the copy is seen ON the word
   before it goes, which is what makes it a copy of THAT word. Undo the
   centring and these two beats have to be merged back into one. */
html.ea .wm-fly {
  display: inline-block;
  opacity: 0;
  transition: opacity 350ms ease,
              transform 1200ms cubic-bezier(0.22, 0.61, 0.36, 1);
}
html.ea.e3 .wm-fly { opacity: 1; }

/* The mark and the tail hold the space from the start, so revealing them
   cannot reflow anything.

   ⚠️ The 200ms delay became 650ms on 08.09.2026 so they assemble IN FLIGHT,
   and that is a collision fix, not a rhythm one. They unfold to the RIGHT of
   `sales`, which used to be empty gradient because the rest of the sentence
   had already faded out. The sentence stays now, so ` strategy, you can
   double...` is sitting in exactly that space: unfolding on the spot puts
   `_essentially` straight through live words. Screenshotted; it is mush.

   650ms after `.e3` is 4550 absolute - 300ms into a travel that starts at
   4250, by which point the easing has already carried the copy ~59% of the
   way and it is over open gradient. It finishes at 5250 against a travel
   ending at 5450, so the wordmark is assembled just before it parks. All
   three numbers move together; do not shorten this without checking what is
   to the right of the word at the moment it fires. */
html.ea .wm-fly .wm-mark,
html.ea .wm-tail { opacity: 0; transition: opacity 700ms ease 650ms; }
html.ea.e3 .wm-fly .wm-mark,
html.ea.e3 .wm-tail { opacity: 1; }

/* The resting wordmark is the travel target, so it has to be laid out
   and measurable the whole time. Hidden with opacity, never display. */
html.ea .entry-top .wm { opacity: 0; }
html.ea.edone .entry-top .wm { opacity: 1; }
html.ea.edone .wm-fly { opacity: 0; transition: none; }

html.ea .door {
  opacity: 0;
  transform: translateY(12px);
  transition: opacity 480ms ease, transform 480ms ease;
}
html.ea .door:nth-child(2) { transition-delay: 90ms; }
html.ea .door:nth-child(3) { transition-delay: 180ms; }
html.ea.e5 .door { opacity: 1; transform: none; }

html.ea .entry-foot { opacity: 0; transition: opacity 500ms ease; }
html.ea.e6 .entry-foot { opacity: 0.7; }

/* ══════════════════════════════════════════════════════════════
   § SHELL - header, page bands, footer
   ══════════════════════════════════════════════════════════════ */

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

.hdr { padding: clamp(20px, 2.6vw, 34px) 0; }
.hdr-in {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 18px 28px;
  flex-wrap: wrap;
}
.hdr .wm { font-size: clamp(1rem, 1.15vw, 1.18rem); }
.hdr-nav {
  display: flex;
  flex-wrap: wrap;
  gap: 12px 26px;
  font-size: 0.92rem;
}
.hdr-nav a {
  color: var(--text-muted);
  text-decoration: none;
  transition: color 180ms ease;
}
.hdr-nav a:hover { color: var(--teal); }
.on-teal .hdr-nav a { color: rgba(255, 255, 255, 0.82); }
.on-teal .hdr-nav a:hover { color: #ffffff; }

/* On mobile the three links wrap under the wordmark. */
@media (max-width: 640px) {
  .hdr-in { flex-direction: column; align-items: flex-start; }
}

.band { padding-block: var(--band); }
.band-alt { background: var(--bg-alt); }

/* ⚠️ The third band background, added 07.09.2026 for /coaching's three
   principles, which was the only page with no teal anywhere.

   ⚠️ FLAT `--teal-dark`, and NOT `--grad`, on measurement rather than
   taste. The gradient ends at `--teal-bright`, where white body text is
   3.09:1 and fails AA; the entry page and the /why hero only pass there
   because large text needs 3.0, not 4.5. This band carries body copy.
     --teal-dark   7.46:1  white body text
     --teal        5.07:1
     --teal-bright 3.09:1  FAILS
   ⚠️ Always pair it with `.on-teal`, which inverts the type and the
   focus ring. Without that the headings stay near-black on dark teal. */
.band-teal { background: var(--teal-dark); }

.foot {
  padding: 40px 0 52px;
  font-size: 0.82rem;
  color: var(--text-muted);
}
.foot a { text-decoration: none; }
.foot a:hover { text-decoration: underline; }
.foot .sep { margin: 0 0.55em; }

/* ── Contact in the footer, 07.09.2026 ─────────────────────────
   On every scrolling page. ⚠️ NOT on the entry page, which has
   `.entry-foot` and keeps its legal line as the only thing on it that is
   not one of the three doors.

   ⚠️ These are the site's FIRST icons that are filled rather than
   stroked. The rule elsewhere is `stroke="currentColor"`, and it is
   broken here on purpose: a stroked LinkedIn or WhatsApp glyph is not
   the recognisable mark. The envelope is filled to match, so the three
   carry one weight instead of an outline beside two solids.

   ⚠️ This puts a SECOND route to Lorenz on /why and /free, whose one
   action is the guide. Accepted: a footer is the conventional place for
   it and it sits at the quietest point on the page. If those pages ever
   read as asking for two things, this is the thing that arrived second. */
/* ⚠️ The line and the arrow that highlight the contact row, 07.09.2026.
   The row on its own was too quiet to be noticed, which was the point of
   adding it.

   ⚠️ Darker and larger than the rest of the footer on purpose: `.foot`
   sets 0.82rem and `--text-muted`, and this has to break out of that or
   it disappears into the legal line.

   ⚠️ The arrow's stroke is 3.2 in a 70-unit viewBox, which renders at
   about 2px. That is THINNER than the other four drawn objects (~3.5px)
   and it is not an inconsistency: this one is drawn at 44px where they
   are drawn at 262 to 460, so matching their stroke number would make it
   proportionally five times heavier. Match the rendered weight to the
   element's size, never the number to the other objects. */
/* ⚠️ The contact block sits on the RIGHT, the legal line stays bottom
   left. It was all on the left spine for one round and that put the
   footer arrow directly under the CTA arrow, two hand-drawn arrows
   stacked in the same column a few hundred px apart. Lorenz caught it.
   Moving the block right also stops the footer competing with the CTA
   for the same edge.

   Placement is by grid area, so the markup did not have to change and
   the DOM order stays ask, arrow, icons, legal - which is also the order
   a screen reader wants. */
.foot .wrap {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  align-items: end;
}
.foot-ask     { grid-column: 2; grid-row: 1; text-align: right; }
.foot-contact { grid-column: 2; grid-row: 2; }
.foot-legal   { grid-column: 1; grid-row: 2; }

.foot-ask {
  font-size: clamp(0.98rem, 1.1vw, 1.06rem);
  font-weight: 600;
  color: var(--text);
  /* Room for the ring's top overhang, which is 15px of negative inset.
     At the old 2px the line sat inside the circle. */
  margin-bottom: clamp(22px, 2vw, 28px);
}
/* ⚠️ The ring around the icon row, replacing a small drawn arrow that
   pointed at them. Lorenz: "too many arrows, regardless where it is
   placed" - a /free or /coaching screen had three at once. Circling is a
   different gesture from pointing, so it stops competing with the CTA
   arrow above.

   ⚠️ It is the site's FIRST enclosure, on a build whose rule is "space is
   the divider everywhere". The reason it is allowed here and was argued
   down around the /why triangle: that shape already says "these three are
   one system", so a ring restated it, and this row says nothing on its
   own. A loose circle round a few links reads as annotation, not as a box.

   ⚠️ Negative insets, ASYMMETRIC on purpose. Even insets make it look
   like a border; uneven ones make it look drawn. */
/* ⚠️ Explicit width and height, NOT four insets. An <svg> is a replaced
   element, so `width: auto` with left+right set resolves to its intrinsic
   viewBox size instead of stretching between the offsets - the ring
   collapsed to a 20px circle beside LinkedIn the first time. The calc
   values are the insets doubled back in: 20 + 15 across, 15 + 12 down. */
.foot-ring {
  position: absolute;
  left: -20px;
  top: -15px;
  width: calc(100% + 35px);
  height: calc(100% + 27px);
  /* ⚠️ The global reset sets `img, svg, video { max-width: 100% }`, which
     clamped this back to the nav's own width and clipped the right side of
     the ring. It is the only element on the site that has to opt out. */
  max-width: none;
  color: var(--teal);
  pointer-events: none;
  overflow: visible;
}

.foot-contact {
  position: relative;
  display: flex;
  flex-wrap: wrap;
  justify-content: flex-end;
  gap: 0.6em clamp(20px, 2.6vw, 38px);
  margin-bottom: 0;
}
/* Above the ring, so the links stay clickable and legible. */
.foot-contact a { position: relative; }

/* ⚠️ Back to one stacked column on the left below 700px. Right-aligning a
   footer on a phone reads as a mistake, and the reason for the right
   alignment - the CTA arrow above - does not exist down here anyway:
   every CTA arrow is already `display: none` below 1100 to 1180px. */
@media (max-width: 700px) {
  .foot .wrap { display: block; }
  .foot-ask { text-align: left; }
  /* ⚠️ `width: fit-content` matters here. On desktop the nav is a grid item
     in an `auto` column, so it is already content-sized and the ring hugs
     the icons. Switching the wrap to `display: block` made the nav a
     full-width block, and the ring - which is sized from the nav - stretched
     to 665px across a 306px row. Measured at 700px. */
  .foot-contact {
    justify-content: flex-start;
    width: fit-content;
    margin-bottom: clamp(24px, 5vw, 32px);
  }
  /* ⚠️ Tighter insets down here. The row starts at the gutter, which is
     only 22px at 375, so the desktop -20px put the ring 2px off the screen
     edge and it read as clipped. -10px leaves 12px of air. */
  .foot-ring {
    left: -10px;
    width: calc(100% + 22px);
  }
}
.foot-contact a { display: inline-flex; align-items: center; gap: 0.55em; }
/* ⚠️ Scoped to `a svg`, not `.foot-contact svg`. The looser selector was
   more specific than `.foot-ring` and sized the ring to 1.2em - it
   rendered as a 17px circle beside LinkedIn. Any future child of this nav
   would have hit the same rule.

   `em`, so the marks scale with the footer type rather than needing a
   second number when that changes. `flex: none` or a long label squashes
   them at narrow widths. */
.foot-contact a svg { width: 1.2em; height: 1.2em; flex: none; }
.foot-contact a:hover { color: var(--teal); }
.foot-contact a:hover span { text-decoration: underline; }

/* The gradient first screen. /why opens on it, and the brief gives it
   the same treatment as the entry sentence. */
/* ⚠️ Full screen, and it has been both ways. It went to 75dvh on
   04.09.2026 to cut the scrolling, and back the same day: at three
   quarters the neighbouring section's edge shows while this one is
   centred, and the page reads as two half-finished screens rather than
   one clean one. **The height was never the problem** - the type was,
   and that came down separately. Do not trade this away again. */
.grad {
  background: var(--grad);
  color: #ffffff;
  min-height: 100dvh;
  display: flex;
  flex-direction: column;
  padding-bottom: var(--band);
}
.grad-mid {
  flex: 1 1 auto;
  display: grid;
  place-items: center;
  padding-block: var(--band);
  padding-inline: var(--gutter);
}

/* ══════════════════════════════════════════════════════════════
   § TYPE
   ══════════════════════════════════════════════════════════════ */

/* Was 68px at weight 600, which set this page like display advertising
   while everything below it is set like a book. Now it IS the entry
   sentence: same token, same weight, same tracking, so arriving here
   feels like the page you just left. */
.big {
  font-size: var(--statement);
  font-weight: 300;
  line-height: 1.12;
  letter-spacing: 0;
  text-align: center;
  text-wrap: balance;
  max-width: 20ch;
  color: inherit;
}

.h1 {
  font-size: clamp(1.85rem, 4.2vw, 3.1rem);
  font-weight: 700;
  line-height: 1.14;
  letter-spacing: -0.022em;
  color: var(--text);
  max-width: 20ch;
}

.h2 {
  font-size: clamp(1.3rem, 2.3vw, 1.95rem);
  font-weight: 700;
  line-height: 1.22;
  letter-spacing: -0.015em;
  color: var(--text);
  max-width: 28ch;
}

/* The one enlarged block of body copy on the site, per § 3.1. */
/* Nudged down 04.09.2026 with the photos and the heading. Only /why's
   story uses this class. */
.lede {
  font-size: clamp(1.05rem, 1.5vw, 1.32rem);
  line-height: 1.5;
  color: var(--text);
  max-width: 46ch;
}

.p     { max-width: 62ch; }
.p + .p { margin-top: 1.1em; }
.stack > * + * { margin-top: clamp(18px, 2.2vw, 30px); }

/* ══════════════════════════════════════════════════════════════
   § BUTTONS - two of them on the whole site
   .door  white on the gradient (entry page, above)
   .btn   filled teal, everywhere else
   ══════════════════════════════════════════════════════════════ */

.btn-row {
  display: flex;
  flex-wrap: wrap;
  gap: 12px;
}
.btn {
  display: inline-block;
  padding: 13px 28px;
  background: var(--teal);
  color: #ffffff;
  font-weight: 600;
  font-size: 0.97rem;
  line-height: 1.2;
  text-decoration: none;
  border-radius: 999px;
  transition: background 180ms ease;
}
.btn:hover { background: var(--teal-dark); }

/* ══════════════════════════════════════════════════════════════
   § CTA - the block from § 2.2
   Twice on /why, twice on /free, once on /coaching. Identical every
   time: same markup, same copy. A visitor who scrolled past it sees
   the same offer, not a second one.
   ══════════════════════════════════════════════════════════════ */

/* ⚠️ Rebuilt 04.09.2026 as ONE CENTRED COLUMN. It used to be copy left,
   cover right - the story section's shape, given to it deliberately so the
   page would repeat one shape instead of inventing two.

   That reasoning expired. The story grew into a three-beat arc with two
   photographs and a full-width divider, so the CTA's miniature version of
   the same split read as a weak echo rather than a rhyme. It also sat
   1040px wide inside a 1352px container, left-aligned, leaving 312px dead
   on the right: neither flush nor centred, so it floated.

   It went to a single centred column with the cover on top, then to this
   the same day: the two-column split is back, but the BLOCK is centred
   rather than left-aligned, and the cover is 200px rather than 330px.
   That keeps the split without the float and without the old bulk.

   ⚠️ This block is shared by /why, /free and /coaching. The brief wants it
   identical on every page, so changing it here changes it everywhere. That
   is intended. */
.cta-in {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  gap: clamp(28px, 4vw, 56px);
  align-items: center;
  max-width: 780px;
  margin-inline: auto;
  /* ⚠️ The BLOCK is centred, the TEXT inside it is not. That combination
     is deliberate: it means the CTA is the one section whose copy does
     not start on the page's left spine - at 1440 it begins ~330px in,
     where My Story begins at 44px. Lorenz chose it knowingly. */
  text-align: left;
}

.cta-copy > * + * { margin-top: clamp(14px, 1.6vw, 22px); }
.cta-copy .btn-row { margin-top: clamp(22px, 2.6vw, 32px); }

@media (max-width: 640px) {
  /* Copy first. Leading with the cover means opening on a teal rectangle
     before the sentence that explains it. */
  .cta-in { grid-template-columns: minmax(0, 1fr); }
}

/* ⚠️ The CTA was the last section still on the pre-nudge scale, and it
   showed: its paragraph was 17px, the SMALLEST text on the page, in the
   one section meant to convert - while its heading was 32.8px at weight
   700, the heaviest thing on the page, outranking the story heading it
   sits below. Both are scoped so /free and /coaching keep their own
   `.h2` and `.p` sizes elsewhere on those pages. */
.cta-copy .h2 { font-size: clamp(1.22rem, 2.1vw, 1.78rem); max-width: none; }
.cta-copy .p  { font-size: clamp(1.02rem, 1.4vw, 1.22rem); max-width: 46ch; }

/* ══════════════════════════════════════════════════════════════
   § /coaching SECTION 1 - copy left, triangle right
   The same copy-left/object-right rhythm as My Story and the CTA, so
   the page does not invent a third split.

   ⚠️ A drawn growth curve lived in this slot for one round on
   07.09.2026 and was replaced the same day by the triangle, which was
   until then a section of its own further down. Its figures survive in
   the prose. If a drawn curve is ever wanted again, the note that
   matters is that its stroke had to be 0.8 rather than 1.5: the three
   drawn objects sit at different scales, so only the RENDERED weight is
   comparable, and 1.5 measured 6.9px against the arrow's 3.7.
   ══════════════════════════════════════════════════════════════ */

/* Three columns: copy, the arrow, the triangle. The arrow gets a column
   of its own rather than being an absolute overlay like the CTA arrow,
   because here it sits between two things that BOTH reflow - an overlay
   would have to know the copy's rendered text width and would eventually
   land on a word. As a column it cannot collide at any width. */
.coach-hero {
  display: grid;
  grid-template-columns: minmax(0, 1fr) clamp(110px, 13vw, 200px) clamp(280px, 32vw, 460px);
  gap: clamp(24px, 3.4vw, 52px);
  align-items: center;
}
.coach-arrow svg {
  display: block;
  width: 100%;
  height: auto;
  aspect-ratio: 100 / 56;
  color: var(--teal);
  overflow: visible;
}
.coach-copy > * + * { margin-top: clamp(16px, 1.8vw, 26px); }

/* `.method-set` carries a large top margin for its own section on /why,
   where it follows a lead line. Here it IS the column, so that margin
   would only push the triangle off centre against the copy. */
.coach-tri { margin-top: 0; }

/* Copy first, object second - the same rule the story beats follow, so a
   drawing never arrives before the sentence that explains it. */
/* ⚠️ The arrow column costs the copy its measure, and below 1100px that
   cost stops being worth paying. MEASURED at three columns: 67ch at 1440,
   54ch at 1200, 46ch at 1024 and 37ch at 861 - the last two are past
   comfortable for body text. Dropping to two columns here puts 1024 back
   at ~65ch. The arrow is an annotation; the paragraph is the page. */
@media (max-width: 1099px) {
  .coach-hero { grid-template-columns: minmax(0, 1fr) clamp(280px, 32vw, 460px); }
  .coach-arrow { display: none; }
}

@media (max-width: 860px) {
  .coach-hero { grid-template-columns: minmax(0, 1fr); }
  .coach-copy { order: 1; }
  .coach-tri  { order: 2; margin-top: clamp(24px, 5vw, 40px); }
}

/* ══════════════════════════════════════════════════════════════
   § THE THREE PRINCIPLES - /coaching section 3
   Three across, so the second half of that page uses the container
   width instead of stacking three more paragraphs in the same left
   column. That lopsidedness is what Lorenz asked to fix on
   07.09.2026, and the fix is structural, not shorter copy.
   ══════════════════════════════════════════════════════════════ */

/* ⚠️ `.h2` carries `max-width: 28ch`, which is right for a heading over a
   column of prose and wrong for this one - it sits over a three-column
   grid and is a label, not a measure. Lorenz asked for no line break, and
   at 28ch "Coaching & Consulting principles" fit by only 3.8 to 5.7px at
   every width from 600 to 1920. MEASURED. That is not "fits", that is
   "wraps on the first machine whose font metrics differ by one percent",
   and it would have wrapped while Open Sans was still loading.

   Same fix and same reason as `.story-h`, which clears the cap because it
   is centred over the page rather than over the copy column. */
.prin-h { max-width: none; }

.principles {
  list-style: none;
  padding: 0;
  margin: clamp(30px, 3.6vw, 54px) 0 0;
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: clamp(28px, 3.4vw, 56px);
  /* Top-aligned: principle 3 is roughly twice the length of 2, and
     centring would leave the three labels on three different lines. */
  align-items: start;
}

/* ⚠️ `--text-muted`, NOT teal. Teal on this site marks the phrase a
   sentence turns on, plus buttons, links and the two drawn objects. A
   teal numeral would be a fourth use and it would be pure decoration -
   the same reason the /why story heading went back to near-black. One
   line to change if that call is ever revisited.

   `aria-hidden` in the markup: the <ol> already numbers these for a
   screen reader, so reading "01" aloud would say it twice. */
.principle-n {
  display: block;
  font-size: 0.92rem;
  font-weight: 700;
  letter-spacing: 0.08em;
  color: var(--text-muted);
}
.principle-h {
  margin-top: 0.45em;
  font-size: clamp(1.04rem, 1.35vw, 1.2rem);
  font-weight: 700;
  line-height: 1.3;
  letter-spacing: -0.01em;
  color: var(--text);
}
/* Its own measure, on the element carrying the type. The grid column
   caps it at three across; this holds the line at one. */
.principle-p {
  margin-top: 0.5em;
  font-size: 0.97rem;
  line-height: 1.55;
  color: var(--text-body);
  max-width: 40ch;
}

/* Inverted for the teal ground. `--teal-light` rather than white for the
   two smaller elements: it keeps the numeral quieter than its label and
   the paragraph softer than pure white on dark, and still measures
   6.63:1. */
/* ⚠️ No `opacity` here, and that is a correction rather than a
   simplification. At 0.8 the numeral blends to roughly rgb(187,214,214),
   which measures 4.53:1 - technically over AA's 4.5 but close enough that
   any future tweak to the token silently breaks it. At full strength it is
   6.63:1. The hierarchy against the white label is already carried by size
   (15.6px against 19.2px) and by the colour being off-white at all. */
.on-teal .principle-n { color: var(--teal-light); }
.on-teal .principle-h { color: #ffffff; }
.on-teal .principle-p { color: var(--teal-light); }

@media (max-width: 860px) {
  .principles { grid-template-columns: minmax(0, 1fr); gap: clamp(26px, 6vw, 40px); }
}

/* The thesis line under the /coaching h1. `.lede` already sets the size;
   this is only the gap the removed `.stack` wrapper used to make. */
.coach-lede { margin-top: clamp(16px, 1.8vw, 26px); }
.coach-lede + .p { margin-top: clamp(18px, 2.2vw, 30px); }
.coach-lede ~ .p + .p { margin-top: 1.1em; }

/* ── § THE ARROW INTO THE CTA - all four, every page ───────────
   Lorenz's sketch, 07.09.2026. Built on /free first, then applied to every
   CTA on the site the same day: /why x2, /free, /coaching. The second
   drawn arrow on the site; the first is the "me" annotation on the
   Bookboon photo, and this follows its construction exactly - inline SVG
   paths, round caps, sized from its own width so it never shifts layout.

   ⚠️ /why shows it TWICE, once per CTA. That was raised before it was
   applied and Lorenz asked for all of them anyway. If it ever reads as too
   much, /why's first CTA is the one to strip - the second is the page's
   last word.

   ⚠️ It lives in the space to the LEFT of `.cta-in`, which exists only
   because that block is capped at 780px and centred. Available space is
   `50vw - gutter - 390px`: 286px at 1440, 166px at 1200, and gone by
   ~870px. The width formula below spends exactly that space and no more,
   so the arrow can never reach into the gutter or under the copy.

   ⚠️ `right` is measured from the section's CENTRE, not from its edge.
   `.cta-in` is centred, so its left edge is always `50% - 390px` whatever
   the viewport, the wrap cap or the gutter are doing. 414 = 390 + a 24px
   breath before the headline.

   ⚠️ Below 1180px it is DISPLAY:NONE, not shrunk. Under that the space
   left of the copy stops being enough to draw in, and an arrow squeezed
   into 100px reads as a smudge rather than a gesture. There is no mobile
   version of this and there should not be one. */
.cta-band { position: relative; }
.cta-arrow {
  position: absolute;
  right: calc(50% + 414px);

  /* ⚠️ 262 is not a taste number. The wrap's left edge is
     `max(44px, 50vw - 676px)`, and the arrow's is `50vw - 414px - width`.
     Setting width to 262 makes those equal, so the tail starts exactly on
     the page's left spine at EVERY width in this range - 44px at 1180 and
     1440, 284px at 1920 - instead of drifting outside the wrap on a wide
     screen. Change it and the arrow stops lining up with the wordmark.

     ⚠️ Declared once as a custom property because `top` below has to do
     arithmetic on it. Two copies of this expression WILL drift apart. */
  --arrow-w: min(262px, calc(50vw - 458px));
  width: var(--arrow-w);
  aspect-ratio: 100 / 92;
  height: auto;

  /* ⚠️ `top` is derived, not chosen. It was a flat -64px for one round and
     that was wrong: the arrow scales with the viewport but the headline it
     points at is placed by `--band`, so at 1180 the tip floated ~70px above
     the headline while landing on it at 1440. Measured.

     Read it right to left: the tip sits 85% of the way down the box
     (y=85 of a 92-unit viewBox), so subtracting `0.85 * width` puts the
     BOX where the TIP lands on the target. The target is the headline,
     which starts one `--band` into the section, plus 20px to aim at the
     first line rather than its ascender.

     ⚠️ If the viewBox changes, 0.85 changes with it.

     Consequence, accepted: the value goes positive below ~1250px, so the
     tail stops crossing the tint edge and the whole arrow sits inside the
     band. Pointing at the right thing beats crossing the seam.

     Do not put `overflow: hidden` on `.cta-band` or the tail is clipped. */
  top: calc(var(--band) + 20px - 0.85 * var(--arrow-w));
  color: var(--teal);
  pointer-events: none;
  overflow: visible;
}
/* ⚠️ CURRENTLY UNUSED, and kept on purpose. `.cta-first` was written when
   /coaching's CTA was that page's first section; the CTA moved to the
   bottom on 07.09.2026 and nothing carries the class today. It stays
   because the collision it fixes is real, was found by measurement, and
   would have to be rediscovered the next time any page opens on a CTA.
   One rule and a comment, not a dead stylesheet.

   The problem it solves: when the CTA is the FIRST section there is no
   section above for the tail to overhang into - only the header, and at
   full size the tail came out of the wordmark. Measured, not guessed.

   The fix runs through the same formula rather than around it: cap the
   width and `top` resolves to 0 by itself, so the arrow simply stops being
   tall enough to need an overhang. **174 is (128 + 20) / 0.85** - the
   largest arrow whose tip still lands on the headline from a standing
   start, given `--band` maxes at 128. Verified `top` never goes negative
   across the whole range.

   Consequence, accepted: at this size the tail no longer lands on the
   page's left spine (132px in at 1440, not 44). On this page that is the
   better result anyway - it puts clear air between the arrow and the
   wordmark. */
.cta-first .cta-arrow { --arrow-w: min(174px, calc(50vw - 458px)); }

@media (max-width: 1179px) { .cta-arrow { display: none; } }

/* Outline, not solid. Three filled teal pills pointing at one URL was the
   most saturated thing on a very quiet page. `box-shadow: inset` rather
   than `border` so the button does not change size against the solid
   version used for the contact links on /coaching and /guide, which stay
   solid because there they are the only ask on the page. */
.cta-in .btn {
  background: transparent;
  color: var(--teal);
  box-shadow: inset 0 0 0 1.5px var(--teal);
}
.cta-in .btn:hover { background: var(--teal); color: #ffffff; }

/* The guide cover. ⚠️ An IMAGE since 08.09.2026, and it used to be markup.

   The old one was a teal gradient card built from a `<span>` title, a
   `<span>` subtitle and the wordmark - open item 7 in the brief, closed by
   not needing an image at all. It was a placeholder for a guide that did
   not exist yet. The guide exists now, it has a real cover, and a drawn
   approximation of a real cover is worse than the cover.

   ⚠️ What that cost, and what is now gone with it: the whole `em` trick.
   Everything inside the old card was sized in `em` against a font-size of
   exactly width / 20, so the contents scaled with the CARD rather than the
   viewport - the fix for the day the card came down from 330px to 200px
   and the type did not follow. `.cover-mark`, `.cover-title`, `.cover-sub`
   and `.cover-wm` are deleted; nothing else used them. **The title no
   longer changes when the copy changes.** Retitling the guide now means a
   new file, not an edited string.

   The width clamp is unchanged, so the CTA block's layout is untouched.
   No `aspect-ratio` here: the `width` and `height` attributes on the
   `<img>` give the intrinsic ratio, which reserves the space before the
   file lands and is the real ratio rather than a rounded A4.

   ⚠️ The hairline is doing real work, it is not decoration. The cover is
   white at its top and left edges, and /why's two CTAs sit on a plain
   white band - without it the page just stops, with no edge to say the
   object ended. `box-shadow` rather than `border` so it adds no size, the
   same reasoning as `.cta-in .btn` above. It is the site's only enclosure
   apart from the drawn footer ring; if it ever has to go, the alternative
   is not "nothing", it is putting the CTA on a tinted band. */
.cover {
  display: block;
  width: clamp(150px, 14.5vw, 200px);
  height: auto;
  border-radius: var(--radius-lg);
  box-shadow: 0 0 0 1px var(--border);
}

/* No mobile override needed: the block is one centred column at every
   width, and the cover is already small. */

/* ══════════════════════════════════════════════════════════════
   § MESSAGES - /why section 2
   One message at a time, blending into the next, full page width.

   ⚠️ **Four mechanics so far, and this is the current one.**
   Scroll-driven in one position, then a timed crossfade in a narrow
   centred column (03.09.2026), then three columns cascading left to
   right (04.09.2026), then back to the crossfade but spanning the
   container instead of a 34ch column (04.09.2026).

   **The trade, still true:** nothing guarantees a fast scroller sees
   messages 2 and 3. The three-column version could not lose them.
   This one can, and that was accepted for the cadence.

   **The section fills the viewport** so that at rest the message is
   the only thing on screen: no teal from the hero above, no band
   from the CTA below. Dropped below 860px, where three stacked
   fallback paragraphs already exceed the screen.

   Unarmed, the three render as separate stacked paragraphs in order.
   That is the no-JS and reduced-motion state, and it is readable.
   ══════════════════════════════════════════════════════════════ */

.msgs {
  /* Full screen. See the note on .grad: 75dvh was tried and reverted. */
  min-height: 100dvh;
  display: flex;
  flex-direction: column;
  justify-content: center;
}

.msgs-stage { display: grid; gap: clamp(30px, 4.5vw, 60px); }

/* No measure cap and no auto margins: the message runs the full width of
   the container, which is the point. That puts 55 to 70 characters on a
   line at display size, inside the readable band rather than above it,
   because the type scales with the width instead of staying small in a
   wide box.

   Centred (04.09.2026). This is the one place on the site that breaks the
   left spine, and it can afford to because it is alone on the screen with
   nothing to align against.

   `pretty` rather than `balance` on purpose: balance evens the line
   lengths, which pulls the text in from both edges and quietly undoes the
   full width this section was widened for. */
.msg {
  font-size: clamp(1.1rem, 2.45vw, 2.1rem);
  font-weight: 300;
  line-height: 1.35;
  letter-spacing: -0.008em;
  color: var(--text);
  text-align: center;
  /* `balance` here, not `pretty`. Shrinking the type stretches the line to
     85+ characters across the full container, and centred text with one
     long line and one short one looks broken. Balance evens them without
     a hard measure cap, so the block still uses the width instead of
     going back to the narrow centred column this replaced. */
  text-wrap: balance;
}

@media (max-width: 860px) {
  /* Three stacked fallback paragraphs exceed a phone screen, so filling
     the viewport stops meaning anything and only adds dead space. */
  .msgs { min-height: 0; }
}

/* ⚠️ The teal rule changed on 04.09.2026 and the new one is wider.

   It used to be "teal marks simplicity and what it produces", which is
   why message 1 had none: message 1 is the trap, not the way out, and
   colouring `complicated` teal would have marked the antagonist in the
   brand colour. Lorenz asked for message 1 to carry it too, so the rule
   is now **teal marks the phrase the sentence turns on** - one per
   message, except message 3, which turns on three parallel outcomes.

   That is consistent, but it does mean teal no longer means one thing
   on this page. If it ever has to mean one thing again, message 1 is
   the one to strip.

   <em> rather than a class: the emphasis is real, so assistive tech
   should hear it. The italic is turned off because the site has no
   italic anywhere else. */
/* ⚠️ THIS IS AN ALLOWLIST, and that is a footgun. An <em> anywhere not
   named here does not get teal - it gets the browser default, which is
   ITALIC, and the site has no italic anywhere. Caught on /coaching on
   07.09.2026, where `.coach-lede em` rendered as italic black.
   ADD THE SELECTOR WHENEVER YOU ADD A TEAL PHRASE. */
.msg em,
.story-copy em,
.story-turn em,
.coach-lede em,
.p em,
.h2 em {
  font-style: normal;
  color: var(--teal);
}

/* Armed: all three collapse into ONE grid cell and stack on top of each
   other, so the cell sizes to the longest message and nothing moves as
   they hand over. The gap goes with them - it only exists for the
   unarmed fallback, where the three are separate paragraphs. */
html.ms .msgs-stage { gap: 0; }
html.ms .msg {
  grid-area: 1 / 1;
  opacity: 0;
  will-change: opacity;
}
html.ms .msg.is-on { opacity: 1; }

/* ⚠️ The transition is on a SECOND class, added ~50ms after arming.

   Arming has to be an instant snap, not a fade. If the transition were on
   `html.ms .msg` it would apply to the arm itself, and any load where the
   messages had already painted - a reload while scrolled here, a #msgs
   link - would show messages 2 and 3 visibly fading OUT before the
   sequence began. Measured: all three sat at opacity 1 on such a load.

   Splitting it means the arm snaps and only the handovers animate. Do not
   merge these back into one rule. */
html.ms-live .msg { transition: opacity 700ms ease; }

/* ══════════════════════════════════════════════════════════════
   § STORY - /why, "My Story"
   Rebuilt 04.09.2026. Was two dashed placeholder slots for a video
   and a Substack article that do not exist; both are gone.

   Same shape as the CTA block on purpose - copy left on the spine,
   one object right - so the page has one split it repeats rather
   than two different ones. The object here is the portrait, which
   is the only photograph on the site.
   ══════════════════════════════════════════════════════════════ */

/* Scoped, because `.h2` is shared with /free and /coaching and the nudge
   was not asked for there.

   ⚠️ It was teal for one round on 04.09.2026 and went back to the default
   near-black the same day. Teal on a heading is a new use of the colour -
   elsewhere it marks the phrase a sentence turns on, plus buttons and
   links - and it read as decoration rather than emphasis. Leave it black. */
.story-h {
  font-size: clamp(1.22rem, 2.1vw, 1.78rem);
  text-align: center;
  /* ⚠️ `.h2` carries `max-width: 28ch`. Without clearing it the heading
     centres inside a 28ch box sitting at the left edge, so it looks
     centred over the copy column rather than over the page. */
  max-width: none;
}

/* ── The staged reveal ────────────────────────────────────────
   Headline alone, then part one fades in on a timer, then part two on
   the scroll. The site's third and fourth animations.

   Same arming contract as the entry sequence and the messages: `.sr`
   goes on <html> from JS and every hidden state is scoped under it, so
   no-JS and prefers-reduced-motion render the whole story visible and
   static with nothing to reset.

   ⚠️ `.sr-live` carries the transition and lands ~50ms after `.sr`, so
   arming is a snap and only the reveal animates. Without the split, a
   page loaded already scrolled to this section would show the story
   visibly fading OUT before fading back in. That exact bug was shipped
   once on the /why messages; do not merge these two rules. */
/* ⚠️ No `min-height` any more. It was `100dvh` so the headline could own a
   screen, but centring 545px of content in 900px left 198px of dead space
   under the divider - which was most of the 238px gap to part two.

   Part two now peeks in BLURRED instead, which does the isolating that the
   empty screen used to do. Do not put the height back without taking the
   blur out; the two solve the same problem. */
.story-part1 {
  display: flex;
  flex-direction: column;
  /* The headline stands alone here before anything else arrives, so the
     gap under it has to be large enough to read as a deliberate pause
     rather than a paragraph break. It was ~40px, which was not. */
  gap: clamp(44px, 6vw, 104px);
}
/* Controlled by the gap above, in one place. `.story` carries its own
   top margin for part two, where there is no flex parent to space it. */
.story-part1 .story,
.story-haze .story { margin-top: 0; }
/* BOTH parts are BLURRED, not hidden. You can see something is waiting
   without being able to read it, so it draws you down instead of competing
   for attention - which is the job the full-screen part one used to do
   with empty space.

   ⚠️ Part one used to fade from opacity 0 (`.story-veil`) and was switched
   to the same blur on 07.09.2026, on Lorenz's note that the part two effect
   looked better. `.story-veil` had no other user and its three rules were
   deleted with the switch. **One device now, not two.**

   ⚠️ What that cost: part one is no longer INVISIBLE under the headline,
   it is visible-but-unreadable. The headline no longer stands alone in the
   strict sense - there is blurred text beneath it for the 700ms hold. That
   is the effect, not a fault. If the headline ever has to stand truly
   alone again, the fade is what does it, not the blur.

   ⚠️ The two triggers are NOT the same and must not be unified. Part one
   fires on `.story-part1` crossing 0.3 of the viewport and then waits
   HOLD ms; part two fires on `#story-v2` itself crossing 0.55, with no
   hold. Part two is deliberately already on screen while part one is being
   read, so a generous threshold there would fire instantly and there would
   be no effect to see. */
html.sr .story-haze { opacity: 0.45; filter: blur(9px); }
html.sr .story-haze.is-in { opacity: 1; filter: blur(0); }

html.sr-live .story-haze { transition: opacity 1200ms ease, filter 1200ms ease; }

.story {
  display: grid;
  grid-template-columns: minmax(0, 1fr) clamp(220px, 26vw, 370px);
  gap: clamp(30px, 5vw, 72px);
  /* Top-aligned, not centred: each photo should start level with the first
     line of the beat it illustrates, not float against the middle of it. */
  align-items: start;
  max-width: 1180px;
  margin-top: clamp(24px, 3vw, 40px);
}

/* Beat 2 flips the sides. The alternation is what makes the two halves
   read as separate chapters instead of one long column, and it is the
   only place on the site where copy is not on the left spine - which it
   can afford because the section headline still is. */
/* ⚠️ A NARROWER column than beat one, deliberately. The portrait is 4:5
   and the sale photo is 4:3, so at the shared 370px the portrait stood
   463px tall against 278px - and beat two carries less text than beat one
   since "the best people left" moved up. 300px puts it at 375px, close to
   the height of the copy beside it. */
.story-flip {
  grid-template-columns: clamp(190px, 22vw, 300px) minmax(0, 1fr);
}

.story-copy > * + * { margin-top: clamp(18px, 2.2vw, 28px); }

/* ⚠️ Every story paragraph carries `.lede`, so they are all the SAME size.
   Lorenz asked for that on 04.09.2026, replacing a big / small hierarchy
   where the second paragraph sat at body size and was the least readable
   thing on screen while carrying the part that proves the point.
   Do not re-introduce a smaller paragraph here. */

/* Both photos share a column width but NOT a ratio: the portrait is 4:5,
   the sale photo is 4:3 because the five of them span the whole frame and
   any tighter crop clips someone out. The crops are baked into the files,
   so object-fit never has to discard anything. */
.story-photo img {
  width: 100%;
  height: auto;
  border-radius: var(--radius-lg);
}
/* The hand-drawn "me" arrow on the sale photo.

   ⚠️ Bottom-anchored with the height derived from its own width, so the
   overhang above the picture is a fixed SHARE of the width at every size
   and the layout never shifts. Do not switch this to a percentage padding
   or margin: those resolve against the GRID COLUMN, not the figure, and
   would come apart the moment .story-photo is capped on mobile.

   viewBox is 100 x 97: 22 units of overhang above, then the 100 x 75
   picture. If the photo ratio ever changes, that 75 changes with it. */
.story-annot { position: relative; }
.story-arrow {
  position: absolute;
  left: 0;
  bottom: 0;
  width: 100%;
  height: auto;
  aspect-ratio: 100 / 97;
  color: var(--teal);
  pointer-events: none;
  overflow: visible;
}

/* The pulled-out verdict. Split from the second paragraph at a sentence
   boundary, so not one word of Lorenz's copy changed. It is the thesis of
   the entire page, so it lands on its own. */
.story-turn {
  /* More air than any other gap in the section: the space IS the divider,
     since the site has no rules or borders anywhere and this is not the
     place to introduce the first one. */
  margin-top: clamp(44px, 6vw, 88px);
  margin-bottom: clamp(40px, 5.5vw, 80px);

  /* ⚠️ Sized to hold ONE LINE across the full container, not for weight.
     This sentence needs 51.3px of width per 1px of font-size in Open Sans
     400 at -0.015em (measured: 1379px at 26.86px). The container gives
     1352px at 1440 and above, so 1.5rem is the ceiling with ~43px to
     spare. Push it up and it wraps; that is the trade, made knowingly -
     it used to be 2.15rem over three lines.

     ⚠️ **Re-measure inside the real page, not in a scratch file.** A
     standalone probe reported 1311px for the same string because Open
     Sans had not loaded and it fell back to a narrower system face, and
     the first version of this rule wrapped as a result. Clone the live
     element, set `white-space: nowrap`, read its width.

     `calc(1.9vw - 1.6px)` shrinks with the viewport so the single line
     survives to roughly a 1140px window. Below that the 1.2rem floor
     takes over and it wraps, because one line would have to go smaller
     than the paragraphs and the hierarchy would invert.

     ⚠️ No `max-width`. It deliberately runs 172px wider than the two
     story blocks above and below it: overhanging the columns is what
     makes it read as a break across the section rather than another
     paragraph in one. Re-measure all of this if the copy changes. */
  font-size: clamp(1.2rem, calc(1.9vw - 1.6px), 1.5rem);
  font-weight: 400;
  line-height: 1.35;
  letter-spacing: -0.015em;
  color: var(--text);
  text-wrap: pretty;
}

/* The wordmark as a full stop. The story ends with sales_essentially being
   founded, so the mark signs it rather than announcing anything. Muted and
   small on purpose: at full teal it competed with the teal in the sentence
   directly above it. */
.story-sign {
  display: flex;
  align-items: center;
  gap: 0.5em;
  margin-top: clamp(26px, 3vw, 40px);
  font-weight: 700;
  font-size: 0.95rem;
  letter-spacing: -0.015em;
  color: var(--teal);
  opacity: 0.55;
}
.story-sign svg { width: 1.5em; height: 1.5em; flex: none; }

@media (max-width: 860px) {
  /* One column, and neither beat leads with a photo. Leading with one
     would break the headline spine the section opens on, and in beat 2 it
     would also put a portrait before the sentence that explains it. */
  .story,
  .story-flip { grid-template-columns: minmax(0, 1fr); }
  .story-flip .story-photo { order: 2; }
  .story-flip .story-copy  { order: 1; }
  .story-photo { max-width: 340px; }

  /* ⚠️ BEAT 1 ONLY: the sale photo moves BETWEEN the two paragraphs, so it
     lands under "simplicity in every step of the sales process". Lorenz,
     07.09.2026: the photo illustrates the HIGH POINT of the Bookboon story,
     and stacked at the end of both paragraphs it sat under "the best people
     left" instead - under the collapse it has nothing to do with.

     `display: contents` on the copy wrapper drops its box so the two
     paragraphs become grid items in their own right and `order` can put the
     figure between them. The wrapper has no semantics of its own, which is
     what makes this safe. Desktop never sees any of it: there the wrapper
     is a real column and the photo sits beside it. */
  .story-b1 .story-copy { display: contents; }
  .story-b1 .story-copy > p:first-child { order: 1; }
  .story-b1 .story-photo                { order: 2; }
  .story-b1 .story-copy > p:last-child  { order: 3; }
  /* The paragraph gap is now the grid's row gap, so drop the margin that
     used to make it or the two would add up. */
  .story-b1 .story-copy > * + * { margin-top: 0; }

  /* ⚠️ Reserve the arrow's overhang, which stacking made into a collision:
     the svg is bottom-anchored and overhangs the picture by 22% of its own
     width, and side by side that hung over empty column. Stacked it hangs
     over the last line of the paragraph above, which is what Lorenz saw.

     `min(75px, 22%)` is exact rather than approximate, and it is the one
     safe way to use a percentage here. The 22% resolves against the grid
     column, which is only correct while the column is NARROWER than the
     340px cap; past that the figure stops growing and the true overhang
     stops at 0.22 x 340 = 74.8px, which is what the px arm pins. Take
     either half away and it is wrong at one end or the other. */
  .story-annot { margin-top: min(75px, 22%); }
}

/* ══════════════════════════════════════════════════════════════
   § ARCHIVE - /free section 2
   All 17 as previews: cover, headline, one line. No categories, no
   filters, no search, no tags, no reading-time badges.

   ⚠️ Rebuilt 07.09.2026 from a text list into cards, on Lorenz's note to
   bring back the old knowledge base design. What did NOT come back from
   that design, deliberately:
     - the 1px border, the shadow and the hover lift. This build has no
       boxes anywhere and § MOTION bans hover lifts outright. The rounded
       cover is what makes a card read as a card.
     - the "New" badge, the Substack kicker and the "Read on Substack"
       link. Lorenz cut all three; the whole card is already the link.
   Putting any of them back re-opens a rule, so do it on purpose.
   ══════════════════════════════════════════════════════════════ */

/* Three across. The cap is gone with the text list that needed it: a card
   is bounded by its own cover, not by a measure, so the grid can use the
   container's full 1352px. At three columns that is ~410px a card, which
   is close to the 16:9 cover's natural reading size. */
.arc {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: clamp(32px, 3.4vw, 52px) clamp(24px, 2.6vw, 40px);
  /* ⚠️ This is now the ONLY gap between the intro copy and the grid - the
     section seam that used to sit here is gone (see /free section 1). It
     has to read as "a new thing starts", so it is deliberately more than
     twice the 30px `.stack` gap between the headline and its line above.
     Previously clamp(28px, 3.6vw, 44px), when a section boundary and a
     heading were doing this job. */
  margin-top: clamp(44px, 5.4vw, 78px);
}
@media (max-width: 1000px) { .arc { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (max-width:  640px) { .arc { grid-template-columns: minmax(0, 1fr); } }

/* The one line under the headline. Its own measure, on the element that
   carries the type - `.p` caps at 62ch, which is right for a paragraph in
   running text and too long for a single line introducing a grid. */
/* The gap `.stack` used to make, set here instead. The wrapper cannot
   carry `.stack` any more: it would also put a margin on `.arc`, which
   already sets its own and much larger one below. */
.free-lede { max-width: 52ch; margin-top: clamp(18px, 2.2vw, 30px); }

.arc-item { display: block; text-decoration: none; }

/* ⚠️ The 16:9 box is the ONLY thing making the grid regular: the 17 source
   covers run from 0.75 (portrait) to 1.79, so `object-fit: cover` is doing
   real work here and a few of them are cropped hard. The crops are NOT
   baked into the files, unlike the two story photos - these are article
   artwork that often carries text, and an auto-crop baked in would be
   unrecoverable. Fix a bad one with `object-position` on that card, not by
   re-cropping the source. */
.arc-cover {
  display: block;
  aspect-ratio: 16 / 9;
  overflow: hidden;
  border-radius: var(--radius-lg);
  background: var(--bg-alt);
}
.arc-cover img { width: 100%; height: 100%; object-fit: cover; display: block; }

.arc-title {
  display: block;
  margin-top: clamp(12px, 1.2vw, 16px);
  font-weight: 700;
  font-size: 1.06rem;
  line-height: 1.3;
  letter-spacing: -0.01em;
  color: var(--text);
  transition: color 180ms ease;
}
.arc-item:hover .arc-title { color: var(--teal); }
/* Its own measure, on the element carrying the type. The grid column caps
   it at three across; this is what holds the line at two and at one. */
.arc-sub {
  display: block;
  margin-top: 6px;
  font-size: 0.92rem;
  line-height: 1.5;
  color: var(--text-muted);
  max-width: 44ch;
}

/* ══════════════════════════════════════════════════════════════
   § GUIDE - /guide, where every format button lands
   Nothing on this page competes with the three buttons. The P.S. is
   body size, not small print: it is the most persuasive thing on the
   site and shrinking it would waste it.
   ══════════════════════════════════════════════════════════════ */

.gd { max-width: 62ch; }
.gd .btn-row { margin-block: clamp(26px, 3.2vw, 38px); }
.gd-ps { max-width: 62ch; font-size: 1rem; color: var(--text-body); }

/* ══════════════════════════════════════════════════════════════
   § LEGAL - impressum, datenschutz
   ══════════════════════════════════════════════════════════════ */

.legal { max-width: 68ch; }
.legal h1 { font-size: clamp(1.6rem, 3vw, 2.2rem); line-height: 1.2; color: var(--text); letter-spacing: -0.02em; }
.legal h2 { font-size: 1.15rem; color: var(--text); margin-top: 2em; margin-bottom: 0.5em; }
.legal h3 { font-size: 1rem; color: var(--text); margin-top: 1.4em; margin-bottom: 0.35em; }
.legal p, .legal ul { margin-bottom: 1em; }
.legal ul { padding-left: 1.3em; }
.legal a { color: var(--teal); }

/* ══════════════════════════════════════════════════════════════
   § REDUCED MOTION
   Every animation degrades to a complete, readable, static page.
   Never to nothing. The two armed classes are simply never added by
   JS, so this block is a backstop rather than the mechanism.
   ══════════════════════════════════════════════════════════════ */

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

/* ══════════════════════════════════════════════════════════════
   § THE METHOD SECTION - /why, section 3
   Added 06.09.2026 from salesessentially-why-method_Brief_v1.md.

   The page argued that simplicity wins and proved it with Bookboon,
   and never said HOW the simplicity gets produced. This is that, as
   a drawing rather than more prose: the page is already text-heavy
   and the method has to survive being redrawn on a whiteboard in a
   first call.

   Three variants were built and previewed on 06.09.2026 - levers,
   triangle, uprights. Lorenz picked the triangle, and the other two
   were deleted from here the same day along with the preview file.
   What the losers were, in case it ever comes up again:
     A, three sliders with the handles pulled DOWN. The only one that
        answered "the drawing has to read as less" head on.
     C, three uprights. Killed by its own shape: uprights read as
        structure ADDED, which is the argument this page is against.
   ══════════════════════════════════════════════════════════════ */

/* ⚠️ Trimmed top padding, and ONLY above 860px. Measured 06.09.2026 at
   1440: 507px of blank sat between the last message and this heading.
   Only 128px of that was this section's own `--band` top padding; the
   other 379px is `.msgs` being `min-height: 100dvh` with its message
   vertically centred, so the bottom half of that screen is always empty.

   Trimming here cannot close the gap, and is not trying to. What it does
   is put the heading AT the tint edge, so the colour change and the
   heading arrive as ONE event instead of two with a hole between them.
   That is most of the perceived fix; the arithmetic is only a quarter of
   it.

   ⚠️ Scoped to min-width 861px because BELOW that `.msgs` drops its
   100dvh (see the 860px block in § MESSAGES) and there is no void to
   fix - trimming there would only cramp a section that is already tight.

   The remaining lever, if it is ever raised again, is `.msgs` min-height.
   Taking it under 100dvh would close the other 379px and would cost the
   one-message-alone-on-a-screen effect, which is the point of that
   section. Do not do it without asking.

   ⚠️ There is no matching bottom trim. The gap under this section is the
   CTA's own top padding and it reads correctly. */
@media (min-width: 861px) {
  .method-sec { padding-top: clamp(36px, 3.4vw, 52px); }
}

.method-lede { margin-top: clamp(14px, 1.6vw, 22px); }

/* ⚠️ NOT a <ul>, and it cannot be one. The triangle has to sit in the
   same grid as the three labels or it cannot be centred between them,
   and an <svg> is not valid inside a list. role=list / role=listitem
   reads identically to a screen reader and validates. That is the
   price of this variant, paid deliberately.

   No border, no rule, no card. Space is the divider everywhere on this
   build and the method section is not where that changes. */
.method-set {
  margin: clamp(40px, 5vw, 76px) 0 0;
  display: grid;
  grid-template-columns: 1fr 1fr;
  grid-template-areas:
    "top  top"
    "art  art"
    "bl   br";
  justify-items: center;
  gap: clamp(16px, 2vw, 26px) clamp(28px, 4vw, 60px);
}

/* The drawing is the drawing and nothing else. Every string is real
   HTML, so the German twin has something to translate, the lines wrap
   on a narrow screen, and the type renders as Open Sans like the rest
   of the page. */
.method-art {
  display: block;
  grid-area: art;
  width: clamp(200px, 26vw, 320px);
  height: auto;
}

/* ⚠️ The centre stays empty. Do not put a word in it. */
.method-tri { fill: none; stroke: var(--teal); stroke-width: 2; stroke-linejoin: round; }
.method-dot { fill: var(--teal); }

/* ⚠️ This is the second place on the site where copy is centred rather
   than on the left spine, after the /why messages. The shape forces it:
   labels hung off three corners cannot be left-aligned without looking
   like a mistake. Accepted when the triangle was picked. */
.method-item { max-width: 330px; text-align: center; }
.method-item:nth-of-type(1) { grid-area: top; }
.method-item:nth-of-type(2) { grid-area: bl; }
.method-item:nth-of-type(3) { grid-area: br; }

/* px on the box above, ch on the elements that actually carry the type
   - `ch` resolves against the element's own font-size, so a measure set
   on the wrapper would drift from what the label and the line really
   get. Same split as .cta-in and .arc. */
.method-label {
  font-size: clamp(1.02rem, 1.35vw, 1.18rem);
  font-weight: 700;
  line-height: 1.25;
  color: var(--text);
  margin: 0;
  max-width: 24ch;
  margin-inline: auto;
}
.method-desc {
  font-size: 0.98rem;
  line-height: 1.5;
  color: var(--text-muted);
  margin: 0.45em auto 0;
  max-width: 30ch;
}

/* ⚠️ Deliberate departure from brief § 5.2 rule 7, flagged for Lorenz
   and left standing. Rule 7 says one CORNER per row below 600px, which
   dismantles the triangle on every phone and leaves three loose dots.
   The shape is the whole reason this variant won, so it stays whole and
   the three pairs stack beneath it. */
@media (max-width: 600px) {
  .method-set {
    grid-template-columns: 1fr;
    grid-template-areas: "art" "top" "bl" "br";
    justify-items: start;
    gap: clamp(20px, 5vw, 30px);
  }
  .method-item { text-align: left; }
  .method-label, .method-desc { margin-inline: 0; }
  .method-art { justify-self: center; margin-bottom: clamp(10px, 3vw, 18px); }
}
