/* HV Funnels: one stylesheet for every client funnel. The colours, font and hero ratio
   come from the settings file at run time through the custom properties below. */
:root{
  --primary:#0e7a43;        /* buttons, progress, active states */
  --primary-dark:#08492a;   /* hover and pressed */
  --ink:#14231b;            /* headings */
  --body:#4a5a51;           /* body copy */
  --bg:#f7f6f2;             /* page background */
  --card:#ffffff;
  --line:#e2e0da;
  --hero-ratio:1.7;
  --radius:14px;
  --font:'Inter',system-ui,-apple-system,'Segoe UI',sans-serif;
  --display:var(--font);     /* brand.displayFont: headlines, the header name, the question line */
  --eyebrow-tracking:.07em;  /* brand.eyebrowTracking */
  /* Exactness tokens (plan 04-07 exactness pass), each set only when the settings name it:
     --qline-font, --logo-size, --radius-control, --w-<name> (brand.weights), --lh-<name>
     (brand.lineHeights), --ls-<name> (brand.tracking), --gap-<name> (brand.gaps), --c-<name>
     (brand.colors), --icon-<name> (brand.icons), --control-<name> (brand.controls). Every
     rule reads them with the house value as the fallback, so a file that never names them
     renders as before. */
}
*{box-sizing:border-box;margin:0;padding:0}
body{font-family:var(--font);background:#e9e7e1;color:var(--body);font-weight:var(--body-weight,400);
     min-height:100vh;display:flex;flex-direction:column;align-items:center;
     padding:0;overflow-x:hidden;-webkit-font-smoothing:var(--font-smoothing,antialiased)}
.phone{width:100%;max-width:min(430px,100%);background:var(--bg);flex:1;
       display:flex;flex-direction:column;min-height:100vh;position:relative;
       box-shadow:0 0 42px rgba(0,0,0,.14)}
/* On a desktop the column would stretch to the full window and every screen reads as
   half empty. Framing it at phone height is both better looking and a truer preview. */
@media (min-width:600px){
  body{justify-content:flex-start;padding-bottom:26px}
  .phone{flex:0 0 auto;height:min(858px,calc(100vh - 52px));min-height:0;
         margin:26px auto 0;border-radius:26px;overflow:hidden}
}
/* brand.gaps.header also sets the header's top padding without a mark (12 when absent). */
header{padding:var(--gap-header,12px) 20px 0}
.wordmark{display:flex;align-items:center;gap:8px;font-weight:700;color:var(--primary);
          font-size:15px;letter-spacing:-.01em;min-height:18px}
/* brand.logo: an image mark before the name. A header with a mark is taller, so it gets
   the air a 28px square needs above and below. */
.wordmark img.logo{display:block;height:var(--logo-size,28px);width:var(--logo-size,28px);border-radius:6px;flex:0 0 var(--logo-size,28px)}
header.has-mark{padding-top:var(--gap-header,16px)}
header.has-mark .wordmark{font-size:16px;min-height:var(--logo-box,var(--logo-size,28px))}
header.has-mark .track{margin-top:16px}
/* brand.wordmarkAccent: the name goes ink and the named word keeps the brand colour. */
.wordmark .name{font-family:var(--display)}
.wordmark .name.split{color:var(--ink)}
.wordmark .name .accent{color:var(--primary)}
/* brand.wordmarkStyle "pill": the name on a pill in the brand colour, brand.pillText for the
   text (white when absent), brand.wordmarkTracking for its letter spacing. */
.wordmark .name.pill{display:inline-block;background:var(--primary);color:var(--pill-text,#fff);font-size:14px;font-weight:700;
      letter-spacing:var(--wordmark-tracking,0);line-height:20px;border-radius:6px;padding:6px 12px}
/* brand.headerLabel: a quiet label at the right, for example the area covered. */
.wordmark .hlabel{margin-left:auto;font-size:12px;font-weight:500;color:var(--body);letter-spacing:0}
.track{height:var(--bar-height,6px);background:var(--bar-track,var(--line));border-radius:99px;margin-top:10px;overflow:hidden}
.fill{height:100%;background:var(--accent,var(--primary));border-radius:var(--bar-radius,99px);width:0;
      transition:width .35s cubic-bezier(.4,0,.2,1)}
.meta{display:flex;justify-content:space-between;align-items:center;
      margin-top:6px;font-size:var(--size-step,12px);font-weight:var(--w-step,400);line-height:var(--lh-step,normal);color:var(--muted,#8b978f);min-height:14px}
/* header.metaRow "above": the step row (the back link at the left, the step label at the
   right) sits above the bar, the Perspective order. With no back link the label sits left;
   with nothing in it at all (the result) the row goes and the bar takes its place. */
header.meta-above{display:flex;flex-direction:column}
header.meta-above .meta{order:1;margin:var(--gap-meta,20px) 0 8px;min-height:16px}
header.meta-above .track{order:2;margin-top:0}
header.meta-above .meta>span{display:flex}
header.meta-above .meta>span:empty{display:none}
header.meta-above.norow .meta{display:none}
header.meta-above.norow .track{margin-top:var(--gap-meta,20px)}
header.meta-above .wordmark{order:0;align-items:flex-start}
header.meta-above .trust.top{order:3}
.meta .backlink{display:inline-flex;align-items:center;gap:4px;margin:0;font-size:var(--size-step,12px);font-weight:var(--w-back,500);
      color:var(--c-back,var(--muted,#8b978f));text-decoration:none;line-height:var(--lh-step,16px)}
.meta .backlink svg{width:var(--icon-back,16px);height:var(--icon-back,16px);display:block}
/* header.stepAlign "right": the step label at the right of its row whichever side of the
   bar the row sits (with metaRow above and no back link it would otherwise sit left). */
header.step-right #count{margin-left:auto}
/* With the strip at the top the step label and the strip read as one block, so they share
   the body grey rather than the lighter meta grey. */
header.strip-top .meta{color:var(--muted,var(--body))}
/* Top aligned rather than centred: with centring, the headline jumps up and down between
   screens as the number of cards changes, and short screens float in the middle looking
   unfinished. Anchoring the headline puts trailing space at the bottom where it reads as normal. */
main{flex:1;display:flex;flex-direction:column;justify-content:flex-start;padding:var(--gap-main,16px) var(--gap-side,20px) var(--gap-main-bottom,24px);
     overflow-y:auto}
main:not(.inner):not(.done){padding-top:var(--gap-landing,var(--gap-main,16px));padding-bottom:var(--gap-landing-bottom,var(--gap-main-bottom,24px))}
/* screens.valign "center": every screen but the landing centres its content between the
   header and the trust strip, as Perspective's inner pages do. */
.vcenter main.inner,.vcenter main.done{justify-content:center}
/* Wide bands suit a landscape scene; a person needs more height or their head gets cut.
   Set --hero-ratio per client rather than forcing one crop to serve both. */
.hero{width:100%;aspect-ratio:var(--hero-ratio,2.3);object-fit:cover;
      border-radius:var(--radius);margin-bottom:var(--gap-hero,16px);background:#d8d5cd}
.eyebrow{font-size:var(--size-eyebrow,12px);font-weight:600;line-height:var(--lh-eyebrow,normal);color:var(--c-eyebrow,var(--muted,var(--primary)));
         text-transform:uppercase;letter-spacing:var(--eyebrow-tracking);margin-bottom:var(--gap-eyebrow,9px)}
h1{font-size:var(--size-h1,25px);line-height:var(--lh-h1,1.2);color:var(--ink);font-weight:var(--w-h1,var(--w-display,700));
   letter-spacing:var(--ls-h1,-.02em);margin-bottom:var(--gap-h1,9px);font-family:var(--display)}
h2{font-size:var(--size-h2,21px);line-height:var(--lh-h2,1.25);color:var(--ink);font-weight:var(--w-display,700);
   letter-spacing:var(--ls-h2,-.015em);margin-bottom:var(--gap-h2,7px);font-family:var(--display)}
/* brand.textWrap.headings: balance (or pretty) on every headline without a display face;
   the display rules below balance their headlines on their own. */
h1,h2{text-wrap:var(--wrap-headings,wrap)}
/* landing.headlineAccent: the named phrase of the landing headline in the accent colour
   (brand.colors.highlight, then brand.accent, then brand.primary). */
h1 .accent{color:var(--c-highlight,var(--accent,var(--primary)))}
/* result.headlineAccent (plan 04-05): the result headline is an h2, set the same way. */
main.done h2 .accent{color:var(--c-highlight,var(--accent,var(--primary)))}
/* A terminal h1 (thank you, off ramp) is set like the inner h2s: display weight and tracking. */
.done h1{font-weight:var(--w-display,700);letter-spacing:var(--ls-h2,-.02em)}
.sub{font-size:var(--size-sub,14.5px);line-height:var(--lh-sub,1.5);margin-bottom:var(--gap-sub,15px);text-wrap:var(--wrap-sub,wrap)}
/* brand.lineHeights.landingSub: the opening sub line alone (Perspective's Build & Co sets it 26
   over 24). The class exists only when the key does, so no other file's sub line moves. */
.landing-sub main:not(.inner):not(.done) .sub{line-height:var(--lh-landing-sub)}
/* On the opening screen the headline sells and this line asks, so they need separating. */
.qline{font-size:var(--size-qline,17.5px);font-weight:var(--w-qline,700);color:var(--ink);letter-spacing:var(--ls-qline,-.01em);margin:var(--gap-qline-top,0) 0 var(--gap-qline,11px);
       line-height:var(--lh-qline,normal);font-family:var(--qline-font,var(--display));text-wrap:var(--wrap-qline,wrap)}
/* brand.displayFont: the house sizes were tuned for Inter, so a display face brings its own
   scale: headlines 24 on 30 tracked -.025em and balanced across lines, the question line
   16 on 24 with no tracking. */
.display h1{font-size:var(--size-h1,24px)}
.display h2{font-size:var(--size-h2,24px)}
.display h1{line-height:var(--lh-h1,30px);letter-spacing:var(--ls-h1,var(--ls-display,-.025em));margin-bottom:var(--gap-h1,8px)}
.display h2,.display .done h1{line-height:var(--lh-h2,30px);letter-spacing:var(--ls-h2,var(--ls-display,-.025em));margin-bottom:var(--gap-h2,8px)}
.display h1,.display h2{text-wrap:balance}
.display .qline{font-size:var(--size-qline,16px);line-height:var(--lh-qline,24px);letter-spacing:var(--ls-qline,0);margin-bottom:var(--gap-qline,8px)}
/* An off ramp headline is an h1 on a terminal screen. The port specs size it with the inner
   h2s (Integrate: thank you and off ramp at 30px, the landing at 24px), so it reads
   brand.sizes.h2 when named and keeps the h1 size otherwise (plan 04-07). */
.done h1{font-size:var(--size-h2,var(--size-h1,25px))}
.display .done h1{font-size:var(--size-h2,var(--size-h1,24px))}
/* brand.sizes.result: the result headline alone (drawn as h2 inside main.done, an h1 on an
   off ramp), read ahead of sizes.h2 so a file without it renders exactly as above (plan 04-02). */
main.done h2{font-size:var(--size-result, var(--size-h2,21px));line-height:var(--lh-result,var(--lh-h2,1.25))}
main.done h1{font-size:var(--size-result, var(--size-h2,var(--size-h1,25px)));line-height:var(--lh-result,var(--lh-h2,var(--lh-h1,1.2)))}
.display main.done h2{font-size:var(--size-result, var(--size-h2,24px))}
.display main.done h1{font-size:var(--size-result, var(--size-h2,var(--size-h1,24px)))}
.display .wordmark .name{letter-spacing:0}
.display .sub{font-size:var(--size-sub,14px);line-height:var(--lh-sub,1.625);text-wrap:var(--wrap-sub,pretty)}
/* screens.align as an object ({question, form}): the named screen types centre the headline
   and the sub line only; the payoff keeps its panel and the house spacing stays. */
main.tc h2,main.tc .sub{text-align:center}
/* screens.align "center": the inner screens (not the landing, not the result) centre the
   headline, the sub line and the payoff, sit 38px under the header block, and the payoff
   becomes a plain tint with no line, 12px corners and 14px body copy. */
.center main.inner{padding-top:var(--gap-main,38px)}
.center main.inner h2,.center main.inner .sub,.center main.inner .payoff{text-align:center}
.center main.inner .sub{margin-bottom:var(--gap-sub,20px)}
.center main.inner .sub+.payoff{margin-top:-8px}
.center .payoff{border:none;border-radius:12px;padding:12px 16px;font-size:14px;line-height:1.625;
      margin-bottom:20px}
.opts{display:flex;flex-direction:column;gap:var(--gap-stack,9px);margin-top:var(--gap-options,0)}
/* Photo cards: a picture answers "which of these is my project?" faster than a label can. */
.opts.grid{display:grid;grid-template-columns:1fr 1fr;gap:var(--gap-stack,10px)}
.opt.photo{flex-direction:column;padding:0;gap:0;align-items:stretch;overflow:hidden}
.opt.photo img{width:100%;aspect-ratio:4/3;object-fit:cover;display:block;background:#ddd}
.opt.photo .plabel{padding:var(--gap-plabel,11px) 10px;font-size:var(--size-plabel,14px);line-height:var(--lh-plabel,1.3);font-weight:600;
      text-align:center;color:var(--ink)}
.opt.photo:active{transform:scale(.985)}
.opt{display:flex;align-items:center;gap:var(--gap-mark,13px);width:100%;text-align:left;
     background:var(--card);border:var(--option-border,1.5px) solid var(--line);border-radius:var(--radius);
     padding:var(--option-py,15px) var(--option-px,16px);font:inherit;font-size:var(--size-option,15.5px);line-height:var(--lh-option,normal);color:var(--c-option,var(--ink));font-weight:var(--w-option,500);
     cursor:pointer;transition:border-color .15s,transform .1s,box-shadow .15s}
.opt:hover{border-color:var(--primary);box-shadow:0 2px 10px rgba(0,0,0,.05)}
.opt:active{transform:scale(.985)}
.mark{flex:0 0 38px;height:38px;border-radius:10px;background:color-mix(in srgb,var(--primary) 9%,#fff);
      color:var(--c-mark,var(--accent,var(--primary)));display:grid;place-items:center;font-size:14px;font-weight:700}
.mark svg{width:21px;height:21px;display:block}
.opt:hover .mark{background:color-mix(in srgb,var(--primary) 16%,#fff)}
/* Engine set C (plan 04-03): a card marked by a tap on a multi question or a single question
   with a Next button, an emoji printed as the mark, and a capture field with an icon inside
   the control's left edge. Off for every file that never names these keys. */
.opt.picked,.opt.picked:hover{border-color:var(--primary);box-shadow:0 0 0 1px var(--primary) inset}
.multi .opt .mark,.multi .opt:hover .mark{background:color-mix(in srgb,var(--primary) 9%,#fff)}
.multi .opt.picked .mark{background:var(--primary);color:#fff}
.mark.emoji,.opt:hover .mark.emoji,.cards .opt .mark.emoji{font-size:22px;line-height:1;background:none;font-weight:400}
textarea.answer{margin-top:var(--gap-options,0);resize:vertical}
.cta.next{margin-top:var(--gap-cta,18px)}
/* options.markStyle "bare": the icon alone, 24px, no box (Perspective's Build & Co cards). */
.mark-bare .opt .mark,.mark-bare .opt:hover .mark{flex:0 0 var(--icon-mark,24px);width:var(--icon-mark,24px);height:var(--icon-mark,24px);border-radius:0;background:none}
.mark-bare .opt .mark svg{width:var(--icon-mark,24px);height:var(--icon-mark,24px)}
.chev{margin-left:auto;color:#c3c9c5;font-size:17px;flex:0 0 auto}
.payoff{background:var(--payoff-bg,color-mix(in srgb,var(--primary) 8%,#fff));
        border:1px solid var(--payoff-line,color-mix(in srgb,var(--primary) 22%,#fff));
        border-radius:var(--radius);padding:var(--gap-payoff-pad,13px) var(--gap-payoff-pad-x,var(--gap-payoff-pad,15px));font-size:var(--size-payoff,13.5px);
        line-height:var(--lh-payoff,1.5);color:var(--c-payoff,var(--ink));margin-bottom:var(--gap-payoff,17px);text-wrap:var(--wrap-payoff,wrap)}
.payoff b{color:var(--c-payoff-bold,var(--primary));font-weight:var(--w-payoff-bold,bold)}
/* brand.gaps.payoffTop: extra space between a headline and the panel right under it;
   brand.gaps.payoffForm: the space between the panel and the first field label. */
h2+.payoff{margin-top:var(--gap-payoff-top,0)}
.payoff+label{margin-top:var(--gap-payoff-form,var(--gap-field,13px))}
/* screens.payoffStyle "plain": the payoff as a paragraph in the muted grey, no panel, no
   line, no padding, 14px, aligned as the screen is. */
.payoff-plain .payoff{background:none;border:none;border-radius:0;padding:0;font-size:var(--size-payoff,14px);
      color:var(--c-payoff,var(--muted,var(--body)))}
.payoff-plain .payoff b{color:inherit}
/* reviews: a white card with the star row (when counted), the quote in ink and its source
   in the muted grey, 20px above each card, as Perspective's Build & Co contact screen. */
.review{margin:var(--gap-review,20px) 0 0;background:var(--card);border:1px solid var(--line);border-radius:var(--radius);padding:var(--gap-review-pad,20px)}
.reassure+.review{margin-top:var(--gap-reviews-top,var(--gap-review,20px))}
.review .stars{justify-content:flex-start;gap:4px;margin-bottom:12px}
.review .stars svg{width:14px;height:14px}
.review blockquote{font-size:16px;line-height:var(--lh-review,1.5);color:var(--ink);text-wrap:var(--wrap-review,wrap)}
.review figcaption{font-size:14px;font-weight:600;line-height:20px;color:var(--muted,var(--body));margin-top:12px}
label{display:block;font-size:var(--size-label,13px);font-weight:600;line-height:var(--lh-label,normal);color:var(--ink);margin:var(--gap-field,13px) 0 var(--gap-label,6px)}
/* brand.gaps.form: the space between the sub line (or the headline) and the first field. */
.sub+label,h2+label{margin-top:var(--gap-form,var(--gap-field,13px))}
/* Consent is a legal requirement on a lead form, not a nicety, so it gets a real control
   rather than small print under the button. */
.consent{display:flex;gap:var(--gap-inline,10px);align-items:flex-start;margin:var(--gap-consent,15px) 0 var(--gap-consent-bottom,6px);
      font-size:var(--size-consent,12.5px);line-height:var(--lh-consent,1.45);color:var(--body);font-weight:400;cursor:pointer;text-wrap:var(--wrap-consent,wrap)}
.consent input{width:var(--control-checkbox,18px);height:var(--control-checkbox,18px);flex:0 0 var(--control-checkbox,18px);margin:var(--gap-checkbox,1px) 0 0;accent-color:var(--control-checkbox-accent,var(--primary));
      line-height:inherit;min-height:0;padding:0;border-radius:var(--control-checkbox-radius,var(--radius-control,var(--radius)))}
.consent a{color:var(--c-consent-link,var(--ink));font-weight:var(--w-consent-link,inherit)}
.consent.missing{color:#c0392b}
.consent.missing input{outline:2px solid #c0392b;outline-offset:2px}
input,textarea{width:100%;font:inherit;font-size:var(--size-input,16px);line-height:var(--lh-input,normal);padding:var(--control-pad-y,13px) var(--control-pad-x-input,15px);
      border:var(--control-border,1.5px) solid var(--line);border-radius:var(--radius-control,var(--radius));background:var(--control-bg,var(--card));
      color:var(--ink);min-height:var(--control-height,auto)}
input:focus,textarea:focus{outline:none;border-color:var(--primary)}
input.missing,textarea.missing{border-color:#c0392b}
.field.has-icon{position:relative}
.field.has-icon .ficon{position:absolute;left:var(--control-pad-x-input,15px);top:50%;transform:translateY(-50%);font-size:var(--icon-field,18px);line-height:1;pointer-events:none}
.field.has-icon input,.field.has-icon textarea{padding-left:calc(var(--control-pad-x-input,15px) + var(--icon-field-pad,30px))}
/* A text question's icon (plan 04-05) sits in the box's top left corner, not its middle. */
.field.has-icon.top .ficon{top:calc(var(--control-pad-y,13px) + 2px);transform:none}
/* An off screen glyph in the display face so the face is fetched before a headline needs it. */
.font-warm{position:absolute;left:-9999px;top:0;font-family:var(--display);font-weight:var(--w-display,700);visibility:hidden}
/* The honeypot: off screen for people, a normal field for bots. */
.hp{position:absolute;left:-9999px;top:0;height:1px;width:1px;opacity:0;pointer-events:none}
.cta{display:block;width:100%;background:var(--cta-bg,var(--primary));color:var(--cta-text,#fff);border:none;border-radius:var(--radius-control,var(--radius));
     padding:var(--control-pad-y-button,var(--control-pad-y,16px)) var(--control-pad-x,16px);font:inherit;font-size:var(--size-cta,16px);line-height:var(--lh-cta,normal);font-weight:600;cursor:pointer;text-align:center;
     text-decoration:none;margin-top:var(--gap-cta,18px);min-height:var(--control-height,auto);transition:background .15s,transform .1s}
.cta:hover{background:var(--primary-dark)}
.cta:active{transform:scale(.99)}
.cta:disabled{opacity:.7;cursor:default}
/* An off ramp (settings offramps, reached through an option's goto) ends with an outlined
   external link in ink on nothing, the Integrate look; every other cta stays filled. The
   optional second link under it is plain text. */
.cta.offramp{background:none;color:var(--ink);border:var(--control-border,1.5px) solid var(--ink);margin-top:var(--gap-off-button,var(--gap-cta,18px));max-width:var(--off-button-max,none);margin-left:auto;margin-right:auto;display:flex;align-items:center;justify-content:center} .cta.offramp:hover,.cta-grad .cta.offramp:hover{background:color-mix(in srgb,var(--ink) 6%,transparent)}
.offlink{display:block;text-align:center;margin-top:14px;font-size:14px;color:var(--body);text-decoration:underline}
/* brand.landingFont: the landing headline in its own family. The class and the custom
   property exist only when the settings file names the font, so with it absent nothing
   here applies and the headline keeps var(--display). */
.landing h1{font-family:var(--landing-font)}
.error{color:#c0392b;font-size:13px;line-height:1.45;text-align:center;margin-top:10px}
.error:empty{display:none}
.reassure{font-size:var(--size-reassure,12.5px);color:var(--muted,#8b978f);text-align:var(--align-reassure,center);margin-top:var(--gap-reassure,11px);line-height:var(--lh-reassure,1.45);text-wrap:var(--wrap-reassure,wrap)}
.trust{border-top:1px solid var(--line);padding:var(--gap-trust-top,11px) 20px var(--gap-trust-bottom,18px);font-size:var(--size-trust,11.5px);
       color:var(--muted,#8b978f);text-align:center;line-height:var(--lh-trust,1.5);text-wrap:var(--wrap-trust,wrap)}
/* trustStrip.divider false: no line above the strip. trustStrip.balance: even lines. */
.trust.nodivider{border-top:none}
.trust.balance{text-wrap:balance}
/* trustStrip.align "left": the strip's lines start at the left edge of the copy. */
.trust.left{text-align:left}
/* trustStrip.position "top": the strip sits under the step label on the inner screens. */
.trust.top{border-top:none;padding:12px 0 0;font-size:var(--size-trust,11px);color:var(--muted,var(--body));line-height:1.6}
.trust[hidden]{display:none}
.stars{display:flex;justify-content:center;gap:2px;margin-bottom:var(--gap-stars,5px)}
.stars svg{width:var(--icon-star,13px);height:var(--icon-star,13px);color:var(--c-star,var(--primary))}
.done{text-align:center}
/* result.align "left": the result reads like an inner screen. */
.done.left{text-align:left}
/* result.hideBar: no progress bar and no step row on the result. */
header.nobar .track,header.nobar .meta{display:none}
/* brand.wordmarkHome: the wordmark is a button back to the opening screen. */
.wordmark[role=button]{cursor:pointer}
/* brand.wordmarkStyle "mark": the image alone, no name span. */
.wordmark.mark-only img.logo{width:auto;border-radius:0}
/* screens.back: a text link above the headline on the question and form screens. */
.backlink{display:inline-block;background:none;border:none;padding:0;margin-bottom:12px;font:inherit;
      font-size:14px;font-weight:500;color:var(--body);cursor:pointer;text-decoration:underline;text-underline-offset:2px}
.backlink:hover{color:var(--ink)}
/* Opening screen: the pitch, then a single decision. The points sit below the buttons so
   the first tap stays above the fold on a phone. */
.points{list-style:none;margin:0 0 20px;display:flex;flex-direction:column;gap:var(--gap-points,9px)}
.points.below{margin:var(--gap-points-top,20px) 0 0;padding-top:var(--gap-points-pad,17px);border-top:1px solid var(--line)}
/* landing.pointsDivider false: the points under the cards carry no line above them. */
.points.below.nodivider{padding-top:0;border-top:none}
.points li{display:flex;gap:var(--gap-inline,10px);align-items:flex-start;font-size:var(--size-points,14px);line-height:var(--lh-points,1.45);color:var(--c-points,var(--body));text-align:left;text-wrap:var(--wrap-points,wrap)}
.points svg{width:var(--icon-point,17px);height:var(--icon-point,17px);flex:0 0 var(--icon-point,17px);margin-top:2px;color:var(--c-point-tick,var(--accent,var(--primary)))}
/* result.pointsAlign "center": the list sits as a block in the middle, its lines left aligned. */
.done .points.centred{width:fit-content;margin:var(--gap-result-points,0) auto 0}
.start{display:flex;flex-direction:column;gap:var(--gap-stack,9px)}
/* The landing pair reads the control tokens (brand.controls, brand.lineHeights.cta) like the
   submit button, so a 48px Perspective button is one settings file away. */
.primary{display:block;width:100%;background:var(--cta-bg,var(--primary));color:var(--cta-text,#fff);border:none;border-radius:var(--radius-control,var(--radius));
      padding:var(--control-pad-y-button,var(--control-pad-y,16px)) var(--control-pad-x,16px);font:inherit;font-size:var(--size-cta,16px);line-height:var(--lh-cta,normal);font-weight:600;cursor:pointer;min-height:var(--control-height,auto);
      transition:background .15s,transform .1s}
.primary:hover{background:var(--primary-dark)}
.primary:active{transform:scale(.99)}
.secondary{display:block;width:100%;background:none;border:1.5px solid var(--line);border-radius:var(--radius-control,var(--radius));
      padding:14px;font:inherit;font-size:15px;color:var(--body);cursor:pointer;
      transition:border-color .15s}
/* options.secondaryStyle "outline": the second landing button as a white button outlined in
   the brand colour with ink text, set like the first (Perspective's Build & Co pair). */
.secondary-outline .secondary{background:var(--card);border:var(--control-border,1.5px) solid var(--primary);color:var(--ink);font-weight:600;
      font-size:var(--size-cta,15px);line-height:var(--lh-cta,normal);padding:var(--control-pad-y-button,var(--control-pad-y,14px)) var(--control-pad-x,14px);min-height:var(--control-height,auto)}
.secondary-outline .secondary:hover{border-color:var(--primary-dark);color:var(--ink)}
.secondary:hover{border-color:var(--primary);color:var(--ink)}
/* options.style "cards": every option, the landing pair included, is an equal white card
   with the icon bare on the left (a tick unless the option names one) and a chevron right. */
.cards .start,.cards .opts{gap:12px}
.cards .opts.grid{gap:12px}
.cards .opt{border-width:1px;border-radius:16px;padding:16px var(--option-px,20px);gap:var(--gap-inline,16px);min-height:56px;
      font-size:var(--size-option,16px);font-weight:var(--w-option,500)}
.cards .opt .mark{flex:0 0 24px;width:24px;height:24px;border-radius:0;background:none}
.cards .opt .mark svg{width:24px;height:24px}
/* brand.icons.stroke: the line weight of the option and point icons, only when named. */
.icon-stroke .mark svg,.icon-stroke .points svg{stroke-width:var(--icon-stroke)}
.icon-stroke .points svg{stroke-width:var(--icon-point-stroke,var(--icon-stroke))}
.cards .opt:hover .mark{background:none}
.cards .opt .chev{color:#adbcb1;line-height:0}
.cards .opt .chev svg{width:20px;height:20px;display:block}
.cards .opt:hover .chev{color:var(--primary)}
.cards .opt.photo{padding:0;gap:0;min-height:0}
.cards .opt.photo .plabel{text-align:left;padding:12px 16px;font-size:14px;line-height:20px}
/* A knock out replaces the options with the message and a way back. */
.knockout{background:var(--card);border:1.5px solid var(--line);border-radius:var(--radius);
      padding:18px 16px;font-size:15px;line-height:1.5;color:var(--ink)}
.knockout .secondary{margin-top:14px}
.tick{width:56px;height:56px;border-radius:50%;background:var(--primary);color:#fff;
      display:grid;place-items:center;margin:0 auto var(--gap-tick,17px)}
.tick svg{width:28px;height:28px}
/* result.tickStyle "ring": an outlined accent circle, 44px, with the tick in the accent. */
.tick.ring{width:44px;height:44px;background:none;border:3px solid var(--accent,var(--primary));color:var(--accent,var(--primary))}
.tick.ring svg{width:24px;height:24px}
/* Cookie consent, only when the settings file turns it on. It sits on the bottom of the
   phone frame above everything and holds the pixel back until Accept. */
.consent-banner{position:absolute;left:0;right:0;bottom:0;z-index:5;background:var(--card);
      border-top:1px solid var(--line);padding:14px 20px 16px;font-size:13px;line-height:1.45;
      color:var(--body);box-shadow:0 -6px 20px rgba(0,0,0,.06)}
.consent-banner[hidden]{display:none}
.consent-banner p{margin-bottom:11px}
.consent-banner .row{display:flex;gap:8px}
.consent-banner button{width:auto;flex:1;padding:11px 12px;font-size:14px}
/* Engine set C, part two (plan 04-04): blocks, the vsl screen, result links and the Illogical
   cosmetics. Every rule here is gated by a class or a custom property the settings set, so a
   file that never names them renders exactly as above. */
/* brand.ctaGradient: --cta-bg is the gradient, read by .cta and .primary above; the hover
   keeps it (a flat hover colour would wipe the gradient). brand.ctaUppercase: capitals. */
.cta-grad .cta:hover,.cta-grad .primary:hover{background:var(--cta-bg)}
.cta-upper .cta,.cta-upper .primary{text-transform:uppercase}
/* A hidden button (a vsl's revealAfter) stays hidden: .cta sets display block above. */
.cta[hidden]{display:none}
/* A button or link block: the filled house button; the small line sits under the label. */
.cta.block,.cta.link{margin-top:var(--gap-block,18px)}
.cta small{display:block;font-size:var(--size-cta-small,12px);font-weight:var(--w-cta-small,400);line-height:1.3;margin-top:3px;text-transform:none}
/* brand.headerAlign center: the mark centred, no name beside it. */
header.header-center .wordmark{justify-content:center}
/* screens.barPosition bottom: the bar is a strip at the foot of the phone frame. */
.bar-bottom .track{position:absolute;left:0;right:0;bottom:0;margin:0;border-radius:0;z-index:4}
@media (max-width:599px){.bar-bottom .track{position:fixed}}
/* legal.footLink: a quiet underlined link at the foot of every screen. */
.footlink{display:block;text-align:center;padding:var(--gap-footlink,10px) 20px 18px;font-size:var(--size-footlink,14px);color:var(--muted,#8b978f);text-decoration:underline;text-underline-offset:2px}
/* The blocks. Headings read like the inner headlines; text like the sub line. */
.bhead{font-size:var(--size-h2,21px);line-height:var(--lh-h2,1.25);color:var(--ink);font-weight:var(--w-display,700);letter-spacing:var(--ls-h2,-.015em);
       font-family:var(--display);margin:var(--gap-block,18px) 0 var(--gap-h2,7px);text-wrap:var(--wrap-headings,wrap)}
.bhead.small{font-size:var(--size-qline,17.5px);line-height:var(--lh-qline,var(--lh-h2,1.25));margin-bottom:var(--gap-label,6px)}
.bhead .bicon{display:block;margin:0 auto 8px;font-size:34px;line-height:1}
.bhead .accent,.bcard figcaption .accent,.brows .accent{color:var(--c-highlight,var(--accent,var(--primary)))}
.btext{font-size:var(--size-sub,14.5px);line-height:var(--lh-sub,1.5);margin:0 0 var(--gap-text,var(--gap-sub,15px));text-wrap:var(--wrap-sub,wrap)}
.btext.italic{font-style:italic}
.bimg{display:block;width:100%;height:auto;border-radius:var(--radius);margin:var(--gap-block,18px) 0 0;background:#d8d5cd}
/* A video: a 16 by 9 box, the poster behind until the player paints. */
.video{position:relative;width:100%;aspect-ratio:16/9;margin:var(--gap-block,18px) 0 0;border-radius:var(--radius);overflow:hidden;background:#111 center/cover no-repeat}
.video iframe{position:absolute;inset:0;width:100%;height:100%;border:0;display:block}
.bcards{display:flex;flex-direction:column;gap:var(--gap-block,18px);margin-top:var(--gap-block,18px)}
.bcard{margin:0}
.bcard figcaption{font-size:var(--size-sub,14.5px);line-height:var(--lh-sub,1.5);color:var(--ink);font-weight:var(--w-caption,600);margin-bottom:10px}
.bcard img{display:block;width:100%;height:auto;border-radius:var(--radius);background:#d8d5cd}
.blist{margin-top:var(--gap-block,18px)}
.blist .points{margin-bottom:0}
.brows{list-style:none;margin:var(--gap-block,18px) 0 0;display:flex;flex-direction:column;gap:var(--gap-points,9px)}
.brows li{display:flex;gap:var(--gap-inline,10px);align-items:flex-start;font-size:var(--size-points,14px);line-height:var(--lh-points,1.45);color:var(--c-points,var(--body))}
.brows .bicon{flex:0 0 28px;font-size:22px;line-height:1.2;text-align:center}
.brows .bicon svg{width:24px;height:24px;display:block;color:var(--c-point-tick,var(--accent,var(--primary)))}
.testimonial{margin:var(--gap-block,18px) 0 0;background:var(--card);border:1px solid var(--line);border-radius:var(--radius);padding:var(--gap-review-pad,20px)}
.testimonial blockquote{font-size:16px;line-height:var(--lh-review,1.5);color:var(--ink);text-wrap:var(--wrap-review,wrap)}
.testimonial .video{margin-top:12px}
.testimonial figcaption{font-size:14px;font-weight:600;line-height:20px;color:var(--muted,var(--body));margin-top:12px}
.done .bhead,.done .btext,.done .bcard figcaption,.done .testimonial blockquote{text-align:center}
.done .brows li,.done .blist .points li{text-align:left}
/* options.layout squares: the icon above a centred label; a pair of options as two squares,
   three or more a single column; no chevron. options.uppercase: the labels in capitals. */
.squares .opts.two{display:grid;grid-template-columns:1fr 1fr}
/* brand.gaps.squares (plan 04-05): the space above a pair of squares alone. */
.squares .opts.two{margin-top:var(--gap-squares,var(--gap-options,0))}
.squares .opt{flex-direction:column;justify-content:center;align-items:center;text-align:center;gap:10px}
.squares .opts.two .opt{aspect-ratio:1}
.squares .opt .chev{display:none}
.squares .opt .mark{flex:0 0 auto}
.opt-upper .opt{text-transform:uppercase}
/* An option's iconImage: the picture fills the mark. */
.mark.image{background:none;overflow:hidden}
.mark.image img{width:100%;height:100%;object-fit:contain;display:block}
.squares .mark.image,.squares .mark.emoji{width:var(--icon-square,48px);height:var(--icon-square,48px);flex:0 0 var(--icon-square,48px);font-size:34px}
@media (prefers-reduced-motion:reduce){*{transition:none!important}}
/* plan 04-05: screens.blocksAlign center, capture hideLabels (labels kept for assistive tech) */
.blocks-center main:not(.inner):not(.done) h1,.blocks-center main:not(.inner) .sub,.blocks-center .bhead:not(.small),.blocks-center .btext,.blocks-center .bcard figcaption,.blocks-center .testimonial blockquote,.blocks-center .testimonial figcaption{text-align:center}
label.vh{position:absolute;width:1px;height:1px;margin:0;padding:0;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap;border:0}
/* A hidden label sits between the fields, so the gap goes on every field after the first. */
.labels-hidden label.vh~label.vh+.field,.labels-hidden label.vh~label.vh+input,.labels-hidden label.vh~label.vh+textarea{margin-top:var(--gap-field,13px)}
/* options.radio (plan 04-05): more than two options as rows, the label at the left in the
   radio weight and a round mark at the right that fills when picked, Perspective's text
   answers (min height 64, a soft shadow and a hairline inset); a pair stays two squares. */
.radio .opts:not(.two) .opt{flex-direction:row;justify-content:flex-start;align-items:center;text-align:left;min-height:64px;padding:16px;gap:16px;
     font-weight:var(--w-radio,var(--w-option,500));line-height:var(--lh-radio,24px);border:0;box-shadow:0 1px 3px rgba(0,0,0,.1),inset 0 0 0 1px rgba(0,0,0,.1)}
.radio .opts:not(.two) .opt .mark:empty{display:none}
.rdot{margin-left:auto;flex:0 0 24px;width:24px;height:24px;border-radius:50%;background:#fff;box-shadow:inset 0 0 0 2px rgba(0,0,0,.2)}
.opt.picked .rdot{box-shadow:inset 0 0 0 7px var(--primary-dark,var(--primary))}
.radio .opts.two .rdot{display:none}
/* bleed (plan 04-05): a video, an image or a cards block's pictures across the phone's full
   width, square cornered, as Perspective's full width media. */
.video.bleed,.bimg.bleed,.bcards.bleed .bcard img{width:calc(100% + 2 * var(--gap-side,20px));max-width:none;margin-left:calc(-1 * var(--gap-side,20px));margin-right:calc(-1 * var(--gap-side,20px));border-radius:0}
