
/* ---------- self-hosted fonts (2026-07-30) ----------
   The fonts.googleapis.com chain cost ~750ms of mobile render-block, so the
   same faces now ship from our own origin. Montserrat is ONE file for all
   three weights — Google serves it as a variable font, and each declaration
   below instantiates the wght axis at its own weight, exactly as Google's
   own served CSS does. font-display:swap: text renders immediately in the
   fallback and swaps when the face lands. */
@font-face{font-family:'Montserrat';font-style:normal;font-weight:700;font-display:swap;src:url(fonts/montserrat-700.06b16db7.woff2) format('woff2')}
@font-face{font-family:'Montserrat';font-style:normal;font-weight:800;font-display:swap;src:url(fonts/montserrat-700.06b16db7.woff2) format('woff2')}
@font-face{font-family:'Montserrat';font-style:normal;font-weight:900;font-display:swap;src:url(fonts/montserrat-700.06b16db7.woff2) format('woff2')}
@font-face{font-family:'Lato';font-style:normal;font-weight:400;font-display:swap;src:url(fonts/lato-400.918b7dc3.woff2) format('woff2')}
@font-face{font-family:'Lato';font-style:normal;font-weight:700;font-display:swap;src:url(fonts/lato-700.c447dd76.woff2) format('woff2')}
@font-face{font-family:'Lato';font-style:normal;font-weight:900;font-display:swap;src:url(fonts/lato-900.08664859.woff2) format('woff2')}

:root{
  --green:#FF9F1C;          /* the new bright brand green */
  --deep:#7A3418;           /* near-black green, the thumbnail base */
  --deeper:#5C2610;
  --yellow:#FFD02B;         /* brand yellow, from the Descript caption config */
  --cream:#F1F1E6;
  --white:#fff;
  --ink:#5C2610;
  --head:'Montserrat',system-ui,sans-serif;
  --body:'Lato',system-ui,sans-serif;
  --pad:clamp(1.25rem,5vw,6rem);
  --max:1440px;
  --arrow:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M13.1 4.3 20.8 12l-7.7 7.7-1.9-1.9 4.5-4.5H3.2v-2.6h12.5l-4.5-4.5z'/%3E%3C/svg%3E");
}
*,*::before,*::after{box-sizing:border-box}
html{scroll-behavior:smooth;-webkit-text-size-adjust:100%}
body{margin:0;background:var(--deep);color:var(--white);font-family:var(--body);overflow-x:hidden;-webkit-font-smoothing:antialiased}
.wrap{max-width:var(--max);margin-inline:auto;padding-inline:var(--pad)}
h1,h2,h3{font-family:var(--head);margin:0;line-height:1;letter-spacing:-.02em}
.hl{color:var(--yellow)}
.section{position:relative;padding:clamp(4rem,9vw,8rem) 0}
/* diagonal split, the device from the reference template */
.slant{clip-path:polygon(0 0,100% 3.5vw,100% 100%,0 calc(100% - 3.5vw))}
/* The top edge here must be the SAME LINE as .slant's bottom edge, and the
   section must be pulled up by the same 3.5vw so the two coincide. It used to
   slope the opposite way with no negative margin, which left a wedge of page
   background — 134px tall at the left edge on a 1920 screen — showing between
   the two sections as a third colour. The extra 2px is a deliberate hairline
   overlap so sub-pixel rounding cannot reopen a seam along the diagonal. */
.slant-t{margin-top:calc(-3.5vw - 2px);clip-path:polygon(0 0,100% 3.5vw,100% 100%,0 100%)}

/* ---------- nav ---------- */
.nav{position:sticky;top:0;z-index:60;background:rgba(122,52,24,.86);backdrop-filter:blur(10px);border-bottom:1px solid rgba(255,159,28,.18)}
/* The nav is sticky, so anything scrolled to lands UNDERNEATH it unless the
   target reserves a nav's worth of clearance. Without this the section label
   is hidden behind the bar every single time. */
section[id],span[id]{scroll-margin-top:6rem}
.nav__in{display:flex;align-items:center;justify-content:space-between;gap:1rem;padding-block:1rem}
.logo{font-family:var(--head);font-weight:900;font-size:1.4rem;letter-spacing:-.03em}
.logo span{color:var(--green)}
.nav__links{display:none;gap:2rem;font-weight:700;font-size:.9rem;text-transform:uppercase;letter-spacing:.08em}
.nav__links a{color:var(--white);text-decoration:none;opacity:.8}
.nav__links a:hover{opacity:1;color:var(--green)}
/* START gets a hand-drawn yellow circle, like someone went over the menu with
   a marker. The ellipse is a single inline SVG data URI — two slightly uneven
   arcs whose tail overshoots the start, which is what sells "drawn by hand";
   a clean <ellipse> just looks like a border. Sits on a pseudo-element so the
   markup stays a plain link, tilted 4 degrees for the same reason, and
   pointer-events:none so the circle never steals the click. Full opacity: the
   .8 the other links run at makes the yellow look dusty. */
.nav__start{position:relative;opacity:1}
.nav__start::after{content:"";position:absolute;inset:-.85em -1.25em;
  background:url("data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A//www.w3.org/2000/svg%22%20viewBox%3D%220%200%20140%2056%22%20fill%3D%22none%22%3E%3Cpath%20d%3D%22M69%208C34%205%2010%2015%209%2027c-1%2013%2024%2022%2060%2021%2036-1%2062-10%2062-22C131%2014%20104%205%2063%208c-8%20.6-16%202-22%204%22%20stroke%3D%22%23FFD02B%22%20stroke-width%3D%224.5%22%20stroke-linecap%3D%22round%22/%3E%3C/svg%3E") center/100% 100% no-repeat;
  transform:rotate(-4deg);pointer-events:none}
@media(min-width:900px){.nav__links{display:flex}}

/* ---------- buttons ---------- */
.btn{display:inline-flex;flex-direction:column;align-items:center;gap:.25rem;text-decoration:none;
  padding:1.05rem 2.25rem;background:var(--green);color:var(--ink);
  font-family:var(--head);font-weight:900;text-transform:uppercase;letter-spacing:.03em;
  transform:skewX(-9deg);transition:.18s ease;position:relative}
.btn>*{transform:skewX(9deg)}
.btn__main{font-size:clamp(1.05rem,1.8vw,1.3rem);line-height:1.05}
.btn__sub{font-family:var(--body);font-weight:700;text-transform:none;letter-spacing:0;font-size:.85rem;opacity:.78}
/* Arrow before every button label. It was a pointing-hand emoji, which renders
   yellow and all but vanished against the green. This is a mask filled with
   currentColor rather than a coloured image, so it always matches the label —
   black on the green buttons, and correct automatically if a dark variant is
   ever used. A pseudo-element rather than markup so it applies to all six
   buttons at once, and so the submit button's "Sending…" textContent swap
   cannot wipe it out. */
.btn__main::before{content:"";display:inline-block;width:.78em;height:.78em;
  margin-right:.5em;vertical-align:-.04em;background:currentColor;
  -webkit-mask:var(--arrow) center/contain no-repeat;mask:var(--arrow) center/contain no-repeat}
/* Separation, depth and attention — on every button, at every width.
   RING: brand green measured 1.51:1 against the exhaust flame and 1.08:1
   against the falling invoices behind the hero CTA. A CTA wants 6-8:1. The
   near-black ring scores 7.4:1 and 10.3:1 against those same areas, so the
   button reads as an object rather than as part of whatever is behind it.
   SHADOWS: layered, not single — one blurred shadow reads as cheap; depth
   needs a tight shadow anchoring the button plus softer ambient ones. */
.btn{box-shadow:0 0 0 3px var(--deeper),
  0 2px 3px rgba(48,18,8,.42),0 8px 16px rgba(48,18,8,.5),0 20px 44px rgba(48,18,8,.42)}
.btn:hover,.btn:focus-visible{transform:skewX(-9deg) translateY(-3px);
  box-shadow:0 0 0 3px var(--deeper),
    0 3px 5px rgba(48,18,8,.45),0 12px 24px rgba(48,18,8,.52),0 26px 56px rgba(48,18,8,.45)}
.btn:focus-visible{outline:3px solid var(--yellow);outline-offset:4px}
/* A slow beacon: one ring expanding out of the button and fading. 2.6s, not
   the 150-250ms used for interaction feedback — a long duration reads as a
   calm glow, a short one reads as a notification badge nagging you. A
   pseudo-element so the ring can grow past the button without dragging the
   layered shadows along with it.
   Deliberately NOT gated behind prefers-reduced-motion: Janez has that setting
   on, and the same call was already made for the gear machine. Logged in
   Project Boss as a trade-off, not an oversight. */
.btn::after{content:"";position:absolute;inset:0;pointer-events:none;
  animation:ctaBeacon 2.6s cubic-bezier(.22,.61,.36,1) infinite}
@keyframes ctaBeacon{
  0%   {box-shadow:0 0 0 0 rgba(255,159,28,.5)}
  70%  {box-shadow:0 0 0 20px rgba(255,159,28,0)}
  100% {box-shadow:0 0 0 0 rgba(255,159,28,0)}
}
/* For use ON the bright green band, where a green button is the same colour as
   its background and reads as a shadow rather than a button. Near-black with a
   green ring, so it is unmistakably an object sitting on the green. */
.btn--dark{background:var(--deeper);color:var(--white);
  box-shadow:0 0 0 3px rgba(255,159,28,.55),
    0 2px 3px rgba(48,18,8,.3),0 8px 16px rgba(48,18,8,.35),0 20px 44px rgba(48,18,8,.3)}
.btn--dark:hover,.btn--dark:focus-visible{
  box-shadow:0 0 0 3px rgba(255,159,28,.85),
    0 3px 5px rgba(48,18,8,.35),0 12px 24px rgba(48,18,8,.4),0 26px 56px rgba(48,18,8,.35)}
/* The beacon is green on green here, so give it a dark ripple instead. */
.btn--dark::after{animation-name:ctaBeaconDark}
/* The X-Ray CTA. Deep azure — picked from a 20-option line-up. NOT green:
   every Free Roadmap button is green, and two different offers in one colour
   read as the same button. Azure is the only saturated colour on the page from
   a different temperature family entirely, which is exactly why it stops the
   eye. White text: azure is the one bright fill here that fails with ink. */
.btn--xray{background:#C1532B;color:#fff;
/* Grows to half again its size and back, forever. The keyframes carry the
   skew: .btn's identity transform is skewX(-9deg), and an animation REPLACES
   the transform property rather than composing with it — pulse without the
   skew and the button visibly straightens on the first frame.
   Hover kills the animation so the button holds still under the cursor —
   nobody wants to click a moving target — which also hands the transform back
   to the normal hover lift. */
  animation:xrayPulse 1.8s ease-in-out infinite}
.btn--xray:hover,.btn--xray:focus-visible{animation:none}
@keyframes xrayPulse{
  0%,100%{transform:skewX(-9deg) scale(1)}
  50%    {transform:skewX(-9deg) scale(1.5)}
}
/* On a phone the button is already most of the viewport wide, so half again
   its size pushes past the screen edge and adds sideways scroll. The pulse
   stays, the amplitude drops to 8% -- keyframes cannot be overridden inside a
   media query, so the phone swaps to its own animation. */
@media(max-width:640px){
  .btn--xray{animation-name:xrayPulseSm}
  @keyframes xrayPulseSm{
    0%,100%{transform:skewX(-9deg) scale(1)}
    50%    {transform:skewX(-9deg) scale(1.08)}
  }
}
.btn--xray::after{animation-name:ctaBeaconAzure}
@keyframes ctaBeaconAzure{
  0%   {box-shadow:0 0 0 0 rgba(0,119,255,.55)}
  70%  {box-shadow:0 0 0 20px rgba(0,119,255,0)}
  100% {box-shadow:0 0 0 0 rgba(0,119,255,0)}
}

@keyframes ctaBeaconDark{
  0%   {box-shadow:0 0 0 0 rgba(92,38,16,.55)}
  70%  {box-shadow:0 0 0 20px rgba(92,38,16,0)}
  100% {box-shadow:0 0 0 0 rgba(92,38,16,0)}
}

.hero__machine{position:absolute;inset:0;z-index:0;pointer-events:none;display:flex;align-items:center;justify-content:center}
.hero::after{content:"";position:absolute;inset:0;z-index:0;pointer-events:none;background:linear-gradient(100deg,var(--deep) 8%,rgba(122,52,24,.82) 38%,rgba(122,52,24,.25) 62%,transparent 85%)}
.hero__machine svg{width:118%;max-width:none;height:auto}

/* ---------- hero ---------- */
.hero{position:relative;isolation:isolate;padding:clamp(3rem,7vw,6rem) 0 clamp(5rem,10vw,9rem);
  background:radial-gradient(120% 90% at 78% 28%,rgba(255,159,28,.22),transparent 58%),var(--deep)}
/* The phone needs the rocket BETWEEN the headline and the button, so copy and
   CTA have to be separate grid items there. .hero__text is display:contents on
   small screens, which dissolves it and lets both become grid items in their
   own right; from 980px up it turns back into a real block and holds them in
   one column cell, which is the original markup exactly.
   Do not give the art its own row span on desktop instead — an item spanning
   two auto rows inflates them, which pushed the CTA 89px down the page. */
.hero__grid{position:relative;z-index:1;display:grid;gap:clamp(2.5rem,5vw,4rem);align-items:center;
  grid-template-areas:"copy" "art" "cta"}
.hero__text{display:contents}
.hero__copy{grid-area:copy}
.hero__cta{grid-area:cta}
.hero__art{grid-area:art}
/* Proportional, not fixed. The columns used to be `52rem 1fr`, so narrowing the
   window took every pixel off the image and none off the headline — the rocket
   collapsed to a stamp around 1100px while the copy did not move. 2.36fr:1fr is
   the same 832:352 split the fixed version produced at full width, so the wide
   view is unchanged, but now both sides give ground together. Breakpoints are
   for the structural switch to one column; sizing is fluid. */
@media(min-width:980px){.hero__grid{grid-template-columns:minmax(0,2.36fr) minmax(0,1fr);
    grid-template-areas:"text art"}
  .hero__text{display:block;grid-area:text}}
/* The rocket sits on top of the gear machine with no plate behind it — the png
   is already cut out, so anything drawn under it would show as a box. */
.hero__art{display:flex;justify-content:center;align-items:center}
/* --art-h is the one height every cut-out illustration on the page is sized
   by, so the hero rocket and the Chief-Everything-Officer atlas always match.
   It is redefined for the stacked and small layouts at the end of the sheet. */
:root{--art-h:min(80vh,52rem)}
.hero__art img{display:block;width:auto;max-width:100%;height:auto;max-height:var(--art-h)}
/* The headline column stays a full 52rem, which leaves the art track narrow.
   On wide screens let the art bleed into the empty page margin instead of
   taking width off the headline — shrinking the column rewraps h1 to 5 lines.
   Bounded so the bleed is always smaller than the margin: no sideways scroll. */
@media(min-width:1400px){.hero__art{margin-right:-2rem}}
@media(min-width:1600px){.hero__art{margin-right:-4rem}}
@media(min-width:1800px){.hero__art{margin-right:-8rem}}
.eyebrow{font-weight:900;font-size:.82rem;letter-spacing:.19em;text-transform:uppercase;color:var(--green);margin:0 0 1.1rem}
.hero h1{font-size:clamp(2.6rem,6.4vw,5.8rem);font-weight:900;text-wrap:balance;margin-bottom:1.4rem}
/* In the two-column layout the headline is sized against its OWN column, not
   the viewport, so it shrinks in step with the column as the window narrows.
   11.15cqw of the 832px column is 92.8px — identical to the old 5.8rem cap at
   full width. Only inside the media query: once stacked, the copy is full-width
   and a column-relative size would be far too large. */
.hero__copy{container-type:inline-size}
@media(min-width:980px){.hero h1{font-size:clamp(2.6rem,11.15cqw,5.8rem)}}
.hero p.lede{font-size:clamp(1.05rem,1.6vw,1.35rem);line-height:1.55;opacity:.9;max-width:54ch;margin:0 0 2.2rem}
/* The hero CTA runs ~30% larger than the shared .btn. Scoped to .hero so the
   header nav button and the popup's submit button keep their original size. */
.hero .btn{gap:.33rem;padding:1.37rem 2.93rem}
.hero .btn__main{font-size:clamp(1.37rem,2.34vw,1.69rem)}
.hero .btn__sub{font-size:1.1rem}
/* Social proof under the CTA: the cream pill of real client faces, lifted from
   nobsbusinesscoach.com with its baked-in green knocked out. Capped rather than
   full-width — at the copy column's full 52rem the faces get bigger than the
   headline's supporting role warrants. */
.proof{margin-top:2rem}
.proof img{display:block;width:100%;max-width:32rem;height:auto}

/* image slot */
.shot{position:relative;aspect-ratio:4/5;border:2px solid rgba(255,159,28,.45);background:
  repeating-linear-gradient(-45deg,rgba(255,159,28,.05) 0 12px,transparent 12px 24px),rgba(255,255,255,.03);
  display:grid;place-items:center;padding:1.5rem;text-align:center}
.shot::after{content:'';position:absolute;inset:-2px;border:2px solid var(--green);opacity:.25;transform:translate(12px,12px);pointer-events:none}
.shot__label{font-family:var(--head);font-weight:800;font-size:.72rem;letter-spacing:.14em;text-transform:uppercase;color:var(--green);opacity:.95}
.shot__note{font-size:.82rem;opacity:.62;margin-top:.6rem;line-height:1.45;max-width:30ch}

/* The assembly cube that used to sit here has been replaced by the GONE
   FISHING desk image. Its stage CSS, its loader and both JS files (the cube and
   its copy of three.js, 636 kB between them) are gone with it — all recoverable
   from git if it ever comes back. */

/* ---------- generic section heads ---------- */
.sechead{text-align:center;max-width:52rem;margin:0 auto clamp(2.5rem,5vw,4rem)}
.sechead h2{font-size:clamp(1.9rem,4.2vw,3.4rem);font-weight:900;text-wrap:balance;margin-bottom:1rem}
.sechead p{font-size:1.05rem;line-height:1.55;opacity:.82;margin:0}

/* ---------- bright band ---------- */
/* margin-BOTTOM only. This was margin-block, which set a -2px top margin that
   overrode .slant-t's pull-up and reopened the wedge. */
.band{background:var(--green);color:var(--ink);margin-bottom:-2px}
.band h2,.band h3{color:var(--ink)}
.band .sechead p{opacity:.78}

/* The AI-Powered vs Old Way comparison boxes were removed with the solution
   section rebuild; their .versus / .col styles went with them. The bullets
   survived for a while as a .wins list, which has now gone too — Janez cut the
   solution copy back to two paragraphs. Old markup is in git.
   .tick and .cross STAY — the Hustler vs Architect section still uses them. */
.tick,.cross{flex:none;width:1.4rem;height:1.4rem;display:grid;place-items:center;font-weight:900;font-size:.85rem;margin-top:.1rem}
.tick{background:var(--green);color:var(--ink)}
.cross{background:rgba(255,255,255,.14);color:rgba(255,255,255,.6)}

/* ---------- ladder ---------- */
/* ---------- Chief Everything Officer ----------
   Reads as the hero continuing rather than a new flat panel: it opens on the
   same --deep the hero ends on and darkens to --deeper, so there is no seam
   where one stops and the other starts. The green wash at the top carries the
   hero's glow down into it.
   Alternating background colour between sections is what gives a long page its
   rhythm; a gradient is worth using here — where it joins two sections — and
   not on the bright green band below, which is high-contrast by design. */
.ceo{position:relative;background:
  radial-gradient(120% 70% at 50% 0%,rgba(255,159,28,.13),transparent 62%),
  linear-gradient(180deg,var(--deep) 0%,var(--deeper) 72%)}
/* Faint engineering grid, echoing the hero's machine without competing with the
   illustration. Masked so it fades out before the section ends, which is what
   makes the darkening read as depth rather than as a flat second colour. */
.ceo::before{content:"";position:absolute;inset:0;pointer-events:none;
  background-image:
    repeating-linear-gradient(0deg,rgba(255,159,28,.05) 0 1px,transparent 1px 92px),
    repeating-linear-gradient(90deg,rgba(255,159,28,.05) 0 1px,transparent 1px 92px);
  -webkit-mask-image:linear-gradient(180deg,#000,transparent 76%);
          mask-image:linear-gradient(180deg,#000,transparent 76%)}
/* ::before is positioned, so without this the grid would paint over the copy. */
.ceo>.wrap{position:relative;z-index:1}

/* Art left, copy right on desktop — the mirror of the hero, which is the
   conventional alternating rhythm for stacked sections. The markup keeps the
   copy first so the stacked order is heading, paragraph, then image; grid
   areas do the swap, not source order. */
/* Label, headline and body stay together in one column. A full-width header
   spanning both columns was tried and reverted: it bought the headline two
   lines but detached it from the copy it belongs to, and it ran across the
   space the illustration occupies. Line count is not worth that. */
.ceo__grid{display:grid;gap:clamp(2rem,5vw,4rem);align-items:center;
  grid-template-areas:"head" "art" "body"}
/* STACKED ORDER IS HEADLINE, IMAGE, COPY — Janez's mobile order, matching the
   hero. The copy block dissolves (display:contents) so its two wrappers can
   take separate grid rows with the art between them; on desktop it becomes a
   normal single column again. The wrappers re-state .sechead's centring
   because display:contents throws the .sechead box away — inheritable
   text-align survives, but max-width and margin:auto do not. */
.ceo__copy{display:contents}
.ceo__head{grid-area:head}
.ceo__body{grid-area:body}
.ceo__head,.ceo__body{text-align:center;max-width:52rem;margin-inline:auto;width:100%}
/* .sechead carries a bottom margin for the centred layout; in a grid the gap
   already does that job, so it would double up. */
.ceo__copy{grid-area:copy;margin-bottom:0}
/* .sechead p has margin:0, which would run the two paragraphs together. */
.ceo__copy p+p{margin-top:1rem}
.ceo__cta{margin-top:1.9rem}
/* Section label — THE PROBLEM / THE SOLUTION.
   Janez asked for it BIGGER than the headline beneath it. Taken at face value
   that gives you two competing shouts and the headline stops being the
   headline, so it is bigger AND low-contrast: it reads as a printed marker
   behind the headline rather than as a second one. currentColor means it works
   on the dark section and the bright green band without a second rule. */
/* .sechead p already sets font-size and opacity, and it is one class more
   specific than a bare .kicker — so this has to be .sechead .kicker or the
   label silently renders as body copy. */
/* Half the size it was, and kept to a single line — at the old scale it
   competed with the headline instead of labelling it. */
.kicker{font-family:var(--head);font-weight:900;text-transform:uppercase;
  font-size:clamp(1.3rem,3.2vw,2.7rem);line-height:1;letter-spacing:-.02em;white-space:nowrap;
  color:currentColor;opacity:.28;margin:0 0 .55em}
/* Repeated at this specificity on purpose. .sechead p sets its own font-size
   and opacity and beats a bare .kicker, so inside a section head the label
   would silently render as body copy without this. Only the two properties
   that actually clash need repeating. */
.sechead p.kicker{font-size:clamp(1.3rem,3.2vw,2.7rem);opacity:.28}
/* The caps-and-yellow emphasis. box-decoration-break keeps the block intact
   when the phrase wraps across two lines. */
/* Painted as a sized background rather than a plain background colour. A plain
   one fills the whole inline box, which is TALLER than the line box — so on a
   headline that wraps, the yellow blocks on consecutive lines overlap by a few
   pixels and look like one solid slab. Sizing the gradient to 1.02em leaves a
   clean gap between them without needing huge leading. */
.mark{color:var(--ink);padding:0 .24em;
  background-image:linear-gradient(var(--yellow),var(--yellow));
  background-repeat:no-repeat;background-size:100% 1.02em;background-position:0 .13em;
  -webkit-box-decoration-break:clone;box-decoration-break:clone}
/* h1,h2,h3 run at line-height 1, which is far too tight once a headline is
   carrying highlight blocks. Size stays at the .sechead default — enlarging it
   inside a column just adds lines. 1.24 was too airy next to the hero, which
   effectively runs at 1; 1.1 leaves just enough room that the yellow blocks on
   consecutive lines sit apart without the headline looking double-spaced. */
.ceo__copy h2{line-height:1.1;
/* MUST be wrap — the plain greedy default. Neither of the other two values
   fills the line, and both were tried here:
     balance  evens out line lengths on purpose. Wrong by definition.
     pretty   is not "balance-lite". Chrome runs it as a paragraph-level
              optimiser that reduces raggedness, so it ALSO breaks early and
              leaves a hole at the right — which is what Janez spotted: "You're
              Still" and "The "Chief" both stopped with room for another word,
              turning a 3-line headline into 4.
   Only wrap fills each line to the edge before breaking. Set it explicitly:
   .sechead h2 sets balance, so leaving this out inherits the wrong value. */
  text-wrap:wrap}
/* Trademark mark: small, raised, and with the line-height zeroed so it cannot
   push the line it sits on. */
.tm{font-size:.5em;vertical-align:super;line-height:0;margin-left:.06em;font-weight:800}
/* The methodology name, wherever it appears in body copy. */
.mark--name{font-family:var(--head);font-weight:900;text-transform:uppercase;
  letter-spacing:.01em;color:var(--ink)}
/* Mirror of the problem section: copy left, cube right.
   Doubled-up class on purpose — a bare .ceo__grid--flip ties with .ceo__grid
   on specificity and loses on source order, so the flip silently did nothing. */
@media(min-width:980px){
  /* Art gets the wider share here, not the copy. The cube is square, so column
     width is the only thing that sets how big it can be. */
  .ceo__grid.ceo__grid--flip{grid-template-columns:minmax(0,1fr) minmax(0,1.15fr);
    grid-template-areas:"copy art"}
}
.ceoart{grid-area:art;display:flex;justify-content:center}
.ceoart img{display:block;width:auto;max-width:min(100%,90vw);height:auto;max-height:var(--art-h)}
@media(min-width:980px){
  .ceo__grid{grid-template-columns:minmax(0,1.15fr) minmax(0,1fr);
    grid-template-areas:"art copy"}
  .ceo__copy{display:block;grid-area:copy;text-align:left;max-width:none;margin:0}
  .ceo__head,.ceo__body{text-align:left;max-width:none;margin-inline:0}
  /* The grid gap used to separate headline from copy when they were separate
     rows; inside one column that job needs a real margin again. */
  .ceo__body{margin-top:1rem}
}

/* ---------- archetypes ---------- */
.arch{display:grid;gap:1.25rem}
@media(min-width:820px){.arch{grid-template-columns:1fr 1fr}}
.card{padding:clamp(1.5rem,3vw,2.4rem);background:var(--deep);color:var(--white);border-top:6px solid var(--green)}
.card--muted{border-top-color:rgba(255,255,255,.25);opacity:.92}
.card h3{font-size:1.35rem;font-weight:900;text-transform:uppercase;margin-bottom:1.1rem}
.card ul{list-style:none;margin:0;padding:0;display:grid;gap:.7rem;font-size:1rem;line-height:1.4}
.card li{display:flex;gap:.7rem}

/* ---------- proof ---------- */
.stats{display:grid;gap:1.25rem;text-align:center}
@media(min-width:700px){.stats{grid-template-columns:repeat(3,1fr)}}
.stat{padding:2rem 1rem;border:2px solid rgba(255,159,28,.3);background:rgba(255,159,28,.05)}
.stat b{display:block;font-family:var(--head);font-weight:900;font-size:clamp(2.4rem,5vw,3.6rem);color:var(--yellow);line-height:1}
.stat span{font-size:.9rem;text-transform:uppercase;letter-spacing:.1em;opacity:.8;font-weight:700}

/* ---------- testimonial coverflow ----------
   OUR OWN PLAYER since 2026-07-30 (Voomly removed at Janez's call — its
   engine cost ~6.8s of CPU for nine embeds). Each card is a plain <video>
   with a self-hosted poster and preload="none": zero video bytes until
   someone presses play. The front card runs a tiny muted preview loop — the
   moving thumbnail. Everything below about geometry and timing is unchanged
   from the signed-off Option A mockup. */
/* The cards are absolutely positioned from the centre and spread outwards, so
   the outer ones run past the text column. This wrapper takes the section out
   to the full wrap width and clips there — which both stops them adding 69px
   of horizontal scroll (body's overflow-x:hidden is not reliable on iOS) and
   gives the side cards the run-off-the-edge look. The clip is a separate
   element from .cf on purpose: overflow and perspective on the same box is
   where 3D rendering gets flaky. */
.cf__clip{overflow:hidden;margin-inline:calc(var(--pad) * -1)}
/* Geometry and timing below are lifted verbatim from the Option A mockup —
   perspective, card width, the .55s cubic-bezier, the border and active
   shadow. Do not "tidy" these numbers; the motion was signed off as-is. */
.cf{position:relative;height:clamp(340px,46vw,540px)}
.cf:focus-visible{outline:3px solid var(--yellow);outline-offset:6px}
.cf__stage{position:absolute;inset:0;transform-style:flat}
/* Flat and stacked until the script fans them out. The players measure
   themselves on mount, and a card rotated in 3D reports its PROJECTED width —
   far narrower than its real one — so a player that mounts while its card is
   already turned lays itself out tiny and stays that way. Mounting them square
   on is the whole fix. */
.cf{transition:opacity .45s ease}
.cf__card{position:absolute;top:50%;left:50%;margin:0;width:clamp(190px,22vw,280px);aspect-ratio:4/5;
  transform:translate(-50%,-50%);
  transform-origin:50% 50%;transition:transform .55s cubic-bezier(.22,.61,.36,1),opacity .55s,filter .55s;
  background:var(--deeper);border:2px solid rgba(255,159,28,.25);overflow:hidden;
  display:grid;place-items:center;will-change:transform}
/* The card's own player. Sources are 720x900 — the card's exact 4:5 — so
   object-fit:cover crops nothing. The preview loop sits over the poster and
   under the play badge; only the front card shows it (one decoder, not nine).
   The play badge reuses the film pill's round language. */
.cf__card .tmv{width:100%;height:100%;object-fit:cover;display:block;background:var(--deeper)}
.tmv__loop{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;pointer-events:none}
.cf__card:not(.cf__card--active) .tmv__loop{display:none}
.tmv__play{position:absolute;left:50%;top:50%;transform:translate(-50%,-50%);
  width:64px;height:64px;border:0;border-radius:999px;cursor:pointer;
  display:grid;place-items:center;background:var(--btn);color:var(--ink);
  box-shadow:0 10px 30px rgba(0,0,0,.45);transition:transform .18s ease}
.tmv__play svg{width:26px;height:26px;margin-left:3px}
.cf__card--active .tmv__play:hover{transform:translate(-50%,-50%) scale(1.08)}
.cf__card--active{border-color:var(--green);box-shadow:0 0 0 3px var(--deeper),0 30px 70px rgba(0,0,0,.6)}
/* Only the card in front is interactive. Without this, a click meant for a
   card at the side would hit the player rotated away behind it and start a
   video nobody can see. */
.cf__card:not(.cf__card--active) .tmv,
.cf__card:not(.cf__card--active) .tmv__play{pointer-events:none}
.cf__ctrls{display:flex;gap:.6rem;justify-content:center;align-items:center;margin-top:clamp(1.25rem,3vw,2rem)}
.cf__ctrl{width:54px;height:54px;display:grid;place-items:center;cursor:pointer;color:#fff;
  background:rgba(255,255,255,.06);border:2px solid rgba(255,159,28,.35);
  font-family:var(--head);font-weight:900;font-size:1.2rem;transition:.18s ease}
.cf__ctrl:hover{background:var(--green);color:var(--ink);border-color:var(--green)}
.cf__ctrl:focus-visible{outline:3px solid var(--yellow);outline-offset:3px}
.cf__dots{display:flex;gap:.45rem;margin:0 .7rem}
.cf__dot{width:9px;height:9px;padding:0;border:0;cursor:pointer;background:rgba(255,255,255,.25);transition:.18s ease}
.cf__dot[aria-current="true"]{background:var(--green);transform:scale(1.35)}
@media(max-width:640px){
  .cf{height:clamp(330px,88vw,430px)}
  .cf__card{width:clamp(180px,52vw,240px)}
}

/* ---------- about ---------- */
/* Stacked: headline, photo, copy — the same order as every other section —
   and centred. The copy wrapper dissolves so its head and body take separate
   grid rows with the photo between them; desktop puts the column back. */
.about{display:grid;gap:clamp(2rem,5vw,4rem);align-items:center;
  grid-template-areas:"head" "art" "body"}
.about__copy{display:contents}
.about__head{grid-area:head;text-align:center}
.about__body{grid-area:body;text-align:center}
.about .frame{grid-area:art}
@media(min-width:980px){
  .about{grid-template-columns:.85fr 1.15fr;grid-template-areas:"copy art"}
  .about__copy{display:block;grid-area:copy}
  .about__head,.about__body{text-align:left}
}
.about p{font-size:1.08rem;line-height:1.6;opacity:.88}
.about__body p+p{margin-top:1rem}
/* Photo frame. Borrows the offset green outline from .shot further up so it is
   the same device the page already uses, rather than a second frame style.
   The outline is a pseudo-element so it can sit OUTSIDE the picture without a
   wrapper and without eating into it. */
.frame{position:relative;margin:0}
.frame img{display:block;width:100%;height:auto;border:2px solid rgba(255,159,28,.45)}
.frame::after{content:'';position:absolute;inset:0;border:2px solid var(--green);
  opacity:.25;transform:translate(14px,14px);pointer-events:none}
/* Stacked, the offset frame would push against the section edge, and the photo
   comes after the copy in source order — which is the right reading order but
   puts a big image between the text and its button. Above the fold of the
   column layout neither applies. */
@media(max-width:979px){.frame::after{display:none}}

/* ---------- final cta ---------- */
.final{text-align:center;background:radial-gradient(90% 120% at 50% 0%,rgba(255,159,28,.2),transparent 60%),var(--deeper)}
.final h2{font-size:clamp(2.1rem,5.2vw,4rem);font-weight:900;margin-bottom:1.2rem;text-wrap:balance}
/* The lead magnet itself, shown above the button so the offer is a THING
   before it is a promise. Capped at 560px because that is the widest it is
   ever drawn — the file is 1139px, which is exactly 2x that for retina and
   not a pixel more. */
.lmshot{display:block;width:100%;max-width:560px;height:auto;margin:0 auto 2.2rem}

/* ---------- footer ---------- */
footer{background:var(--deeper);padding:3rem 0 2rem;font-size:.88rem}
.foot{display:flex;flex-wrap:wrap;gap:1.5rem 3rem;justify-content:space-between;align-items:center;opacity:.6}
/* Padding + matching negative margin: the links LOOK exactly where they were,
   but the tap target grows past the 24px Lighthouse floor. */
.foot a{color:var(--white);text-decoration:none;margin-right:1.25rem;
  display:inline-block;padding:.5rem .45rem;margin:-.5rem .8rem -.5rem -.45rem}
.foot a:hover{color:var(--green)}
@media(prefers-reduced-motion:reduce){*{transition:none!important}
  /* The carousel's glide is the whole point of the pattern Janez signed off —
     with the blanket rule above it snaps between cards instead. He has this OS
     setting turned ON, so the rule would have taken the smooth movement away
     on the exact machine it was approved on. Same call the gear machine
     already made: this site does not honour reduced-motion for its signature
     animation. Logged in Project Boss. */
  .cf__card{transition:transform .55s cubic-bezier(.22,.61,.36,1),opacity .55s,filter .55s!important}}

/* ---------- opt-in popup ---------- */
/* WHY THE POPUP TEXT WAS BLACK ON DARK GREEN. Not a missing colour on our
   side — <dialog> is one of the few elements the browser gives its OWN colour
   (CanvasText, i.e. black), and that beats the white inherited from body. Only
   the bits with an explicit colour survived: .hl is yellow, the field labels
   are green, the inputs are #fff. Everything else went black on near-black.
   Setting colour on the dialog fixes the whole subtree at once. */
dialog#optinModal{border:0;padding:0;background:transparent;max-width:min(92vw,560px);color:var(--white)}
dialog#optinModal::backdrop{background:rgba(70,28,12,.84);backdrop-filter:blur(6px)}
.om{background:var(--deep);border:2px solid var(--green);padding:clamp(1.6rem,4vw,2.3rem);position:relative;box-shadow:0 30px 90px rgba(0,0,0,.65)}
.om h3{font-family:var(--head);font-size:clamp(1.4rem,3.4vw,1.85rem);font-weight:900;line-height:1.1;margin:0 0 1.6rem;text-wrap:balance;text-align:center}
/* The lead magnet replaces the sub-paragraph — showing it beats describing it.
   Never drawn wider than ~466px here (560 dialog less its padding), so the
   file is 900px: 2x for retina, and a separate smaller file from the one in
   the page so the popup is not made to carry the big one's bytes. */
.om__shot{display:block;width:100%;height:auto;margin:0 0 1.3rem}
.of{display:block;margin-bottom:.9rem}
.of span{display:block;font-size:.7rem;font-weight:900;letter-spacing:.14em;text-transform:uppercase;color:var(--green);margin-bottom:.35rem}
.of input{width:100%;padding:.85rem .95rem;background:rgba(255,255,255,.06);border:2px solid rgba(255,255,255,.15);color:#fff;font-family:var(--body);font-size:1rem}
.of input:focus{outline:0;border-color:var(--green);background:rgba(255,159,28,.07)}
.om button[type=submit]{width:100%;margin-top:.4rem}
.ox{position:absolute;top:.5rem;right:.7rem;background:0;border:0;color:#fff;opacity:.5;font-size:1.6rem;cursor:pointer;line-height:1}
.ox:hover{opacity:1;color:var(--green)}
/* Cream rather than white-at-45%: on the near-black panel a dimmed white goes
   grey and dead, where a warm off-white stays legible while still sitting
   behind the button in the hierarchy. */
.ofine{font-size:.76rem;color:var(--cream);opacity:.72;margin:.9rem 0 0;text-align:center}
.oerr{color:#ff8f7a;font-size:.86rem;margin:.5rem 0 0;min-height:1.1em}
.ohp{position:absolute;left:-9999px;width:1px;height:1px;opacity:0}

/* ---------- stacked hero ----------
   These two blocks live at the very END of the stylesheet on purpose. The hero
   rules above them have the same specificity, so anywhere earlier and they win:
   placing them next to .hero__art silently lost the h1 font-size while keeping
   its line-height, which is a confusing half-applied result.

   They are split by WHY, not by size. This first block is everything that is
   true because the layout has STACKED — it therefore starts at the same 979px
   the columns collapse at. Getting these two thresholds out of step is exactly
   what left 641–979px stacked but still left-aligned with the button stranded
   below the image. If a rule answers "the art is now above the copy", it
   belongs here; if it answers "the screen is small", it belongs below. */
@media(max-width:979px){
  :root{--art-h:56vh}
  .hero{--hero-gap:clamp(2.5rem,5vw,4rem)}
  .hero__grid{row-gap:var(--hero-gap)}
  .hero__art img{max-height:var(--art-h)}

  /* Centred because the rocket is no longer beside the copy but above it, and
     centred copy is the convention once the visual sits over rather than next
     to the text. The two-column layout stays left-aligned. */
  .hero__copy{text-align:center}
  .proof img{margin-inline:auto}

  /* The CTA rides up over the bottom 24% of the illustration. Measured, not
     guessed: the rocket body and figure end at 64% of the image height and the
     flames at 84%, so a 24% overlap covers every invoice, the keyboard and the
     lower flames while leaving the flame roots reading as thrust. The negative
     margin has to absorb the grid row-gap as well as the overlap itself. */
  .hero__cta{display:flex;flex-direction:column;align-items:center;
    position:relative;z-index:2;margin-top:calc(-0.24 * var(--art-h) - var(--hero-gap))}

}

/* ---------- small screens ----------
   Everything here exists to buy vertical space so the eyebrow, headline,
   rocket and button all clear the phone fold: a half-height logo with no nav
   button, smaller type, and the lede paragraph dropped (the same argument is
   made again in the sections further down the page). Nothing here is about
   the layout having stacked — that is the block above. */
@media(max-width:640px){
  .nav__in{padding-block:.5rem}
  .logo{font-size:.92rem}
  .nav .btn{display:none}
  :root{--art-h:min(46vh,28rem)}
  .hero{padding-top:2rem;padding-bottom:2.5rem;--hero-gap:1.5rem}
  /* The gears read as noise behind a cut-out illustration at this size, and
     they cannot be anchored to the art without hard-coding pixel offsets. */
  .hero__machine{display:none}
  .eyebrow{font-size:.66rem;letter-spacing:.12em;margin-bottom:1.1rem}
  .hero h1{font-size:2.2rem;line-height:1.06;margin-bottom:0}
  .hero p.lede{display:none}
  .hero__art img{max-width:72vw}
  .proof{margin-top:1.2rem}
  .hero .btn{padding:.85rem 1.8rem}
  .hero .btn__main{font-size:1.02rem}
  .hero .btn__sub{display:none}
  /* No CTA in the PROBLEM section on phones — it is already a full screen
     there and the hero CTA is one scroll away. Scoped to .ceo on purpose: the
     solution section reuses .ceo__cta and its button should stay, since that
     is the point of the section. */
  .ceo .ceo__cta{display:none}
}

/* ---------- Business X-Ray teaser (homepage) ----------
   Three facts in a row: length, price, cap. Deliberately the same shape as the
   facts strip on /business-xray so the page and the section read as one offer
   rather than two. */
/* Inherits the body --deep on purpose. The green band sits above and the
   --deeper testimonials below; giving this --deeper too would merge it with
   the testimonials into one flat dark slab. */
.xray{background:var(--deep)}
/* Down to TWO cells (the 5-a-week box was cut), so the columns must be two as
   well — a repeat(3) grid with two children leaves an empty third track showing
   the border colour as a dead cell. */
.xray__row{display:grid;gap:1px;background:none;border:2px dashed rgba(255,159,28,.5);
  grid-template-columns:1fr;max-width:34rem;margin:2rem auto 0}
@media(min-width:560px){.xray__row{grid-template-columns:repeat(2,1fr)}}
/* The session photo, centred under the headline like the roadmap image in the
   final section — same 560px cap, so the two read as one device. */
/* Tight above, and half the old gap below. Most of what read as "space above
   the image" was 156px of flat green baked INSIDE the file by the render's
   framing margins — cropped out now — so these margins are the real spacing.
   The section head's default bottom margin is far too generous once the image
   is the very next thing. */
.xray .sechead{margin-bottom:clamp(.7rem,1.2vw,1rem)}
.xrayshot{display:block;width:100%;max-width:560px;height:auto;margin:0 auto clamp(1rem,2vw,1.4rem)}
.xray__copy{max-width:46rem;margin:0 auto;text-align:center;font-size:1.06rem;line-height:1.6;opacity:.87}
.xray__copy p+p{margin-top:1rem}
.xray__fact{background:var(--deeper);padding:1.3rem 1rem;text-align:center}
.xray__fact b{display:block;font-family:var(--head);font-weight:900;font-size:1.6rem;color:var(--green);line-height:1}
.xray__fact span{display:block;font-size:.85rem;opacity:.75;margin-top:.4rem}

/* ---------- THE VIDEO SECTION ----------
   The card is pulled up out of its own section by --bridge so it overlaps the
   blue band above: top half on blue, bottom half on dark. Three things make
   that work rather than look like a mistake:
     1. the Solution band grows its bottom padding by the SAME --bridge, so the
        desk illustration never collides with the video (Janez's note: "this is
        too high, it's almost touching the table");
     2. the card is LIT — see .vidstage::before — and carries layered shadows,
        which is what sells "floating above two sections" rather than "clipped
        by one". A flat rectangle on a seam just looks like a mistake;
     3. --bridge is a clamp, so on a phone the overlap shrinks and the card
        stops trying to span a seam only a few hundred px wide.
   z-index is explicit: .band and .slant-t both create stacking contexts, and
   without it the card can end up UNDER the blue instead of over it. */
/* Bigger than it looks like it needs to be, on purpose. rotateX(4deg) tips the
   frame's top edge away from the viewer and perspective foreshortens it, so the
   frame's VISUAL top lands roughly 50px below its layout top — at the old
   value the card sat entirely inside the dark section and the bridge the whole
   idea depends on simply was not visible. */
/* The film's own height, derived rather than guessed: 16:9 of the stage width
   plus the black border above and below it. Everything about the seam is
   measured from this, so the geometry holds at every viewport instead of only
   at the width it was eyeballed on. */
:root{
  --vidw:min(960px,100vw - (2 * var(--pad)));
  --vidh:calc(var(--vidw) * 0.5625 + 52px);
  /* How much of the section's foot is dark. Two thirds of the film plus the
     padding under it — which puts the colour change one third of the way down
     the film, where Janez asked for it: crossing the picture, nearer the top
     than the middle. */
  --darkrun:calc((var(--vidh) * 0.67) + clamp(3rem,6vw,5rem));
}
#new{position:relative;padding-bottom:clamp(3rem,6vw,5rem)}
/* The dark ground, drawn INSIDE the blue section along its bottom edge. This
   is the "second section" the film straddles — except it is the same section,
   so the join cannot drift. It is also why the film no longer needs a negative
   margin at all. */
#new::after{content:"";position:absolute;left:0;right:0;bottom:0;z-index:0;
  height:var(--darkrun);background:var(--b3)}
#new > .wrap{position:relative;z-index:2}
.vidhold{margin-top:clamp(2.5rem,6vw,5rem)}
.vidstage{position:relative;z-index:3;max-width:var(--vidw);
  margin:0 auto;perspective:1700px}
/* NO filter on this element. filter forces transform-style:flat on an
   element's children, which would collapse every segment below back onto one
   plane and destroy the curve — the same rule that broke the plate/video
   stacking earlier. The shadow therefore lives on .vidstage::after, which is
   outside the 3D context. */
.vidtilt{position:relative;transform:rotateY(-11deg) rotateX(3deg);transform-style:preserve-3d}
.vidstage::after{content:"";position:absolute;left:6%;right:6%;bottom:-14px;height:44px;
  background:rgba(0,0,0,.5);filter:blur(26px);z-index:-1;pointer-events:none}
.vidcard{display:block;width:100%;padding:0;border:0;cursor:pointer;background:none;
  position:relative;height:var(--vidh);transform-style:preserve-3d}
.vidcard:focus-visible{outline:3px solid var(--yellow);outline-offset:10px}
/* The two segment strips, stacked in the same 3D space. */
.film,.fplate{position:absolute;inset:0;display:flex;transform-style:preserve-3d}
.fplate{transform:translate(26px,26px) translateZ(-40px)}
.fs,.ps{position:relative;flex:0 0 auto;height:100%;
  /* Each slice is exactly one Nth of the film WIDE, plus a bleed that is
     pulled back out again with a negative margin, so the row still totals
     exactly --vidw. The bleed has to beat the worst-case gap: a slice turned
     by ANGLE projects cos(ANGLE) as wide as it lays out, losing about 7% at
     22 degrees — on a 36px slice that is ~2.6px, which a 2px bleed did not
     cover, and the aqua plate showed through as hairlines at the steepest
     slices. 6px clears it with room to spare. Over-bleeding costs nothing now
     that the background is addressed in absolute pixels: the extra is real
     adjacent picture, not a magnified copy. */
  width:calc((var(--vidw) / 26) + 6px);margin-right:-6px;
  transform:translateZ(var(--z)) rotateY(var(--ry))}
/* The slice addresses the poster in ABSOLUTE pixels, and this is the whole
   difference between a curve that looks right and the one that did not.
   The previous attempt closed the gaps with scaleX(1.16). But background-size
   was a percentage OF THE ELEMENT, so scaling the element magnified its
   background too: every slice showed ~16% of its neighbour's picture, blown up
   by 16%. That is exactly what Janez saw — the shirt and arm repeating at the
   joins, and soft, resampled edges.
   Here background-size is the FULL film width in px and the position is a
   negative px offset, so a slice shows precisely its own sixteenth of the
   poster at 1:1 — no magnification, nothing resampled, nothing repeated. The
   only overlap is the 2px bleed above, which is real adjacent picture. */
.fs{background-image:url(img/video-poster.webp);
  background-size:var(--vidw) 100%;background-repeat:no-repeat;
  background-position:calc(-1 * var(--i) * var(--vidw) / 26) center;
  border-top:26px solid #2A1208;border-bottom:26px solid #2A1208}
.ps{background:var(--btn)}
/* One sprocket hole per segment, sitting IN that segment's own black border —
   so a hole is part of the curved surface and travels with it. */
.fs::before,.fs::after{content:"";position:absolute;left:50%;translate:-50% 0;
  width:64%;max-width:22px;height:13px;border-radius:3px;background:#e8ecf2;
  box-shadow:inset 0 1px 2px rgba(0,0,0,.4)}
.fs::before{top:-19px}
.fs::after{bottom:-19px}
/* The glow has to be its own element: putting a box-shadow on the segments
   would draw eighteen separate glows, one per slice. */
.vidstage::before{content:"";position:absolute;inset:-8% -5%;z-index:-1;pointer-events:none;
  background:radial-gradient(56% 52% at 52% 52%,var(--btnglow),transparent 72%);
  filter:blur(30px)}
/* Pushed well forward so it rides above the deepest part of the curve, and
   turned with the right-hand edge so it sits ON the surface rather than
   floating flat in front of it. */
.vidtag{position:absolute;right:-4px;top:-20px;background:var(--yellow);color:var(--ink);
  font-family:var(--head);font-weight:900;font-size:.68rem;letter-spacing:.18em;
  text-transform:uppercase;padding:.45em .95em;
  transform:translateZ(30px) rotateY(-14deg);
  box-shadow:0 8px 18px rgba(0,0,0,.45)}
/* ---- the play control ----
   left is 53.5%, not 50%: under rotateY(-14deg) the near edge is magnified and
   the far edge compressed, so the frame's OPTICAL centre sits right of its
   geometric centre. At a true 50% the control reads as off to the left.
   The motion is a conic-gradient sweep travelling around the pill's rim. It is
   a rotating BACKGROUND behind an opaque face rather than an animated border,
   because border-image cannot be animated and a spinning pseudo-element at a
   negative z-index would paint above its parent's own background. */
.vidplay{position:absolute;left:53.5%;top:50%;
  transform:translate(-50%,-50%) translateZ(60px);
  padding:4px;border-radius:999px;overflow:hidden;line-height:1;
  box-shadow:0 16px 38px rgba(0,0,0,.5);transition:transform .25s ease}
.vidplay::before{content:"";position:absolute;inset:-60%;
  background:conic-gradient(from 0turn,transparent 0 58%,rgba(255,255,255,.95) 76%,transparent 90%);
  animation:vidSweep 2.6s linear infinite}
@keyframes vidSweep{to{transform:rotate(1turn)}}
.vidplay__face{position:relative;display:flex;align-items:center;gap:.6rem;
  border-radius:999px;background:var(--btn);color:var(--ink);
  padding:.85rem 1.5rem .85rem 1.15rem;
  font-family:var(--head);font-weight:900;font-size:.92rem;letter-spacing:.1em;
  text-transform:uppercase}
.vidplay__face svg{width:19px;height:19px;flex:none}
.vidplay__face i{font-style:normal;font-weight:800;opacity:.62;letter-spacing:.04em}
.vidcard:hover .vidplay,.vidcard:focus-visible .vidplay{transform:translate(-50%,-50%) translateZ(60px) scale(1.06)}
/* The caption sits on the dark ground under the card, small and quiet — the
   card is the whole point of the section, so nothing here competes with it. */
.vidcap{margin:2.6rem auto 0;text-align:center;font-size:.95rem;opacity:.6}
.ocavid{display:block;width:100%;aspect-ratio:16/9;height:auto;background:#000}
/* ---------- THE PLAYER DIALOG ----------
   Flat, deliberately: the film keeps its curve and its turn on the page, and
   the dialog is where the video actually has to be watchable. Same film strip
   so it reads as the same object opening up, but nothing tilted, nothing
   clipped, nothing for the picture to fight. */
.vmodal{border:0;padding:0;background:transparent;max-width:min(1100px,92vw);width:100%;
  color:#fff;overflow:visible}
.vmodal::backdrop{background:rgba(3,14,28,.86);backdrop-filter:blur(6px)}
.vmodal__reel{position:relative;background:#2A1208;padding:0 12px;
  box-shadow:0 0 0 3px var(--btn),0 0 80px var(--btnglow),0 40px 90px rgba(0,0,0,.7)}
/* The dialog's sprocket strips. These are their own rules rather than shared
   with the inline film: the inline one is 26 curved segments each carrying a
   single hole, which has no meaning on a flat player. The classes were shared
   at first and the holes silently vanished from the popup the moment the
   inline frame was rebuilt — same markup, styling deleted from under it. */
.vmodal__reel .vidperf{display:flex;height:26px;align-items:center;
  justify-content:space-between;padding:0 2px}
.vmodal__reel .vidperf i{flex:0 0 20px;height:13px;border-radius:3px;background:#e8ecf2;
  box-shadow:inset 0 1px 2px rgba(0,0,0,.4)}
@media(max-width:640px){
  .vmodal__reel .vidperf{height:18px}
  .vmodal__reel .vidperf i{flex-basis:13px;height:9px}
}
.vmodal__screen{position:relative;background:#000;aspect-ratio:16/9}
.vmodal__screen video{position:absolute;inset:0;width:100%;height:100%}
.vmodal__x{position:absolute;top:-46px;right:0;width:38px;height:38px;line-height:1;
  border:0;cursor:pointer;background:var(--btn);color:var(--ink);
  font-size:1.5rem;font-weight:900;font-family:var(--head)}
.vmodal__x:hover{transform:scale(1.08)}
@media(max-width:640px){.vmodal__reel{padding:16px 8px}.vmodal__x{top:-42px}}
@media(max-width:760px){
  /* The turn costs picture width, which a phone cannot spare — and a 14° twist
     on a 340px-wide frame reads as a rendering fault rather than as depth. */
  .vidtilt{transform:none}
  .vidplay{left:50%}
  .vidplay__face{font-size:.78rem;padding:.7rem 1.1rem .7rem .85rem}
  .vidcard{padding:18px 8px}
  .vidperf{height:18px}.vidperf i{flex-basis:13px;height:9px}
}

/* ---------- OCA: the clickable layer ----------
   --btn is the one colour on this page that means "press me". --btnglow is the
   same colour at low alpha, used behind the video card. */
:root{--btn:#FF9F1C;--btnglow:rgba(255,159,28,.5);--blue:#E8834A}
.btn{background:var(--btn);color:var(--ink)}
/* ---------- the bright bands take the LOGO blue, not the accent ----------
   And their text flips to white, which is a contrast call rather than a taste
   one: #E8834A sits at 0.180 relative luminance, so the near-black ink the
   band inherited scores 4.02:1 against it — under the 4.5:1 floor for body
   text. White scores 4.56:1 and passes. The yellow .mark highlights keep dark
   ink because they sit on yellow, not on the blue. */
.band{background:var(--blue);color:var(--white)}
.band .mark{color:var(--ink)}
/* The beacon ring must be the BUTTON's colour, not the brand's — the base
   stylesheet hard-codes the brand into these keyframes, so it has to be
   restated or the ring pulses in a colour the button no longer is. */
@keyframes ctaBeacon{
  0%   {box-shadow:0 0 0 0 rgba(255,159,28,.5)}
  70%  {box-shadow:0 0 0 20px rgba(255,159,28,0)}
  100% {box-shadow:0 0 0 0 rgba(255,159,28,0)}
}
/* .btn--dark is the variant used ON the bright band, where a button in the
   button colour would vanish into its own background. Its ring follows --btn
   for the same reason the beacon does. */
.btn--dark{background:var(--deeper);color:var(--white);
  box-shadow:0 0 0 3px var(--btn),
    0 2px 3px rgba(48,18,8,.42),0 8px 16px rgba(48,18,8,.5),0 20px 44px rgba(48,18,8,.42)}
.btn--dark:hover,.btn--dark:focus-visible{
  box-shadow:0 0 0 3px var(--btn),
    0 3px 5px rgba(48,18,8,.45),0 12px 24px rgba(48,18,8,.52),0 26px 56px rgba(48,18,8,.45)}
/* The X-Ray CTA keeps Upscalum's exact azure and its white text — azure is the
   one bright fill on either site that fails against dark ink. */
.btn--xray{background:#C1532B;color:#fff}

/* ---------- OCA: the drawn logo replaces the type wordmark ---------- */
.logo{display:flex;align-items:center;line-height:0}
.logo img{display:block;height:46px;width:auto}
.logo--foot img{height:56px}
@media(max-width:640px){.logo img{height:38px}}

/* ---------- the blue scale ---------- */
:root{
  --b1:#C1532B;  /* lifted navy — top of a dark section */
  --b2:#A4431E;  /* mid */
  --b3:#8C3A1B;  /* base dark; the body colour, so slant reveals match it */
  --b4:#6B2A11;  /* deepest */
}
/* ---- THE SEAM RULE ----
   Every gradient below starts AND ends on --b3, and the body is --b3 too. That
   is not a stylistic choice, it is what makes the diagonal seams work.
   .slant clips a triangle out of each section's top-right and bottom-left
   corners, and what shows through the cut is the BODY. While every dark
   section was one flat colour identical to the body, that reveal was
   invisible. The first version of this gradient ran --b1 → --b3 top to bottom,
   so a section's edges no longer matched the body — and a 48px stripe of body
   colour (3.5vw, exactly the slant's depth) appeared along every seam.
   Pinning both ends of the ramp to the body colour makes the cut reveal the
   same value the section already had there, so the wedge cannot exist. The
   light now peaks in the MIDDLE of each section rather than at its top, which
   reads as a soft spotlight per section and keeps the seams clean.
   Same reason the radial glows are held away from the edges: anything bright
   touching 0% or 100% would reintroduce the mismatch it is there to avoid. */
body{background:var(--b3)}
.section{
  background-color:var(--b3);
  background-image:
    radial-gradient(rgba(255,255,255,.055) 1px,transparent 1px),
    radial-gradient(78% 34% at 50% 44%,rgba(255,159,28,.10),transparent 72%),
    radial-gradient(62% 30% at 86% 34%,rgba(232,131,74,.32),transparent 74%),
    linear-gradient(180deg,var(--b3) 0 6%,var(--b1) 34%,var(--b2) 68%,var(--b3) 96% 100%);
  background-size:28px 28px,auto,auto,auto;
  background-repeat:repeat,no-repeat,no-repeat,no-repeat}
/* The bright band keeps the logo blue as its anchor but stops being flat:
   a lighter blue at the top-left falling to a deeper one bottom-right, so it
   has the same sense of a light source as the dark sections do. */
.band{background-color:var(--blue);
  background-image:
    radial-gradient(rgba(255,255,255,.07) 1px,transparent 1px),
    radial-gradient(75% 60% at 12% 0%,rgba(255,255,255,.22),transparent 66%),
    linear-gradient(158deg,#FFA468 0%,var(--blue) 52%,#B04A22 100%);
  background-size:28px 28px,auto,auto;
  background-repeat:repeat,no-repeat,no-repeat}
/* The hero keeps its own gear machine, so it only gets the lift and the glow —
   a dot grid on top of the gears would be two textures fighting. */
.hero{background-color:var(--b3);
  background-image:
    radial-gradient(72% 42% at 78% 40%,rgba(232,131,74,.34),transparent 74%),
    radial-gradient(60% 34% at 10% 72%,rgba(255,159,28,.10),transparent 74%),
    linear-gradient(180deg,var(--b3) 0 5%,var(--b1) 36%,var(--b2) 70%,var(--b3) 96% 100%)}
/* The video section is a continuation of the band above it, not a new slab —
   it starts where the band's gradient ended so the seam reads as one fall of
   light rather than two unrelated colours meeting. */
.vidsec{background-image:
  radial-gradient(rgba(255,255,255,.055) 1px,transparent 1px),
  radial-gradient(66% 40% at 50% 34%,rgba(255,159,28,.14),transparent 72%),
  linear-gradient(180deg,var(--b3) 0 5%,var(--b2) 34%,var(--b3) 96% 100%);
  background-size:28px 28px,auto,auto}
/* NO background on .foot. It looks like a section and is not: .foot is the
   flex ROW of links inside the footer, and it carries opacity:.6. Painting a
   background on it drew a lighter slab the width of the wrap's max-width,
   inset from both page edges — the "random buffer" around the footer. The
   footer's ground comes from the section that contains it, as on Upscalum. */

/* ---------- THE TOP TWO SECTIONS + TESTIMONIALS ----------
   Copied off the four-scheme build, because those three are the ones Janez
   picked out of it. Measured from that render rather than from the CSS I
   thought I wrote — the hero read #072342 and the section under it a flat
   #B04A22, and that flatness is the point: the reverted build's #problem ramps
   down to #8C3A1B at both ends, which is what made it merge with its
   neighbours.
   #problem also switches to the slant-t mechanism. Its .slant clip reveals the
   BODY, so with a colour of its own it would show a stripe of body colour
   along the join — the wedge again. slant-t pulls it up over the hero and
   clips its own top edge instead, so the diagonal reveals the HERO. One hard
   line between two different colours, which is the border he asked to match. */
#problem{
  margin-top:calc(-3.5vw - 2px);
  clip-path:polygon(0 0,100% 3.5vw,100% 100%,0 100%);
  background:linear-gradient(176deg,#CC5A2F 0%,#B04A22 55%,#9E4420 100%)}
#proof{background:linear-gradient(168deg,#FF9455 0%,#E8834A 52%,#A4431E 100%) !important}
/* Every remaining join moves to the slant-t mechanism too.
   .slant clips BOTH the top-right and the bottom-left, and both cuts reveal
   the BODY. So the moment a section has a colour of its own, its bottom cut
   shows a stripe of body colour before the next section starts — which is the
   wedge under the testimonials. slant-t clips only the top and pulls the
   section up over its predecessor, so the cut reveals the SECTION ABOVE and
   nothing can leak through. Applied to the whole run, the body is never
   visible at any boundary. */
#proof,.xray,#about,.final{
  margin-top:calc(-3.5vw - 2px);
  clip-path:polygon(0 0,100% 3.5vw,100% 100%,0 100%);
  position:relative}
/* About and the closing section must not match, the way Upscalum alternates
   them: measured there, About sits on the deeper ground (#041B0F) and the
   closer on the lighter one (#06251A). Same relationship here — About drops
   back, the closer steps forward — so the page does not end on two identical
   slabs. */
#about{background:linear-gradient(174deg,#78331A 0%,var(--b4) 62%)}
.final{background:linear-gradient(170deg,#BE5128 0%,#A44420 55%,#8A3A1B 100%)}
.vidcap{display:none}
/* ---------- the Red / Yellow / Green legend ----------
   These three are SEMANTIC, not brand. .score .g was written as
   var(--green) — correct on Upscalum, where the brand colour happens to be
   green, and wrong the moment the token is remapped: on OCA the word "Green"
   came out aqua and on EI it came out orange, which destroys the only thing
   the legend is for. Pinned to literal traffic-light values in both forks so
   no future palette change can break the meaning again. */
.score .r{border-color:#FF5C47 !important} .score .r b{color:#FF8F7A !important}
.score .y{border-color:#FFC400 !important} .score .y b{color:#FFD84D !important}
.score .g{border-color:#22C55E !important} .score .g b{color:#4ADE80 !important}

/* ---------- THE X-RAY PAGE: MIMIC UPSCALUM ----------
   Checked rather than assumed: Upscalum's business-xray page contains ZERO
   linear-gradients of its own. It is a flat --deep body with exactly three
   sections pinned to --deeper, and the diagonals come from .slant / .slant-t.
   That is the whole design.
   The OCA fork shares ONE stylesheet with the homepage, so every gradient,
   texture and re-toned section built for the homepage landed on this page too
   — which is the "too much gradient compared to Upscalum" Janez is seeing. It
   was never a decision about this page; it was spill.
   So the page is scoped out of all of it via a body class and handed back the
   flat treatment, one-for-one with Upscalum, blue where it was green. The one
   deliberate departure he asked for stays: The Solution is bright — but FLAT
   bright, because Upscalum uses no gradient here and he asked for faithful. */
body.xr{background:var(--deep)}
body.xr .section{background-color:transparent;background-image:none;
  margin-top:0;clip-path:none}
/* the two slant shapes put back exactly as Upscalum defines them */
body.xr .section.slant{clip-path:polygon(0 0,100% 3.5vw,100% 100%,0 calc(100% - 3.5vw))}
body.xr .section.slant-t{margin-top:calc(-3.5vw - 2px);
  clip-path:polygon(0 0,100% 3.5vw,100% 100%,0 100%)}
body.xr .band{background:var(--blue);color:var(--white)}
/* The Solution section is NOT bright. Measured on Upscalum: at the equivalent
   scroll position its ground is #04170F — --deeper, one of the dark pair. I
   had made it bright on an earlier instruction and then kept it through the
   "mimic faithfully" pass, which contradicted the instruction. Faithful wins. */
body.xr .xsol{background:var(--deeper)}
/* The hero. Upscalum's .xhero is a 16% brand-colour glow over --deeper, and it
   lands on #041A0F — a lift of THREE points over the flat colour, so the hero
   reads slightly darker than the --deep section beneath it. The palette remap
   turned that glow aqua, and aqua at the same 16% over navy lands on #04475E:
   a fifty-point lift, a visible cyan wash, and — because it brightened the
   hero to roughly the tone of the section under it — the two top sections
   merged into one block. That is the "no sections, just one colour" Janez saw.
   The glow goes back to the brand blue, which reproduces Upscalum's small lift
   instead of overwhelming it. */
body.xr .xhero{background:
  radial-gradient(90% 120% at 50% 0%,rgba(232,131,74,.16),transparent 60%),
  var(--deeper) !important}

.vidhold{margin-top:clamp(2rem,4.5vw,3.5rem)}
#new{padding-bottom:clamp(1.5rem,3vw,2.75rem)}


/* ---------- the orange-dominant X-Ray page ----------
   Seven rust sections, two slate. Light rust is kept off the big blocks: white
   type on #D9743F measures about 3.4:1, under the 4.5 floor, so the lighter
   tones only carry short headline blocks and the long-copy sections stay on
   the deeper rusts where white is comfortable. */
body.xr .xo{background-color:transparent}
/* The X-Ray hero. It was still slate — .xhero pins itself to --deeper and beat
   the section rule — which left the top of an orange-dominant page reading
   blue. It has to be orange AND distinct from section two, which is the brand
   #C1532B carrying the video; so the hero goes DEEPER and richer, a burnt rust
   falling to near-ember at the fold. Section two then arrives brighter than the
   thing above it, which is the right way round: the page opens dark and warms
   up rather than starting at full brightness with nowhere to go. */
body.xr .xo1,body.xr .xhero{background:
  radial-gradient(88% 110% at 50% 0%,rgba(255,208,43,.16),transparent 62%),
  linear-gradient(168deg,#B5502A 0%,#8C3A1B 46%,#6B2A11 100%) !important}
body.xr .xo2{background:#C1532B !important}
body.xr .xo3{background:#6B2A11 !important}
body.xr .xo4{background:#A4431E !important}
body.xr .xo5{background:linear-gradient(168deg,#D9743F 0%,#C1532B 55%,#A4431E 100%) !important}
body.xr .xo6{background:#8C3A1B !important}
body.xr .xo7{background:#5C2610 !important}
body.xr .xo8{background:#B04A22 !important}
body.xr .xo9{background:#7A3418 !important}
/* every join is a hard diagonal revealing the section above, so two rusts that
   differ by only a few points still read as separate sections */
body.xr .xo:not(.xo1){margin-top:calc(-3.5vw - 2px);
  clip-path:polygon(0 0,100% 3.5vw,100% 100%,0 100%);position:relative}
/* the slate panels inside the rust sections need to stop being slate-on-slate */
body.xr .xo .pricebox{border-color:#FFD02B !important}
/* BOOK IT carries .band, which sets dark ink for type on a bright fill. Its
   fill is now rust, not the bright band colour, so ink drops to about 3:1 and
   the headline half-disappears. White throughout that section instead. */


/* The hero was reading as a blue-to-orange wash. Cause: the base .hero rule
   paints a slate background-color UNDER a semi-transparent gradient stack, so
   wherever my orange gradient thinned out, slate showed through — a diagonal
   blend nobody asked for. Fixed by making the orange fully opaque across the
   whole element and neutralising anything the base rule layers on top. */
.hero{background:linear-gradient(168deg,#E07C42 0%,#C1532B 46%,#9A3C18 100%) !important}
.hero::before,.hero::after{background:none !important}
/* The nav takes EI's cream, which is what their live site uses — so the logo
   has to flip to the dark lockup or it disappears into it. */
.nav{background:#C1532B !important;border-bottom:1px solid rgba(255,255,255,.16) !important}
.nav a,.nav__link{color:#fff !important}
/* The hand-drawn START ellipse. It was being forced near-black by a filter I
   added when the nav was dark; on cream that is just a black scribble. The
   artwork already carries the accent colour, so the filter only has to deepen
   it to the rusty brand orange rather than recolour it from scratch. */
/* the hand-drawn circle around HIRE US, in brand yellow on the rusty nav */
.nav__start::after{filter:brightness(1.25) saturate(1.6) hue-rotate(-14deg)}
.nav__start{color:#FFD02B !important}
/* The DARK lockup is for the cream nav only. The first rule targeted every
   .logo img, which included the footer — dark logo on a dark footer, invisible.
   The footer keeps the white one.
   Height is trimmed to 34px to sit where Upscalum's footer wordmark sits: that
   is type at 1.1rem, roughly 20px of letter height, and this lockup carries two
   stacked lines plus an icon, so 34px puts its text at about the same size
   rather than making the footer twice as loud as Upscalum's. */
.nav .logo img{content:url(img/logo-ei-white.webp)}
.logo--foot img{content:url(img/logo-ei-white.webp) !important;height:34px !important}
.nav a{color:#fff !important;opacity:1}
.nav .btn{color:#1A1400 !important}
.nav__start{color:#fff !important}

.hero{background-color:#C1532B !important;
  background-image:
    radial-gradient(72% 42% at 78% 40%,rgba(255,255,255,.16),transparent 74%),
    radial-gradient(60% 34% at 10% 72%,rgba(255,159,28,.22),transparent 74%),
    linear-gradient(172deg,#D9743F 0%,#C1532B 52%,#A4401C 100%) !important}
/* Black label text on every bright fill that is now orange. */
/* The AQUA from OCA, not the azure — that was my misread of "the same one as
   on the online course". OCA's main buttons are #00FFFF; azure is only its
   X-Ray CTA. Black label: aqua is bright enough that dark ink beats white.
   THE BLACK FRAME: .btn carries box-shadow 0 0 0 3px var(--deeper) — a ring in
   the darkest ground colour. On OCA that is navy sitting on navy, so it is
   invisible and does its job silently. On an orange hero the same ring reads
   as a hard black outline for no apparent reason. The ring is there to stop
   the button dissolving into busy artwork behind it, so it is kept but
   restated in the ORANGE's own dark end — still separating, no longer a
   black box. */
.btn{background:#FFD02B !important;color:#1A1400 !important;
  box-shadow:0 0 0 3px #FFFF00,
    0 2px 3px rgba(60,22,8,.3),0 8px 16px rgba(60,22,8,.34),0 20px 44px rgba(60,22,8,.3) !important}
.btn:hover,.btn:focus-visible{box-shadow:0 0 0 3px #FFFF00,
    0 3px 5px rgba(60,22,8,.34),0 12px 24px rgba(60,22,8,.38),0 26px 56px rgba(60,22,8,.34) !important}
/* The glow is the CTA beacon — one ring expanding out of the button every 2.6s.
   It inherited the accent orange, which on an orange hero expands into a
   colour barely different from the ground, so the pulse was invisible. Yellow
   matches the button and the new ring, so the whole device reads as one. */
@keyframes ctaBeacon{
  0%   {box-shadow:0 0 0 0 rgba(255,208,43,.55)}
  70%  {box-shadow:0 0 0 20px rgba(255,208,43,0)}
  100% {box-shadow:0 0 0 0 rgba(255,208,43,0)}
}
.btn__main::before{background:#000}
/* Eyebrows. They inherit the brand colour, which is now orange — orange text
   on an orange hero is invisible. They take the button colour instead, which
   also answers the bottom section: one accent doing both jobs rather than a
   third colour joining in. */
/* Eyebrows take the button colour, per Janez: one accent doing both jobs
   rather than a third colour joining in. Brand yellow is also what the
   headline emphasis already uses, so the whole accent layer is now ONE value —
   button, eyebrow and highlight — against the orange ground. */
.kicker,.eyebrow{color:#FFD02B !important}
/* The X-Ray CTA takes EI's OWN accent blue — #1C9FD6, sampled off the live
   "See Our Blueprint" button and confirmed against the brand doc, which lists
   it as "Accent — bright blue, CTAs". So this is not a colour I chose; it is
   the one EI already uses for exactly this job. It also does the separating
   work the green was failing at: 197 degrees from the yellow primary and the
   near-complement of the orange ground, so it cannot be confused with either. */
/* Janez changed his mind: the Hire Us / booking CTA is the branded rusty
   orange. It works everywhere except BOOK IT, whose ground IS that orange — so
   that one section flips to the slate instead, and the button keeps its colour
   rather than the page keeping a button it swallows. */
.btn--xray{background:#C1532B !important;color:#fff !important;
  box-shadow:0 0 0 3px #FFD02B,0 8px 20px rgba(0,0,0,.4) !important}
/* BOOK IT is the LOUD band, exactly as Upscalum uses it: there the section is
   the full-strength brand green with dark ink on top, and it is the only
   section on the page that shouts. Mine had been forced to the same ember as
   HONESTY above it by an override written back when the button was orange and
   the section had to get out of its way — so the two sections merged into one
   block. The button is no longer orange, so the section can have its colour
   back. Super-bright orange, dark ink, and the button on it goes dark the way
   Upscalum's does on green. */
#buy{background:#FF7A1F !important;color:#2A1208 !important}
#buy h2,#buy p,#buy .kicker{color:#2A1208 !important}
#buy .kicker{opacity:.62}
#buy .mark{background:#2A1208 !important;color:#FF7A1F !important}
/* The price block on the bright band. It still carried a dark fill and dark
   type, which on orange left the supporting lines unreadable. Johnson box
   proper here: dashed dark rule, NO fill, dark ink throughout, and the small
   print lifted off full opacity rather than dimmed toward the background. */
#buy .pricebox{border:2px dashed #2A1208 !important;background:none !important}
#buy .pricebox *{color:#2A1208 !important;opacity:1 !important}
#buy .pricebox small,#buy .pricebox p{opacity:.78 !important}
/* HONESTY keeps the deep ember so the two no longer read as one section */
body.xr .xo7{background:#5C2610 !important}
.btn--xray .btn__main::before{background:#fff}
.vidplay__face{color:#000 !important}
.btn__sub{opacity:.72}
/* ---------- the Red / Yellow / Green legend ----------
   These three are SEMANTIC, not brand. .score .g was written as
   var(--green) — correct on Upscalum, where the brand colour happens to be
   green, and wrong the moment the token is remapped: on OCA the word "Green"
   came out aqua and on EI it came out orange, which destroys the only thing
   the legend is for. Pinned to literal traffic-light values in both forks so
   no future palette change can break the meaning again. */
.score .r{border-color:#FF5C47 !important} .score .r b{color:#FF8F7A !important}
.score .y{border-color:#FFC400 !important} .score .y b{color:#FFD84D !important}
.score .g{border-color:#22C55E !important} .score .g b{color:#4ADE80 !important}


/* (the blue-buttons trial rules lived here; removed 2026-07-30 -- they
   out-specified every later colour and were why the X-Ray page stayed slate) */

/* The Message us widget builds its button from var(--green), which on this
   site is the accent orange -- orange on an orange page, invisible. Janez:
   same colour as the Free Roadmap button. The widget's own elements are
   restyled here rather than editing message.js, so the widget file stays
   byte-identical across all three brands (that is its whole design). */
.mw-fab{background:#FFD02B !important;color:#1A1400 !important;
  box-shadow:0 0 0 3px #FFFF00,0 8px 20px rgba(0,0,0,.4) !important}
.mw-send{background:#FFD02B !important;color:#1A1400 !important}

/* the small-card mask scales the embed; never let it spill the card */
.cf__card{overflow:hidden}

/* ── Janez 2026-07-30: Roadmap goes PURE YELLOW, Hire Us/Book goes NEON RED */
.btn{background:#FFFF00 !important;color:#1A1A00 !important;
  box-shadow:0 0 0 3px rgba(60,22,8,.55),0 8px 20px rgba(0,0,0,.4) !important}
.btn .btn__main::before{background:#1A1A00 !important}
@keyframes ctaBeacon{
  0%{box-shadow:0 0 0 0 rgba(255,255,0,.5)}
  70%{box-shadow:0 0 0 20px rgba(255,255,0,0)}
  100%{box-shadow:0 0 0 0 rgba(255,255,0,0)}}
.kicker{color:#FFFF00 !important}
.btn--xray{background:#FF1E1E !important;color:#fff !important;
  box-shadow:0 0 0 3px rgba(60,22,8,.55),0 8px 20px rgba(0,0,0,.4) !important}
.btn--xray .btn__main::before{background:#fff !important}

/* ── FINAL BUTTON TREATMENT (EI) ─────────────────────────────────────────
   No ring. The 3px ring is inherited from Upscalum, where it exists to stop
   a green CTA dissolving into busy rocket artwork. Nothing on this site sits
   on artwork like that, so here it was only ever a hard outline in whatever
   colour the last edit happened to leave behind -- brown on the yellow, slate
   on the red. Janez is right that it looks random, because it was.
   Replaced with a GLOW in the button's own colour: soft, coloured, and it
   reads as light coming off the button rather than a line drawn round it.
   Specificity is body.xr-proof so these hold on both pages. */
.btn,body.xr .btn,#buy .btn{
  background:#FFFF00 !important;color:#1A1A00 !important;
  box-shadow:0 0 22px 2px rgba(255,255,0,.55),0 10px 26px rgba(0,0,0,.42) !important}
.btn .btn__main::before,body.xr .btn .btn__main::before{background:#1A1A00 !important}
.btn:hover,body.xr .btn:hover,.btn:focus-visible{
  box-shadow:0 0 34px 6px rgba(255,255,0,.75),0 14px 32px rgba(0,0,0,.46) !important}

.btn--xray,body.xr .btn--xray,#buy .btn--xray{
  background:#FF1E1E !important;color:#fff !important;
  box-shadow:0 0 22px 2px rgba(255,30,30,.6),0 10px 26px rgba(0,0,0,.42) !important}
.btn--xray .btn__main::before,body.xr .btn--xray .btn__main::before{background:#fff !important}
.btn--xray:hover,body.xr .btn--xray:hover,.btn--xray:focus-visible{
  box-shadow:0 0 34px 6px rgba(255,30,30,.8),0 14px 32px rgba(0,0,0,.46) !important}

/* the hand-drawn circle round HIRE US follows its button to red.
   The artwork is brand yellow (hue ~45); -30 lands it on ~0 = red. */
.nav__start{color:#FFFF00 !important}
.nav__start::after{filter:hue-rotate(-30deg) saturate(3.4) brightness(1) !important}

/* The circle is an SVG data-URI with stroke="#FFD02B" baked in. Filters were
   only ever approximating red from yellow -- and hue-rotate on a near-primary
   yellow cannot reach red cleanly. Redraw it with the red stroke instead, and
   drop the filter entirely so nothing shifts it afterwards. */
.nav__start::after{background:url("data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A//www.w3.org/2000/svg%22%20viewBox%3D%220%200%20140%2056%22%20fill%3D%22none%22%3E%3Cpath%20d%3D%22M69%208C34%205%2010%2015%209%2027c-1%2013%2024%2022%2060%2021%2036-1%2062-10%2062-22C131%2014%20104%205%2063%208c-8%20.6-16%202-22%204%22%20stroke%3D%22%23FFFF00%22%20stroke-width%3D%224.5%22%20stroke-linecap%3D%22round%22/%3E%3C/svg%3E") center/100% 100% no-repeat;filter:none !important}

/* Janez: red did not stand out on the rust nav — too close in hue to the
   ground, so it separated only by brightness. Pure yellow is 40 degrees away
   AND far brighter, and it ties the circle to the Free Roadmap button. */
.nav__start{color:#FFFF00 !important}

/* ── EVERY eyebrow, whatever its parent ──────────────────────────────────
   The sized/faded rule was written as .sechead p.kicker, but eyebrows live
   under THREE different parents: .sechead (most sections), .ceo__head (The
   Problem / The Solution on the homepage) and .about__head (About). So About
   silently rendered at body size and full strength while its neighbours were
   large and faded — it was never styled differently on purpose, it just never
   matched the selector. Listing all three keeps them identical, and any new
   head class only has to be added here once. */
.sechead p.kicker,.ceo__head p.kicker,.about__head p.kicker{
  font-size:clamp(1.3rem,3.2vw,2.7rem);
  opacity:.28;
}

/* ── EYEBROW SPACING, uniform across all three parents ───────────────────
   The gap under an eyebrow was different depending on which head it sat in,
   and not by design. The base rule is .kicker{margin:0 0 .55em}, but
   .sechead p{margin:0} — written for body paragraphs — is one class more
   specific, so inside .sechead the eyebrow's bottom margin was silently
   zeroed. .ceo__head and .about__head have no equivalent, so theirs kept the
   .55em. That is why About sat further from its headline than Results did.
   Set explicitly here, in REM not em, so it can no longer drift with the
   eyebrow's own font-size either. */
.sechead p.kicker,.ceo__head p.kicker,.about__head p.kicker{margin:0 0 .35rem !important}
.sechead h2,.ceo__head h2,.about__head h2{margin-top:0 !important}

/* EI eyebrow — Janez pick, option 1: white at 45%. Same reasoning as OCA:
   the accent orange at 28% sat too close to its own rust ground. White is
   ground-agnostic and reads identically on the rust sections and the bright
   orange band. */
.sechead p.kicker,.ceo__head p.kicker,.about__head p.kicker,.kicker{
  color:#FFFFFF !important;opacity:.45 !important}

/* ── FINAL SPACING + MOBILE PASS ─────────────────────────────────────────
   1. MORE ROOM ABOVE THE FILM. It was almost touching the desk on desktop and
      the FREE ROADMAP button on mobile. The gap is .vidhold's top margin;
      roughly doubled. The blue band grows with it automatically — the dark
      run is anchored to the section's BOTTOM and sized from the film's own
      height, so pushing the film down carries the seam down with it and the
      bright blue simply extends further. Nothing else needs moving. */
.vidhold{margin-top:clamp(4.5rem,9vw,7.5rem) !important}
/* On a phone the clamp bottoms out at its 4.5rem floor (9vw is only ~45px
   at 500px wide), so the phone got the least extra room precisely where
   the crowding was worst — THE FILM tag nearly touching the Roadmap
   button. Raise the floor for narrow screens only. */
@media(max-width:760px){.vidhold{margin-top:6.5rem !important}}

@media(max-width:760px){
  /* 2. THE BACKING PLATE ON A PHONE. At 14px the offset was a slab rather
        than an edge, and on the right it ran past the screen. ~2mm at phone
        density is about 6px, which reads as depth without spilling. */
  }

@media(max-width:640px){
  /* 3. A LOUDER PULSE ON THE HIRE US BUTTON. The mobile amplitude was capped
        at 8% for a specific reason — at full desktop scale the button is most
        of the viewport wide and pushes past the edge, adding sideways scroll.
        So this is raised, not removed: 8% -> 14%, which is the most that
        still keeps the skewed button inside the viewport at 320px. */
  @keyframes xrayPulseSm{
    0%,100%{transform:skewX(-9deg) scale(1)}
    50%    {transform:skewX(-9deg) scale(1.14)}
  }
}

/* ── THE MOBILE PLATE, TARGETED AT THE RIGHT CLASS ───────────────────────
   Every previous mobile rule for this named .vidplate — a class that does not
   exist in the markup. The element is .fplate. So none of them ever applied
   and the plate stayed at the desktop 26px offset on phones, reaching within
   two pixels of a 500px viewport edge.
   26px -> 8px, which is the 30% Janez asked for. The Z offset is dropped on
   The negative Z is KEPT. Dropping it put the plate IN FRONT of the film:
   inside a preserve-3d parent the paint order is by Z, not by DOM order,
   so -40px is the only thing holding the plate behind the strip. Only the
   2D offset changes on phones. */
@media(max-width:760px){
  .fplate{transform:translate(8px,8px) translateZ(-40px) !important}
}

/* ── THE HERO PARAGRAPH ON MOBILE ─────────────────────────────────────────
   It was hidden on phones outright. Restored, and placed between the button
   and the client strip.
   The paragraph had to MOVE IN THE DOM to get there: it lived in .hero__copy
   while the button and client strip live in .hero__cta, and no amount of CSS
   ordering can interleave children of two different parents. It now sits
   inside .hero__cta, between the two -- which is the mobile order wanted.
   On desktop that would put it BELOW the button, so order:-1 lifts it back
   above. Both parents stack in the same column there, so the desktop result
   is pixel-identical to before.
   The 2.5rem top margin on phones is one line box of clearance: without it
   the first line runs through the artwork above, which reaches lower than
   its visible edge suggests.
   Deliberately NOT touched: .hero__cta's negative margin-top, which is what
   makes the button overlap the artwork. */
.hero p.lede{display:block}
@media(min-width:980px){
  .hero__cta{display:flex;flex-direction:column;align-items:flex-start}
  .hero__cta p.lede{order:-1}
}
@media(max-width:979px){
  .hero__cta p.lede{order:0;text-align:center;max-width:54ch;margin:1.1rem auto 0}
}
@media(max-width:640px){
  .hero p.lede{display:block;font-size:.95rem;margin:2.5rem auto .2rem}
}

/* One row of clearance was not enough -- the paper debris under the rocket
   falls further than it looks, and the paragraph's first line still ran
   through it on all three sites. Two rows clears it. */
@media(max-width:640px){
  .hero p.lede{margin-top:4rem}
}
