/* ECO POWERTECH — design tokens
   Single source of truth. Nothing in src/css/ may hardcode a colour, size or duration.
   Derived from measured values: brand magenta #A2185B and slate #54595F sampled from the
   live site; magenta-lit derived from the hero render (#BD3F79 surface / #CD4A88 lit, H332).
   ------------------------------------------------------------------------------------ */

:root {
  /* ---- Magenta ramp -------------------------------------------------------
     One hue family, H331–333, four luminance stops. The brand magenta is
     preserved verbatim where it passes contrast (cotton bands) and lifted where
     it must be (ink bands). The palette gains luminance in the dark exactly as
     the magenta rim light does in the hero footage. */
  --magenta-deep:    #6B0F3D;  /* dark magenta surfaces, shadow, overlay      */
  --magenta-brand:   #A2185B;  /* HERITAGE — unchanged. 6.61:1 on cotton      */
  --magenta-lit:     #E03B84;  /* ink bands only. 4.73:1 on ink               */
  --magenta-glow:    #FF5C9E;  /* hover, glow, focus ring. NEVER text         */
  /* Fifth stop, added for the magenta band. H332.5 — same family, measured.
     --magenta-glow is only 4.18:1 on --magenta-deep, which fails AA for the
     11px mono eyebrows that band carries; this tint is 6.96:1 and passes. */
  --magenta-tint:    #E8B8CE;  /* muted text on magenta. 6.96:1 on deep       */

  /* ---- Neutrals ---------------------------------------------------------- */
  --ink:             #0B0E11;  /* near-black canvas                           */
  --ink-raised:      #131820;  /* cards and panels on ink                     */
  --ink-hairline:    #242B33;  /* 1px rules on ink                            */
  --cotton:          #F4F1EA;  /* warm cotton white. 17.16:1 against ink      */
  --cotton-raised:   #FBF9F5;  /* cards and panels on cotton                  */
  --cotton-hairline: #DCD6CB;  /* 1px rules on cotton                         */
  --slate:           #54595F;  /* HERITAGE — body text on cotton. 6.27:1      */
  --slate-dim:       #8A9099;  /* muted text on ink. 6.02:1                   */

  /* ---- Control edges — WCAG 2.1 AA §1.4.11 ---------------------------------
     The hairline stops above are TEXT-adjacent decoration and were measured
     against 1.4.3 only. Measured again against 1.4.11 (Non-text Contrast, 3:1
     for the visual boundary of a user-interface component) they all fail as
     control borders: --ink-hairline 1.35:1, --cotton-hairline 1.37:1,
     --magenta-brand 1.60:1. A form input whose only boundary is a 1.37:1 rule
     is a control a low-vision visitor cannot find, and the enquiry form is the
     one thing on this page that converts.

     These three stops exist so a CONTROL edge can pass 3:1 without dragging
     every decorative rule on the page up with it — the section rules and card
     edges are not controls and should stay quiet. Measured, worst case of the
     band's own --bg and --bg-raised:
       --ink-edge      3.42:1 on ink   · 3.15:1 on ink-raised
       --cotton-edge   3.39:1 on cotton · 3.63:1 on cotton-raised
       --magenta-edge  3.96:1 on magenta-deep
     --magenta-edge is H331.7, inside the H331–333 family the whole ramp holds;
     it is not a new hue. */
  --ink-edge:        #606870;  /* control boundary on ink                     */
  --cotton-edge:     #878279;  /* control boundary on cotton                  */
  --magenta-edge:    #C77FA1;  /* control boundary on magenta. H331.7         */

  /* ---- Semantic defaults (ink band) --------------------------------------
     Bands set these. Components only ever read the semantic name, never a raw
     colour — that is what lets a section flip ink↔cotton with one attribute. */
  --bg:            var(--ink);
  --bg-raised:     var(--ink-raised);
  --fg:            var(--cotton);
  --fg-muted:      var(--slate-dim);
  --accent:        var(--magenta-lit);
  --hairline:      var(--ink-hairline);
  --control-edge:  var(--ink-edge);
  --focus:         var(--magenta-glow);

  /* ---- Type -------------------------------------------------------------
     Archivo (variable, 100–900 + Expanded width) — technical grotesque, full
     German diacritic coverage. JetBrains Mono for eyebrows and data only.
     No Didone. No third family. */
  --font-sans: 'Archivo', system-ui, -apple-system, 'Segoe UI', sans-serif;
  --font-mono: 'JetBrains Mono', ui-monospace, 'SF Mono', Menlo, monospace;

  /* Fluid to 2560, not to 1400.
     The previous ladder hit every ceiling far too early — --display-xl reached
     its cap at a 1511px viewport and --h2 at 1300px, so from ~1536px upward the
     page stopped growing entirely and a 1920 display got a letterboxed column
     with 192px of dead margin each side. The vw coefficients below are set so
     each maximum lands near 2560 instead.

     Running text is deliberately NOT fluid. --body stays at 1rem: line length is
     already governed by --measure, and tying body copy to viewport width breaks
     user zoom for the people who need it most. Only display sizes scale. */
  --display-xl: clamp(3.25rem, 7vw, 11rem);      /* cap at ~2515px  */
  /* The hero display sits in a half-width column beside the clip, not across
     the whole viewport, so it is a step below --display-xl. At 134px across
     1169px it dominated the frame and forced the scrim to be enormous; at ~84px
     in an 800px column it reads as a statement and leaves the footage alone.

     Raised from 4.4vw. Measured at 1440: the h1 rendered 63px against an --h2
     of 49px — a ratio of 1.29, so the page thesis barely outranked a section
     heading. 4.8vw gives 69px and a 1.41 ratio. It is not pushed further
     because the hero line is now a full sentence in a half-width column. */
  --display-hero: clamp(2.5rem, 4.8vw, 6rem);
  --display-l:  clamp(2.5rem, 5vw, 7rem);        /* cap at ~2240px  */
  --h2:         clamp(2rem, 3.4vw, 4.5rem);      /* cap at ~2118px  */
  /* The missing rung. Measured, the ladder jumped --h2 49px -> --h3 20px, a
     2.45x step with nothing in it, while --h3 -> --body was only 1.25x. Every
     sub-head and list item between those two sizes had to borrow a wrong one.
     This sits at ~32px at 1440 and is what the Berufsfelder list uses — the
     list that was previously rendering at 72px, LARGER than the h1. */
  --h3-l:       clamp(1.5rem, 2.2vw, 2.75rem);
  /* --h3 is a CARD heading as often as a sub-head, so it scales far less than
     the display tiers. Letting it reach 36px made six-across service cards
     wrap their titles to three lines. */
  --h3:         clamp(1.25rem, 1.2vw, 1.75rem);
  --body-l:     clamp(1.125rem, 1.05vw, 1.375rem);
  --body:       1rem;
  --small:      0.875rem;
  --eyebrow:    0.6875rem;

  /* Leading climbs one step per tier. --lh-lead was added after
     research/03-references.md measured the same ladder on three references
     (Connectr 1.10-1.50, Podium 1.10/1.20/1.50, CURA 0.90-1.30) and found this
     token set jumping 1.08 -> 1.65 with nothing between. Sub-headings and lead
     paragraphs had no correct value and would have borrowed a wrong one. */
  --lh-display: 0.92;
  --lh-heading: 1.08;
  --lh-lead:    1.30;
  --lh-body:    1.65;

  --tr-display: -0.035em;   /* display sizes need negative tracking          */
  --tr-heading: -0.02em;
  --tr-lead:    -0.01em;    /* body family, still above running-text size    */
  --tr-body:    0;
  --tr-eyebrow: 0.18em;     /* mono caps, wide                               */

  /* Width axis. Archivo ships wdth 62-125 in the one variable file; the
     display face is the expanded end. Declared as tokens so no component
     hardcodes a font-stretch. */
  --wd-display: 118%;
  --wd-normal:  100%;

  /* SVG diagram type. These are USER-SPACE units inside a 300x220 viewBox,
     not CSS pixels — a rem value here scales with the viewBox and overflows
     the nodes. Sized so the longest label ("Ihr Unternehmen", 15 characters
     of mono) sits inside a 116-unit node with margin. */
  --diagram-label: 11px;
  --diagram-edge:  10px;

  --wt-regular: 400;
  --wt-medium:  500;
  --wt-semi:    600;
  --wt-bold:    700;

  /* ---- Space — 4px base -------------------------------------------------- */
  --s-1: 0.25rem;  --s-2: 0.5rem;   --s-3: 0.75rem;  --s-4: 1rem;
  --s-6: 1.5rem;   --s-8: 2rem;     --s-12: 3rem;    --s-16: 4rem;
  --s-24: 6rem;    --s-32: 8rem;    --s-48: 12rem;

  /* Minimum interactive target. Measured on a 375px viewport, the page had ten
     targets under 44px — the worst being the telephone and e-mail links at
     18px, which are one of the two ways a visitor actually converts. WCAG 2.2
     §2.5.8 sets 24px as the AA floor; 44px is the figure Apple and Google both
     publish and the one this build holds itself to. */
  --tap-min: 44px;

  --section-y: clamp(4rem, 9vw, 14rem);
  /* The page is full-bleed: there is no fixed container any more, so the gutter
     IS the layout. It has to keep growing well past 1600px or the content runs
     to the screen edge on a wide display. */
  --gutter:    clamp(1.25rem, 4vw, 7rem);
  --measure:   68ch;          /* max line length for body copy — never fluid */

  /* ---- Shape — ONE radius system, sharp. No mixing. ---------------------- */
  --radius:       0px;
  --radius-pill:  999px;      /* pills only where the brand already uses them */
  --hairline-w:   1px;

  /* ---- Motion — timings from emil-design-eng ---------------------------- */
  --dur-hover:  140ms;
  --dur-press:  120ms;
  --dur-enter:  520ms;
  --dur-exit:   240ms;
  /* Hover/press affordance. Separate from --dur-enter (520ms) on purpose:
     --dur-enter times a scroll REVEAL, where 520ms is a settle the visitor is
     not waiting on. The Berufsfelder cards were reusing it for the hover image
     scale and the accent rule draw, which are direct RESPONSES to a pointer —
     and a response the user is watching has a 300ms ceiling before it reads as
     sluggish (emil-design-eng). 220ms is inside the dropdown/select band. */
  --dur-affordance: 220ms;
  --stagger:    60ms;

  --ease-out:   cubic-bezier(0.22, 1, 0.36, 1);   /* entries                 */
  --ease-inout: cubic-bezier(0.65, 0, 0.35, 1);   /* on-screen movement      */
  /* ease-in is never used — it reads sluggish. */

  /* Phase 6. The hero pin travel. The scrubber is now a real <video> at 24fps
     (387 frames over 16.1s), so the frame budget no longer constrains this —
     300svh gives ~8px of scroll per frame at a 1080px viewport, finer than
     anyone can perceive. Applied ONLY inside the scrubber guard in motion.css:
     with JS off, reduced motion, or below 900px the hero stays one screen tall
     and there is no dead scroll. */
  /* The nav's height, locked rather than inferred.
     The hero stage is exactly 100svh, so if the hero started BELOW the nav the
     stage would overflow the viewport by this much and the first 80px of
     scrolling would move the hero without scrubbing anything — a dead zone
     inside the first screen. The hero is pulled up by --nav-h instead, so the
     pin and the scrub both begin at scrollY 0. Locking the value with
     min-height keeps that arithmetic true if the logo or the buttons change. */
  --nav-h:        5rem;

  --hero-track:   300svh;
  --reveal-shift: 2rem;      /* how far a revealing block travels          */
  /* How far into view a block is before its reveal STARTS.
     Without this the range began at `entry 0%` — the instant the element's top
     edge touches the bottom of the viewport — so the whole reveal played out in
     the lowest few hundred pixels of the screen, in peripheral vision, and was
     over before the element was properly on screen. Nobody saw it. Starting
     140px in puts the motion in the lower-middle of the viewport, where the
     reader is actually looking. */
  --reveal-delay: 140px;
  /* One step between items in a staggered list, expressed in SCROLL pixels
     because scroll-driven ranges are lengths, not durations. --stagger is
     the time-based sibling used by transitions; the two are not
     interchangeable and conflating them is how a stagger ends up either
     invisible or comically slow. */
  --stagger-px:   64px;
  /* Scroll-linked reveals are ranged by LENGTH, not by percentage of the
     subject: an `entry 8% -> entry 62%` range is sized by the element, so a
     793px block took 428px of scroll to fade in — under 0.05px of change per
     scrolled pixel, which reads as nothing happening at all. A fixed length
     gives every block the same reveal rhythm regardless of its height. */
  --reveal-run:   280px;

  --z-hero: 1; --z-content: 10; --z-nav: 100; --z-overlay: 1000;
}

/* ---- Bands --------------------------------------------------------------
   The page rhythm is alternating full-bleed ink and cotton. A band re-points
   the semantic tokens; every component inside adapts with no extra rules. */

[data-band="ink"] {
  --bg: var(--ink);          --bg-raised: var(--ink-raised);
  --fg: var(--cotton);       --fg-muted:  var(--slate-dim);
  --accent: var(--magenta-lit);
  --hairline: var(--ink-hairline);
  --control-edge: var(--ink-edge);
}

[data-band="cotton"] {
  --bg: var(--cotton);       --bg-raised: var(--cotton-raised);
  --fg: var(--ink);          --fg-muted:  var(--slate);
  --accent: var(--magenta-brand);
  --hairline: var(--cotton-hairline);
  --control-edge: var(--cotton-edge);
}

/* The third band. The live site runs its two loudest moments — the positioning
   statement and the Jobbörse hand-off — on solid brand magenta, and that is
   worth keeping: it breaks a page that would otherwise alternate ink/cotton
   eight times without variation, and it costs no new hue (--magenta-deep is
   already in the ramp).

   There is no second accent here. On a magenta ground the band IS the accent,
   so --accent resolves to --cotton and the emphasis comes from weight, not
   colour. Measured: cotton 10.64:1, tint 6.96:1, both on --magenta-deep. */
[data-band="magenta"] {
  --bg: var(--magenta-deep); --bg-raised: var(--magenta-deep);
  --fg: var(--cotton);       --fg-muted:  var(--magenta-tint);
  --accent: var(--cotton);
  --hairline: var(--magenta-brand);
  --control-edge: var(--magenta-edge);
}

/* ---- Reduced motion -----------------------------------------------------
   awwwards-standard hard gate #2 overrides emil-design-eng here: the site is
   complete, legible and navigable with ZERO motion, not reduced motion. */

@media (prefers-reduced-motion: reduce) {
  :root {
    --dur-hover: 0ms; --dur-press: 0ms;
    --dur-enter: 0ms; --dur-exit: 0ms; --stagger: 0ms;
    --dur-affordance: 0ms;
  }
}
