@import url('https://fonts.googleapis.com/css2?family=Plus+Jakarta+Sans:wght@400;500;600;700;800&display=swap');
/* ============================================================
   Nestie — Design System
   Every page links this file; 
   system-styleguide.html is the component reference. 
   Mobile-first. WCAG AA.
   ============================================================ */

:root{
  /* ---- brand colour (each family numbered light → dark) ---- */
  --primary-50:#E6F6EE;   /* soft green surface — section tint, chips, tracks */
  --primary-100:#EAF6F0;  /* near-twin of -50 (candidate to merge into -50) */
  --primary-500:#0E9E6A;  /* bright green — large display / decorative only */
  --primary-600:#0A7A50;  /* the action green — anchor, CTAs, links (white text AA) */
  --primary-900:#222C28;  /* deep desaturated green-grey — feature blocks, footer */

  --blue-50:#E4EFFB;      /* soft blue surface */
  --blue-500:#2E7DE8;     /* bright blue — large display / decorative only */
  --blue-600:#1366D6;     /* confident secondary action (white text AA) */
  --blue-700:#0F58BE;     /* darker blue — text on blue-50 */

  --amber-50:#FCF1DC;     /* soft amber surface */
  --amber-500:#DB971C;    /* gold — stars, decorative */
  --amber-700:#94660F;    /* warm accent (white text AA) */

  --coral-50:#FDEAE3;     /* soft coral surface */
  --coral-600:#B5402A;    /* warm pop (white text AA) */

  --error-50:#FCEAE6;     /* soft error surface */
  --error-600:#B4301A;    /* error text + fill (white text AA) */

  /* on deep panels (--primary-900): context colours, not hue steps */
  --feat-eyebrow:#F5C24B; /* gold eyebrow on deep surfaces (AA ~8.7:1) */
  --feat-sub:#BFD8CC;     /* muted light green body text on deep surfaces */

  /* ---- semantic aliases ---- */
  --success:var(--primary-600);
  --info:var(--blue-600);
  --warning:var(--amber-700);

  /* ---- neutrals (n- ramp, light → dark; green-tinted greys, not pure neutral) ---- */
  --white:#FFFFFF;
  --n-25:#F9FBFA;    /* faintest grey — barely-there fill above n-50 */
  --n-50:#F6F8F7;    /* very light grey — section surface */
  --n-100:#ECEFED;   /* dividers & decorative borders (exempt 3:1) */
  --n-200:#CFD3D0;   /* light green-grey — hover borders (decorative, exempt 3:1) */
  --n-500:#8A918C;   /* form/control border — lightest green-grey clearing 3:1 on n-50; don't lighten */
  --n-600:#5E6E66;   /* muted helper / hint */
  --n-700:#51625A;   /* secondary text / placeholders */
  --n-900:#14211B;   /* headings + body */

  /* ---- Type scale (Plus Jakarta Sans) ---- */
  --font:'Plus Jakarta Sans',system-ui,-apple-system,Segoe UI,Roboto,sans-serif;
  --t-display:clamp(40px,6vw,58px);
  --t-h1:clamp(32px,5vw,46px);
  --t-h2:clamp(28px,3.4vw,38px);
  --t-h3:22px;
  --t-h4:19px;
  --t-lead:19px;
  --t-body:17px;
  --t-caption:14px;

  /* ---- spacing scale ---- */
  --sp-1:4px; --sp-2:8px; --sp-3:12px; --sp-4:16px; --sp-5:24px;
  --sp-6:32px; --sp-7:48px; --sp-8:64px; --sp-9:96px;

  /* ---- radius ---- */
  --r-sm:8px; --r-md:12px; --r-lg:18px; --r-xl:24px; --r-2xl:32px; --r-pill:100px;

  /* ---- elevation ---- */
  --sh-sm:0 1px 2px rgba(20,40,30,.05),0 8px 20px rgba(20,60,40,.06);
  --sh-md:0 1px 2px rgba(20,40,30,.05),0 14px 34px rgba(20,60,40,.08);
  --sh-lg:0 1px 2px rgba(20,40,30,.05),0 24px 54px rgba(20,60,40,.11);
  --sh-xl:0 2px 6px rgba(20,40,30,.07),0 32px 70px rgba(20,60,40,.20);  /* top-of-stack lift for modals/overlays */

  /* ---- focus tokens. Standard for fields/buttons/controls is the solid offset
     outline (--focus-outline), or --focus-inset for inset contexts — both higher
     contrast, survive forced-colors/high-contrast mode, and match the Apple-style
     ring. The old box-shadow --focus-ring has been retired from the app; the
     reports keep their own copy in reports/report-tokens.css. Only the error ring
     remains here (signature-pad error state). ---- */
  --focus-ring-error:0 0 0 3px color-mix(in srgb, var(--error-600) 18%, transparent);
  /* solid inset ring for consumer fields/controls — pairs with the 1px border to read as a 2px focused/selected outline */
  --focus-inset:0 0 0 1px var(--primary-600) inset;
  /* the same 2px inset in one layer, for borderless inset controls (list/menu rows) that have no 1px border to pair with */
  --focus-inset-2:0 0 0 2px var(--primary-600) inset;
  /* the standard solid focus outline (colour + weight); pair with outline-offset per context (usually 2px) */
  --focus-outline:3px solid var(--primary-600);

  /* ---- icon sizes ---- */
  --icon-sm:16px; --icon-md:20px; --icon-lg:24px;

  --maxw:1160px;
}

/* ---- reset / base ---- */
 *, *::before, *::after { box-sizing: border-box; }
html{-webkit-text-size-adjust:100%;min-width:320px;}
body{margin:0;font-family:var(--font);background:var(--white);color:var(--n-900);
  font-size:var(--t-body);line-height:1.65;-webkit-font-smoothing:antialiased;}
/* form controls don't inherit font-family from body — force it, or buttons/inputs
   fall back to the UA control font (renders as Arial). Components may still override. */
button,input,select,textarea,optgroup{font-family:inherit;}
h1,h2,h3,h4{margin:0;line-height:1.12;letter-spacing:-0.025em;font-weight:800;}
p{margin:0;}
/* Lists start flat — no UA margin or indent. Markers aren't reset here so prose can opt back in (.prose). */
ul,ol{margin:0;padding:0;}
a{color:var(--primary-600);text-decoration:underline;text-underline-offset:2px;}
a:hover{color:#086742;}
img,svg{display:block;max-width:100%;}
:focus-visible{outline:var(--focus-outline);outline-offset:2px;border-radius:4px;}
.skip{position:absolute;left:-9999px;top:0;background:var(--primary-600);color:#fff;padding:12px 18px;z-index:100;border-radius:0 0 10px 0;}
.skip:focus{left:0;}

/* ---- layout helpers ---- */
.wrap{width:100%;max-width:var(--maxw);margin:0 auto;padding:0 var(--sp-5);}
.wrap--narrow{max-width:760px;}
.stack{display:flex;flex-direction:column;}
.section{padding:var(--sp-8) 0;}
@media(min-width:900px){ .section{padding:var(--sp-9) 0;} }
/* section surfaces — white is default; use grey or green-tint to separate sections.
   Rhythm rule: never two coloured bands back-to-back. */
.section--grey{background:var(--n-50);}
.section--tint{background:var(--primary-100);}

/* ---- typography utilities ---- */
.t-eyebrow{font-size:var(--t-caption);letter-spacing:0.06em;text-transform:uppercase;color:var(--primary-600);font-weight:700;}
.t-display{font-size:var(--t-display);font-weight:800;letter-spacing:-0.03em;line-height:1.05;}
.t-h1{font-size:var(--t-h1);font-weight:800;letter-spacing:-0.03em;line-height:1.1;}
.t-h2{font-size:var(--t-h2);font-weight:800;letter-spacing:-0.03em;line-height:1.12;}
.t-h3{font-size:var(--t-h3);font-weight:700;letter-spacing:-0.02em;line-height:1.2;}
.t-h4{font-size:var(--t-h4);font-weight:700;letter-spacing:-0.015em;line-height:1.3;}
.t-lead{font-size:var(--t-lead);color:var(--n-700);line-height:1.6;}
.t-body{font-size:var(--t-body);}
.t-body-lg{font-size:var(--t-lead);line-height:1.6;}   /* 19px body — a deliberate step up from body, chosen by context */
.t-caption{font-size:var(--t-caption);color:var(--n-700);line-height:1.45;}
.t-muted{color:var(--n-700);}

/* ---- buttons ----
   The flat 44px app button is the standard: bare .btn + a colour variant (--primary,
   --neutral, --clear). The marketing website is the exception, adding --lg (56px) and
   --marketing (the shadow-lift treatment). */
.btn{display:inline-flex;align-items:center;justify-content:center;position:relative;white-space:nowrap;gap:9px;min-height:44px;padding:0 18px;border-radius:999px;
  font-family:inherit;font-size:17px;font-weight:700;line-height:1;text-decoration:none;cursor:pointer;border:2px solid transparent;
  transition:transform .2s,filter .2s,background .2s,border-color .2s,color .2s,box-shadow .2s;}
.btn,.btn:hover,.btn:focus{text-decoration:none;}   /* buttons are never underlined links */
.btn:active{transform:scale(.97);}                  /* app press feedback; --marketing overrides to stay lifted */
.btn .arrow{transition:transform .2s;}
/* Per-variant hover emphasis on hover-capable pointers only, so a tap on touch doesn't leave
   a button stuck in its hover look. Keyboard gets the same emphasis via :focus-visible below;
   each rule re-pins text colour so a global a:hover can't recolour it. */
@media (hover:hover){
  .btn--primary:hover{filter:brightness(.92);color:#fff;}
  .btn--secondary:hover{border-color:var(--primary-600);color:var(--primary-600);}
  .btn--secondary-on-dark:hover{border-color:#fff;color:#fff;}
  .btn--primary-on-dark:hover{filter:brightness(.97);color:var(--primary-600);}
  .btn--neutral:hover{background:color-mix(in srgb,var(--n-100) 92%,var(--n-900));color:var(--n-900);}
  .btn--clear:hover{background:var(--n-50);color:var(--n-900);}
  .btn--floating:hover{box-shadow:0 20px 42px rgba(20,40,30,.30),0 8px 18px rgba(20,40,30,.16);}
}
/* keyboard emphasis — same look as hover, ungated; the focus ring itself is the global :focus-visible outline */
.btn--primary{background:var(--primary-600);color:#fff;}
.btn--primary:focus-visible{filter:brightness(.92);color:#fff;}
.btn--secondary{background:#fff;color:var(--n-900);border-color:var(--n-500);}
.btn--secondary:focus-visible{border-color:var(--primary-600);color:var(--primary-600);}
.btn--neutral{background:var(--n-100);color:var(--n-900);}
.btn--neutral:focus-visible{background:color-mix(in srgb,var(--n-100) 92%,var(--n-900));color:var(--n-900);}
.btn--clear{background:transparent;color:var(--n-700);}
.btn--clear:focus-visible{background:var(--n-50);color:var(--n-900);}
/* white pill lifted by shadow rather than fill — for a CTA floating over content (e.g. a
   jump-to button). Its own punchy literal shadow, like --marketing; hover/focus deepen the lift. */
.btn--floating{background:#fff;color:var(--n-900);font-weight:600;box-shadow:0 14px 30px rgba(20,40,30,.24),0 5px 12px rgba(20,40,30,.12);}
.btn--floating:focus-visible{box-shadow:0 20px 42px rgba(20,40,30,.30),0 8px 18px rgba(20,40,30,.16);}
.btn--icon{padding:0;aspect-ratio:1;font-size:var(--icon-md);}   /* square icon-only */
.btn--block{width:100%;}
/* on-dark variants — used on the marketing site's deep panels */
.btn--primary-on-dark{background:#fff;color:var(--primary-600);}
.btn--primary-on-dark:focus-visible{filter:brightness(.97);color:var(--primary-600);}
.btn--secondary-on-dark{background:transparent;color:#fff;border-color:rgba(255,255,255,.45);}
.btn--secondary-on-dark:focus-visible{border-color:#fff;color:#fff;}
/* ---- marketing tier — larger size + shadow-lift (the website's CTAs) ---- */
.btn--lg{min-height:56px;padding:0 32px;font-size:var(--t-lead);}
.btn--primary.btn--marketing{box-shadow:0 10px 22px rgba(10,90,60,.22);}   /* primary keeps its green glow; the other variants carry no shadow */
.btn--marketing:active{transform:translateY(-2px);}   /* press stays lifted rather than taking the base scale */
@media (hover:hover){
  .btn--marketing:hover{transform:translateY(-2px);}
  .btn--marketing:hover .arrow{transform:translateX(3px);}
}
.btn:disabled{opacity:.5;cursor:not-allowed;transform:none;}
/* ---- loading state (opt-in) ----
   Wrap the label in .btn__label and add a .btn__dots of three spans, then toggle
   .is-loading + aria-busy in JS. The label cross-fades down as three dots fade up in
   its place; the hidden label keeps its box (opacity, not display) so the button holds
   its width, and the dots use currentColor so they pick up each variant's text colour. */
.btn__label{display:inline-flex;align-items:center;gap:9px;transition:opacity .1s ease-in,scale .12s ease-in;}
.btn__dots{position:absolute;top:50%;left:50%;translate:-50% -50%;display:flex;align-items:center;gap:5px;opacity:0;scale:.6;pointer-events:none;transition:opacity .2s ease .05s,scale .25s ease .05s;}
.btn__dots span{width:6px;height:6px;border-radius:50%;background:currentColor;animation:btn-dots-bounce .8s ease-in-out infinite;}
.btn__dots span:nth-child(2){animation-delay:.12s;}
.btn__dots span:nth-child(3){animation-delay:.24s;}
.btn.is-loading .btn__label{opacity:0;scale:.75;}
.btn.is-loading .btn__dots{opacity:1;scale:1;}
@keyframes btn-dots-bounce{0%,70%,100%{translate:0 0;}35%{translate:0 -5px;}}
/* reduced-motion: swap the bounce for a calm opacity pulse so the indicator still lives */
@media (prefers-reduced-motion:reduce){
  .btn__dots span{animation:btn-dots-fade 1.2s ease-in-out infinite;}
}
@keyframes btn-dots-fade{0%,80%,100%{opacity:.35;}40%{opacity:1;}}

/* ---- badges ---- */
/* non-interactive status / category marker — pill, green default. (Interactive pills are .choice-btn.) */
.badge{display:inline-flex;align-items:center;gap:7px;font-size:var(--t-caption);font-weight:700;padding:7px 14px;border-radius:var(--r-pill);
  background:var(--primary-50);color:var(--primary-600);}
.badge--blue{background:var(--blue-50);color:var(--blue-700);}
.badge--amber{background:var(--amber-50);color:var(--amber-700);}
.badge--coral{background:var(--coral-50);color:var(--coral-600);}

/* ---- cards ---- */
.card{background:#fff;border:1px solid var(--n-100);border-radius:var(--r-xl);padding:var(--sp-6);box-shadow:var(--sh-sm);}
.card--flat{box-shadow:none;}
.tile{border-radius:var(--r-xl);padding:var(--sp-6) var(--sp-5);}
.tile--green{background:var(--primary-50);}
.tile--blue{background:var(--blue-50);}
.tile--amber{background:var(--amber-50);}
.tile--coral{background:var(--coral-50);}

/* ---- link grid (hub / related / "areas we serve" link cards) ---- */
.linkgrid{display:grid;gap:16px;grid-template-columns:1fr;}
@media(min-width:560px){ .linkgrid{grid-template-columns:repeat(2,1fr);} }
@media(min-width:900px){ .linkgrid--3{grid-template-columns:repeat(3,1fr);} .linkgrid--4{grid-template-columns:repeat(4,1fr);} }
.linkgrid__card{display:flex;flex-direction:column;gap:6px;background:#fff;border:1px solid var(--n-100);
  border-radius:var(--r-xl);padding:var(--sp-5);box-shadow:var(--sh-sm);text-decoration:none;color:inherit;
  transition:transform .2s,border-color .2s,box-shadow .2s;}
.linkgrid__card:hover{border-color:var(--primary-600);box-shadow:var(--sh-md);transform:translateY(-2px);}
.linkgrid__card .go{margin-top:auto;padding-top:4px;color:var(--primary-600);font-weight:700;
  font-size:var(--t-body);display:inline-flex;align-items:center;gap:6px;}
.linkgrid__card:hover .go i{transform:translateX(3px);}
.linkgrid__card .go i{transition:transform .2s;}

/* ---- selectable choice cards (large icon + title + blurb; single-select) ---- */
.choice-cards{display:grid;gap:12px;grid-template-columns:1fr;}
@media(min-width:520px){ .choice-cards{grid-template-columns:repeat(2,1fr);} }
.choice-card{display:flex;flex-direction:column;gap:8px;text-align:left;background:#fff;border:1px solid var(--n-200);border-radius:var(--r-lg);padding:var(--sp-4);cursor:pointer;transition:border-color .15s,background .15s,box-shadow .15s;}
.choice-card__icon{width:48px;height:48px;border-radius:50%;background:var(--n-100);display:grid;place-items:center;color:var(--n-900);font-size:var(--icon-lg);transition:background .15s,color .15s;}
.choice-card__title{font-size:var(--t-body);font-weight:700;color:var(--n-900);}
.choice-card__blurb{font-size:var(--t-caption);color:var(--n-700);line-height:1.45;}
@media (hover:hover){ .choice-card:hover{border-color:var(--primary-500);} }
.choice-card:focus-visible{outline:var(--focus-outline);outline-offset:2px;}
.choice-card[aria-pressed="true"]{border-color:var(--primary-600);background:var(--primary-50);box-shadow:var(--focus-inset);}
.choice-card[aria-pressed="true"] .choice-card__icon{background:var(--primary-100);color:var(--primary-900);}

/* ---- form fields ---- */
.field{display:flex;flex-direction:column;gap:var(--sp-2);}
.field__label{font-size:var(--t-body);font-weight:700;color:var(--n-900);}
.field__label .req{color:var(--error-600);}
.field__hint{font-size:var(--t-caption);color:var(--n-600);}
.field__error{font-size:var(--t-caption);color:var(--error-600);font-weight:600;display:none;align-items:center;gap:6px;}
.field--error .field__error{display:flex;}
.field--error .field__hint{display:none;}
.input,.select,.textarea{font-family:inherit;font-size:var(--t-body);color:var(--n-900);background:#fff;
  min-height:56px;padding:0 16px;border:1px solid var(--n-500);border-radius:var(--r-md);width:100%;
  transition:border-color .15s,box-shadow .15s;}
.textarea{min-height:80px;padding:14px 16px;line-height:1.5;resize:none;field-sizing:content;}
.input::placeholder,.textarea::placeholder{color:var(--n-500);}
.input:focus,.select:focus,.textarea:focus{outline: none; border-color: var(--primary-600); box-shadow: var(--focus-inset);}
.field--error .input,.field--error .select,.field--error .textarea{border-color:var(--error-600);background:var(--error-50);}
/* element-level error (for JS that flags the control directly — matches .field--error) */
.input--error,.textarea--error{border-color:var(--error-600);background:var(--error-50);}
/* focus clears the error styling — green border, white surface, inset ring (same as a normal focus) */
.field--error .input:focus,.field--error .select:focus,.field--error .textarea:focus,
.input--error:focus,.textarea--error:focus{border-color:var(--primary-600);background:#fff;box-shadow:var(--focus-inset);}
.select-wrap{position:relative;}
.select{appearance:none;-webkit-appearance:none;padding-right:44px;cursor:pointer;}
.select-wrap::after{content:"";position:absolute;right:18px;top:50%;width:9px;height:9px;border-right:2px solid var(--n-700);
  border-bottom:2px solid var(--n-700);transform:translateY(-70%) rotate(45deg);pointer-events:none;}
.input-affix{position:relative;display:flex;align-items:center;}
.input-affix .pre{position:absolute;left:16px;color:var(--n-900);pointer-events:none;}
.input-affix .input{padding-left:34px;}

/* ---- floating label (opt-in: compact stacks like the sign-up funnel) ---- */
/* Label rests as the field's prompt and lifts to a small grey caption inside the top
   of the box on focus or once filled. Opt in with .field--floating-label on a normal
   .field — markup order is unchanged; :has() reads the input's state. The input MUST
   carry a placeholder (even " ") so :placeholder-shown can drive the lift; any example
   format is hidden until focus so it doesn't sit under the resting label. Single-line
   .input only — not select/textarea. */
.field--floating-label{position:relative;}
.field--floating-label .input{min-height:60px;padding:24px 16px 8px;}
/* top:30px = half the 60px field height, anchoring the label to the input's centre
   regardless of any hint/error stacked below it */
.field--floating-label .field__label{position:absolute;left:17px;top:30px;transform:translateY(-50%);
  font-weight:400;color:var(--n-600);pointer-events:none;transform-origin:left center;transition:transform .15s ease;}
.field--floating-label:has(.input:focus) .field__label,
.field--floating-label:has(.input:not(:placeholder-shown)) .field__label{transform:translateY(calc(-50% - 13px)) scale(.78);}
.field--floating-label .input:placeholder-shown:not(:focus)::placeholder{color:transparent;}

/* ---- composer: textarea + file attachments ---- */
/* The border lives on .composer__box so the field sits borderless inside it; attachments stack
   below the text and the action row sits outside the box. JS toggles .is-dragging on drag-over. */
.composer{display:flex;flex-direction:column;gap:var(--sp-3);}
.composer__box{position:relative;display:flex;flex-direction:column;background:#fff;border:1px solid var(--n-500);
  border-radius:var(--r-md);transition:border-color .15s,box-shadow .15s;}
.composer__box:focus-within{border-color:var(--primary-600);box-shadow:var(--focus-inset);}
.composer__input{border:0;background:transparent;resize:none;field-sizing:content;min-height:80px;max-height:220px;
  padding:14px 16px 4px;font-family:inherit;font-size:var(--t-body);line-height:1.5;color:var(--n-900);}
.composer__input:focus{outline:none;}
.composer__input::placeholder{color:var(--n-500);}
.composer__files{display:flex;flex-direction:column;gap:6px;}
.composer__files:empty{display:none;}
.composer__file{display:flex;align-items:center;gap:6px;padding:8px 10px;background:var(--n-50);border:1px solid var(--n-200);border-radius:var(--r-sm);}
.composer__file-icon{flex:none;font-size:var(--icon-md);color:var(--n-700);}
.composer__file-name{flex:1;min-width:0;font-size:var(--t-caption);font-weight:600;color:var(--n-900);white-space:nowrap;overflow:hidden;text-overflow:ellipsis;}
.composer__file-size{flex:none;font-size:var(--t-caption);color:var(--n-600);}
.composer__remove{flex:none;display:flex;align-items:center;justify-content:center;width:24px;height:24px;border:0;
  border-radius:var(--r-sm);background:transparent;color:var(--n-700);font-size:16px;cursor:pointer;transition:background .15s,color .15s;}
.composer__remove:hover{background:var(--n-100);color:var(--n-900);}
.composer__remove:focus-visible{outline:var(--focus-outline);outline-offset:2px;}
.composer__drop{position:absolute;inset:0;border-radius:inherit;display:flex;align-items:center;justify-content:center;gap:var(--sp-2);
  background:color-mix(in srgb,var(--primary-50) 90%,#fff);border:1.5px dashed var(--primary-600);color:var(--primary-600);
  font-weight:700;opacity:0;pointer-events:none;transition:opacity .12s;}
.composer__drop i{font-size:22px;}
.composer.is-dragging .composer__drop{opacity:1;}
.composer__actions{display:flex;flex-wrap:wrap;align-items:center;gap:var(--sp-2);}
/* Upload chip: a light green fill sweeps across the chip while a file "uploads" (simulated),
   then it settles to rest. Base is .composer__file; .upload-file adds the fill layer over it.
   Duration is driven per-file by an inline --upload-ms so a batch doesn't finish in lockstep. */
.upload-file{position:relative;overflow:hidden;}
.upload-file .composer__file-icon,
.upload-file .composer__file-name,
.upload-file .composer__remove{position:relative;z-index:1;}
.upload-file__bar{position:absolute;inset:0;z-index:0;width:0;background:color-mix(in srgb,var(--primary-500) 16%,#fff);transition:width var(--upload-ms,1200ms) linear;pointer-events:none;}
.upload-file:not(.is-uploading) .upload-file__bar{display:none;}

/* choice chips — compact pills for inline single/multi-select */
.choice-group{display:flex;flex-wrap:wrap;gap:8px;}
.choice-btn{display:inline-flex;align-items:center;gap:8px;min-height:40px;padding:0 16px;border:1px solid var(--n-500);border-radius:var(--r-pill);
  background:#fff;font-family:var(--font);font-size:var(--t-body);font-weight:400;color:var(--n-900);cursor:pointer;outline:none;
  transition:background .15s,color .15s,border-color .15s,box-shadow .15s;}
.choice-btn i{font-size:var(--icon-md);}
@media (hover:hover){.choice-btn:hover{border-color:var(--primary-600);color:var(--primary-600);background:var(--primary-50);}}
.choice-btn:focus-visible{outline:var(--focus-outline);outline-offset:2px;}
.choice-btn.selected{background:var(--primary-50);border-color:var(--primary-600);box-shadow:var(--focus-inset);color:var(--n-900);}
.choice-group--error .choice-btn{border-color:var(--error-600);}

/* checkbox */
.check{display:flex;align-items:flex-start;gap:12px;cursor:pointer;}
.check input{position:absolute;opacity:0;width:1px;height:1px;}
.check__box{width:24px;height:24px;border-radius:7px;border:1.5px solid var(--n-500);flex:none;display:flex;align-items:center;justify-content:center;transition:.15s;margin-top:1px;}
.check__box svg{opacity:0;color:#fff;transition:.15s;}
.check:has(input:checked) .check__box{background:var(--primary-600);border-color:var(--primary-600);}
.check:has(input:checked) .check__box svg{opacity:1;}
.check:focus-within .check__box{outline:var(--focus-outline);outline-offset:2px;}
.check__text{font-size:var(--t-body);color:var(--n-700);}

/* ---- modal: full-screen on phones, centred on a light frosted scrim from 700px ----
   One overlay primitive, two card shapes:
     .modal__card                 dialog that shrinks to its content (confirm / compose); --wide for room
     .modal__frame > .modal__panel  a fixed-size sheet that scrolls internally — a __bar header
                                    over a scrolling __body (customer switcher, answers modal)
   Mount as a direct child of <body>: a backdrop-filter ancestor would become this fixed
   layer's containing block and trap it. Toggle [hidden] to show/hide. */
.modal{position:fixed;inset:0;z-index:200;display:flex;background:var(--white);}
.modal[hidden]{display:none;}
.modal__head{display:flex;align-items:center;justify-content:space-between;gap:var(--sp-3);}
.modal__actions{display:flex;gap:var(--sp-2);}

/* Phones: the card/sheet fills the screen (more room); a sheet's __body scrolls. */
.modal__card{flex:1;min-height:0;width:100%;display:flex;flex-direction:column;gap:var(--sp-4);
  background:var(--white);padding:var(--sp-5);overflow-y:auto;}
.modal__frame,
.modal__panel{flex:1;min-height:0;min-width:0;display:flex;flex-direction:column;}
.modal__panel{background:var(--white);}
.modal__bar{flex-shrink:0;height:80px;border-bottom:1px solid var(--n-100);}
.modal__bar-inner{width:100%;height:100%;margin:0 auto;padding:0 24px;display:flex;align-items:center;gap:14px;}
.modal__body{flex:1;min-height:0;overflow-y:auto;}

@media (min-width:700px){
  /* Frosted scrim; the card shrinks to content, the sheet sits in a fixed slot. */
  .modal{align-items:center;justify-content:center;padding:24px;
    background:color-mix(in srgb,var(--n-50) 72%,transparent);backdrop-filter:blur(3px);-webkit-backdrop-filter:blur(3px);}
  .modal__card{flex:0 1 auto;max-width:440px;border-radius:var(--r-xl);box-shadow:var(--sh-xl);overflow:visible;}
  .modal__card--wide{max-width:520px;}
  /* The frame is an invisible click-through slot fixing the footprint; the panel top-aligns
     in it and shrinks to content, so its top stays put as a list grows/shrinks during a search. */
  .modal__frame{flex:0 1 auto;width:600px;max-width:100%;height:min(680px,calc(100vh - 48px));pointer-events:none;}
  .modal__panel{flex:0 1 auto;width:100%;max-height:100%;pointer-events:auto;
    border-radius:var(--r-xl);box-shadow:var(--sh-xl);overflow:hidden;}
  .modal__bar{height:68px;}
  .modal__bar-inner{padding:0 20px;}
}

/* ---- nav ---- */
.nav{position:sticky;top:0;z-index:50;background:rgba(255,255,255,.9);backdrop-filter:blur(10px);border-bottom:1px solid var(--n-100);}
.nav--static{position:static;backdrop-filter:none;} /* funnel header: scrolls away with the page to free vertical space on mobile */
.nav--static .nav__inner{justify-content:center;} /* funnel header carries only the logo — centre it */
.nav__inner{display:flex;align-items:center;justify-content:space-between;height:80px;}
.brand{font-size:23px;font-weight:800;letter-spacing:-0.04em;text-decoration:none;color:var(--n-900);display:flex;align-items:center;gap:10px;} /* 23px: deliberate wordmark lockup size — off-scale by design */
.brand:hover{color:var(--n-900);}
.brand .logo{height:22px;width:auto;display:block;}
/* logo art lives in assets/nestie-logo.svg (and nestie-logo-white.svg for the dark footer) */
.nav__links{display:none;gap:30px;list-style:none;align-items:center;}
.nav__links a{text-decoration:none;color:var(--n-700);font-weight:600;font-size:var(--t-body);}
.nav__links a:hover{color:var(--n-900);}
.nav__links a[aria-current="page"]{color:var(--n-900);}
.nav__right{display:flex;align-items:center;gap:36px;}
/* .nav__menu groups the text links at a tight gap; the wider .nav__right gap then falls only before the heavy "See your price" button, so it doesn't crowd the links */
.nav__menu{display:flex;align-items:center;gap:20px;}
@media(min-width:880px){ .nav__links{display:flex;} }

/* ---- quote card ---- */
.quote-card{background:#fff;border:1px solid var(--n-100);border-radius:var(--r-xl);box-shadow:var(--sh-lg);overflow:hidden;}
.quote-card__top{background:var(--primary-600);color:#fff;padding:18px 22px;display:flex;align-items:center;justify-content:space-between;}
.quote-card__top span{font-weight:700;font-size:var(--t-body);}
.quote-card__body{padding:22px;}
.qrow{display:flex;align-items:center;justify-content:space-between;padding:14px 0;border-bottom:1px solid var(--n-100);}
.qrow:first-child{padding-top:2px;}
.qrow__k{font-size:var(--t-body);color:var(--n-700);}
.qrow__v{font-size:var(--t-body);font-weight:700;color:var(--n-900);display:flex;align-items:center;gap:8px;}
.qrow__v svg{color:var(--primary-600);}
.qprice{margin-top:18px;background:var(--primary-100);border-radius:var(--r-lg);padding:20px;display:flex;align-items:center;justify-content:space-between;}
.qprice .lab{font-size:var(--t-caption);text-transform:uppercase;letter-spacing:.05em;color:var(--primary-600);font-weight:700;}
.qprice .fig{font-size:34px;font-weight:800;color:var(--n-900);letter-spacing:-.02em;} /* 34px: decorative price figure — off-scale display one-off by design */
.qprice .fig small{font-size:var(--t-caption);color:var(--n-700);font-weight:600;}

/* ---- panels (feature / closing) ---- */
.panel{background:var(--primary-900);color:#fff;border-radius:var(--r-2xl);padding:var(--sp-7) var(--sp-6);position:relative;overflow:hidden;}
.panel .t-eyebrow{color:var(--feat-eyebrow);}
.panel h2{color:#fff;}
.panel p{color:var(--feat-sub);}
.panel--cta{background:var(--primary-600);text-align:center;}
.panel--cta h2{color:#fff;}
.panel--cta p{color:var(--primary-100);}   /* near-white body on green — AA 4.84:1 */

/* ---- footer ---- */
.footer{background:var(--primary-900);color:#C3D6CB;padding:var(--sp-8) 0 var(--sp-7);}
.footer .brand{color:#fff;}
.footer .brand:hover .logo{filter:brightness(0) invert(1);} /* logo is baked #C3D6CB to match footer text; snaps white on hover like the links */
.footer a{color:#9DB6A9;text-decoration:none;}
.footer a:hover{color:#fff;}
.footer__meta{margin-top:var(--sp-6);padding-top:var(--sp-5);border-top:1px solid rgba(255,255,255,.14);font-size:var(--t-caption);color:#95B0A0;}
.footer__meta a{text-decoration:underline;}

/* ---- trust strip (row of small credibility marks) ---- */
.trust-strip{border-top:1px solid var(--n-100);border-bottom:1px solid var(--n-100);}
.trust-strip__inner{display:flex;flex-wrap:wrap;justify-content:center;gap:12px 30px;padding:18px 0;list-style:none;}
.trust-strip__item{display:flex;align-items:center;gap:9px;font-size:var(--t-body);font-weight:600;color:var(--n-700);white-space:nowrap;}
.trust-strip__item i{color:var(--primary-600);font-size:var(--icon-md);line-height:1;}
.trust-strip__item img{height:20px;width:auto;}

/* ---- tick list (what's included) ---- */
.ticklist{list-style:none;display:flex;flex-direction:column;gap:12px;}
.ticklist li{display:flex;align-items:flex-start;gap:11px;font-size:var(--t-body);line-height:1.5;color:var(--n-900);}
.ticklist li i{flex:none;color:var(--primary-600);font-size:var(--icon-md);line-height:1.4;}

/* ---- FAQ accordion (native details/summary) ---- */
.faq{display:flex;flex-direction:column;max-width:760px;}
.faq__item{border-top:1px solid var(--n-100);}
.faq__item:last-child{border-bottom:1px solid var(--n-100);}
.faq__q{display:flex;align-items:center;justify-content:space-between;gap:16px;padding:22px 0;cursor:pointer;list-style:none;font-weight:700;font-size:var(--t-h4);line-height:1.4;color:var(--n-900);}
.faq__q::-webkit-details-marker{display:none;}
.faq__q:focus-visible{outline:var(--focus-outline);outline-offset:3px;border-radius:6px;}
.faq__icon{flex:none;width:28px;height:28px;border-radius:50%;border:1.5px solid var(--n-500);display:flex;align-items:center;justify-content:center;color:var(--n-700);transition:background .2s,border-color .2s,color .2s;}
.faq__icon i{font-size:var(--icon-sm);transition:transform .25s;}
details[open] .faq__icon{background:var(--primary-600);border-color:var(--primary-600);color:#fff;}
details[open] .faq__icon i{transform:rotate(45deg);}
.faq__a{padding-bottom:24px;max-width:64ch;color:var(--n-700);font-size:var(--t-body);line-height:1.65;}

/* ---- testimonials (quote cards) ---- */
.quotes{display:grid;grid-template-columns:1fr;gap:20px;}
@media(min-width:560px){ .quotes{grid-template-columns:repeat(3,1fr);} }
.quotes blockquote{margin:0;display:flex;flex-direction:column;gap:14px;}
.quotes .stars{color:var(--amber-500);letter-spacing:3px;font-size:15px;}   /* decorative star glyphs — off the type scale by design */
.quotes blockquote p{font-size:var(--t-lead);font-weight:600;line-height:1.5;}
.quotes cite{font-size:var(--t-caption);color:var(--n-700);font-style:normal;font-weight:700;margin-top:auto;}

/* ---- credential chip (for use on deep panels) ---- */
.cred{display:inline-flex;align-items:center;gap:8px;padding:8px 14px;border:1px solid rgba(255,255,255,.18);border-radius:var(--r-pill);font-size:var(--t-caption);font-weight:600;color:var(--feat-sub);}
.cred i{color:var(--feat-eyebrow);font-size:var(--icon-sm);line-height:1;}
.cred img{height:16px;width:auto;}

/* ---- segmented control (single-select pill row) ---- */
.seg{display:inline-flex;background:var(--n-50);border:1px solid var(--n-100);border-radius:var(--r-pill);padding:4px;gap:3px;}
.seg__btn{display:inline-flex;align-items:center;justify-content:center;flex:1 1 auto;gap:8px;padding:11px 18px;border:none;border-radius:var(--r-pill);background:transparent;color:var(--n-700);font-family:inherit;font-size:var(--t-body);font-weight:700;line-height:1.1;white-space:nowrap;cursor:pointer;transition:background .15s,color .15s,box-shadow .15s;}
@media (hover:hover){.seg__btn:hover{color:var(--n-900);}}
.seg__btn[aria-pressed="true"]{background:#fff;color:var(--n-900);box-shadow:0 1px 3px rgba(20,40,30,.16),0 1px 1px rgba(20,40,30,.08);}
.seg__btn:focus-visible{outline:var(--focus-outline);outline-offset:2px;}
/* three-option variant: on narrow screens fill the row and let the longest label wrap, so it never overflows */
@media(max-width:559px){
  .seg--three{display:flex;}
  .seg--three .seg__btn{flex:1 1 0;min-width:0;white-space:normal;padding-left:10px;padding-right:10px;}
}

/* ---- tabs (underline nav — single-select; pattern from the report viewer, on app tokens) ----
   Switches between views/filters of the same surface. Use the segmented control instead for a
   compact in-form toggle. Drive state off aria-selected; the active tab carries the underline.
   Markup: <div class="tabs" role="tablist"><button class="tab" role="tab" aria-selected>Label
   <span class="tab__sub">&middot; detail</span></button>…</div>. The row scrolls if it can't fit. */
.tabs{display:flex;align-items:stretch;gap:4px;overflow-x:auto;overscroll-behavior:none;scrollbar-width:none;border-bottom:1px solid var(--n-100);}
.tabs::-webkit-scrollbar{display:none;}
.tab{flex-shrink:0;position:relative;display:inline-flex;align-items:center;gap:.3em;padding:12px 14px;border:none;background:none;cursor:pointer;font-family:inherit;font-size:var(--t-body);font-weight:600;line-height:1.1;white-space:nowrap;color:var(--n-700);transition:color .15s;}
@media (hover:hover){.tab:hover{color:var(--n-900);}}
.tab:focus-visible{outline:none;box-shadow:var(--focus-inset-2);border-radius:var(--r-sm);}
.tab[aria-selected="true"]{color:var(--n-900);}
/* underline sits at the tab's bottom edge, on the divider line. Keep it at bottom:0 (not
   -1px) so it doesn't overflow the box — overflow-x:auto forces overflow-y to auto, and a
   stray pixel below would make the strip vertically scrollable. Inset left/right to match the
   tab's horizontal padding so the marker lines up with the label, not the full hit area. */
.tab[aria-selected="true"]::after{content:"";position:absolute;left:14px;right:14px;bottom:0;height:3px;background:var(--primary-600);}
.tab__sub{color:var(--n-700);font-weight:400;}

/* ---- stepper ---- */
.stepper{display:inline-flex;align-items:center;gap:4px;background:var(--n-50);border:1px solid var(--n-100);border-radius:var(--r-pill);padding:4px;}
.stepper__btn{width:42px;height:42px;border:none;border-radius:var(--r-pill);background:#fff;box-shadow:0 1px 3px rgba(20,40,30,.16);color:var(--n-900);font-size:var(--icon-md);line-height:1;cursor:pointer;display:flex;align-items:center;justify-content:center;transition:background .15s,box-shadow .15s;}
@media (hover:hover){.stepper__btn:hover:not(:disabled){background:var(--primary-50);}}
.stepper__btn:disabled{background:transparent;box-shadow:none;color:var(--n-600);cursor:default;opacity:.6;}
.stepper__btn:focus-visible{outline:var(--focus-outline);outline-offset:2px;}
.stepper__val{min-width:34px;text-align:center;font-size:var(--t-body);font-weight:800;font-variant-numeric:tabular-nums;}

/* ---- price breakdown rows ---- */
.breakdown{display:flex;flex-direction:column;gap:8px;border-top:1px solid var(--n-100);padding-top:18px;}
.breakdown__row{display:flex;justify-content:space-between;gap:16px;font-size:var(--t-body);line-height:1.5;color:var(--n-700);}
.breakdown__row .amt{font-variant-numeric:tabular-nums;font-weight:700;color:var(--n-900);white-space:nowrap;}
.breakdown__total{display:flex;justify-content:space-between;gap:16px;border-top:1px solid var(--n-100);padding-top:12px;margin-top:4px;font-size:var(--t-body);font-weight:700;color:var(--n-900);}
.breakdown__total .amt{font-variant-numeric:tabular-nums;}

/* ---- split (deposit / balance summary — funnel order cards) ---- */
/* like .breakdown but for splitting a total rather than summing to one; the
   emphasised row (--em) can sit anywhere, not just at the foot. */
.split{display:flex;flex-direction:column;gap:8px;border-top:1px solid var(--n-100);padding-top:16px;}
.split__row{display:flex;justify-content:space-between;gap:16px;font-size:var(--t-body);color:var(--n-700);}
.split__row .amt{font-variant-numeric:tabular-nums;white-space:nowrap;}
.split__row--em{font-weight:700;color:var(--n-900);}
.split__row--em .amt{color:var(--n-900);}

/* ---- soft note (callout) ---- */
.note{display:flex;align-items:flex-start;gap:9px;font-size:var(--t-caption);line-height:1.5;color:var(--n-700);background:var(--primary-50);border-radius:var(--r-md);padding:12px 14px;}
.note i{flex:none;color:var(--primary-600);font-size:var(--icon-sm);line-height:1.3;}

/* ---- locked-price chip (funnel nav) ---- */
.price-chip{display:inline-flex;align-items:center;gap:8px;padding:8px 14px;border-radius:var(--r-pill);background:var(--primary-50);color:var(--primary-600);font-size:var(--t-body);font-weight:700;font-variant-numeric:tabular-nums;white-space:nowrap;}
.price-chip i{font-size:var(--icon-sm);line-height:1;}

/* ---- address combobox ---- */
.combo{position:relative;}
.combo__list{position:absolute;top:calc(100% + 6px);left:0;right:0;z-index:30;background:#fff;border:1px solid var(--n-100);border-radius:var(--r-md);box-shadow:var(--sh-lg);list-style:none;padding:6px;}
.combo__option{padding:11px 12px;border-radius:var(--r-sm);font-size:var(--t-body);line-height:1.4;cursor:pointer;color:var(--n-900);}
.combo__option[aria-selected="true"],.combo__option:hover{background:var(--primary-50);}
.combo__option strong{font-weight:700;}

/* ---- dropdown / context menu (app surfaces — account menu, row actions) ---- */
/* The floating panel; position it from the anchoring context (e.g. an absolutely
   placed wrapper). Toggle open/closed with the [hidden] attribute. */
.menu{display:flex;flex-direction:column;gap:2px;min-width:180px;padding:6px;background:#fff;border:1px solid var(--n-100);border-radius:var(--r-md);box-shadow:var(--sh-md);}
.menu-item{display:flex;align-items:center;gap:10px;width:100%;padding:9px 12px;font-family:inherit;font-size:var(--t-body);color:var(--n-700);background:none;border:none;border-radius:var(--r-sm);text-align:left;text-decoration:none;cursor:pointer;transition:background .15s,color .15s;}
.menu-item:hover{background:var(--n-50);color:var(--n-900);}
.menu-item:focus-visible{background:var(--n-50);color:var(--n-900);outline-offset:-2px;}
.menu-item i{font-size:18px;color:var(--n-700);}
.menu-item--danger,.menu-item--danger i{color:var(--error-600);}
.menu-sep{height:1px;margin:4px 6px;background:var(--n-100);}

/* ---- minimal funnel footer ---- */
.footer-min{border-top:1px solid var(--n-100);padding:var(--sp-5) var(--sp-5);text-align:center;}
.footer-min p{font-size:var(--t-caption);line-height:1.6;color:var(--n-600);max-width:60ch;margin:0 auto;}
.footer-min a{color:var(--n-700);}

/* ---- signature pad (used on the commitment moments — sign & approve) ---- */
/* the canvas overlays the whole surface — incl. the labels below the baseline — so a signature can run over them; padding-top is the clear drawing height above the line */
.sigpad{position:relative;border-radius:var(--r-lg);background:var(--n-50);padding:190px 16px 16px;}
.sigpad canvas{position:absolute;top:0;left:0;border-radius:inherit;touch-action:none;cursor:crosshair;} /* sized to the surface in JS — a replaced element won't stretch to an auto-height box via inset */
.sigpad__baseline{position:absolute;left:16px;right:16px;top:174px;border-top:1px dashed var(--n-500);pointer-events:none;}
.sigpad__clear{position:absolute;top:16px;right:16px;background:none;border:none;padding:4px 0;font-family:inherit;font-size:var(--t-caption);color:var(--n-600);text-decoration:underline;text-underline-offset:3px;cursor:pointer;}
.sigpad__typed{position:absolute;left:16px;width:calc(100% - 32px);top:116px;background:none;border:none;outline:none;padding:0;font-family:'Caveat',cursive;font-size:46px;font-weight:600;line-height:1;color:var(--blue-700);} /* 46px Caveat: decorative signature — off-scale by design */
.sigpad__typed::placeholder{font-family:'Caveat',cursive;color:var(--n-500);}

/* ---- marketing page hero ---- */
.page-hero{padding:48px 0 8px;}
.page-hero__inner{max-width:660px;display:flex;flex-direction:column;gap:14px;}

/* ---- prose (guide / articles) ---- */
.prose{max-width:720px;display:flex;flex-direction:column;gap:18px;}
.prose h2{font-size:var(--t-h3);font-weight:800;letter-spacing:-.02em;margin-top:18px;}
.prose h3{font-size:var(--t-h4);font-weight:700;margin-top:6px;}
.prose p{font-size:var(--t-body);line-height:1.7;color:var(--n-700);}
.prose ul{margin:0;padding-left:22px;display:flex;flex-direction:column;gap:8px;color:var(--n-700);font-size:var(--t-body);line-height:1.6;}
.prose li::marker{color:var(--primary-600);}
.prose strong{color:var(--n-900);font-weight:700;}
.prose a{color:var(--primary-600);font-weight:600;}
.prose .lead{font-size:var(--t-lead);color:var(--n-700);}

/* ---- byline (E-E-A-T author/reviewer) ---- */
.byline{display:flex;align-items:center;gap:11px;font-size:var(--t-caption);color:var(--n-700);padding:14px 0;border-top:1px solid var(--n-100);border-bottom:1px solid var(--n-100);}
.byline img{width:38px;height:38px;border-radius:50%;object-fit:cover;object-position:50% 18%;flex:none;}
.byline b{color:var(--n-900);font-weight:700;}

/* ---- contents list (pillar) ---- */
.toc{list-style:none;padding:18px 22px;background:var(--n-50);border-radius:var(--r-lg);display:flex;flex-direction:column;gap:10px;}
.toc a{color:var(--primary-600);font-weight:600;font-size:var(--t-body);text-decoration:none;}
.toc a:hover{text-decoration:underline;}

/* ---- footer layout (shared) ---- */
/* horizontal nav row across the top (logo left, links right), with the
   brand-led trust card (mission + Playdough contact + CA ANZ credential) below. */
.footer__top{display:flex;flex-direction:column;gap:24px;}
.footer__head{display:flex;flex-wrap:wrap;align-items:center;justify-content:space-between;gap:16px 32px;}
.footer__nav{display:flex;flex-wrap:wrap;align-items:center;gap:10px 22px;}
.footer__nav a{font-size:var(--t-caption);color:#C3D6CB;text-decoration:none;}
.footer__nav a:hover{color:#fff;}
.footer__brandcol{display:flex;flex-direction:column;gap:14px;max-width:46ch;}
.footer__mission{font-size:var(--t-body);line-height:1.55;max-width:34ch;}
.footer__contact{display:flex;flex-direction:column;gap:5px;font-style:normal;}
.footer__contact span,.footer__contact a{font-size:var(--t-caption);line-height:1.6;color:#C3D6CB;}
.footer__contact a{text-decoration:none;width:fit-content;}
.footer__contact a:hover{color:#fff;}
.footer__cred{display:flex;align-items:center;gap:9px;font-size:var(--t-caption);font-weight:600;color:#C3D6CB;}
.footer__cred img{height:20px;width:auto;display:block;}

/* ---- reduced motion ---- */
@media(prefers-reduced-motion:reduce){*{transition:none!important;}}
