/* Ported verbatim from the live site (build.mjs CONSENT_CSS).
 * Accept and Reject are deliberately identical in size, padding, font and
 * border weight - only the fill differs, so rejecting is never harder than
 * accepting. Do not restyle one without the other. */
.cc-banner{position:fixed;left:0;right:0;bottom:0;z-index:9999;display:none;
  background:var(--white);border-top:1px solid var(--line);
  box-shadow:0 -8px 40px -24px rgba(19,21,15,.45)}
.cc-banner.cc-show{display:block}
.cc-inner{max-width:1240px;margin:0 auto;padding:18px clamp(16px,4vw,40px);
  display:flex;align-items:center;gap:clamp(14px,3vw,36px);flex-wrap:wrap}
.cc-copy{margin:0;flex:1 1 320px;min-width:0;font-size:14.5px;line-height:1.6;color:var(--slate)}
.cc-copy a{color:var(--emerald);text-decoration:underline;text-underline-offset:3px}
.cc-copy a:hover{color:var(--ink)}
.cc-actions{display:flex;gap:10px;flex:0 0 auto}
.cc-btn{font-family:var(--body);font-size:14.5px;font-weight:600;line-height:1;
  padding:12px 22px;border-radius:999px;cursor:pointer;border:1px solid var(--ink);
  transition:background .2s,color .2s,border-color .2s;-webkit-appearance:none;appearance:none}
.cc-reject{background:transparent;color:var(--ink)}
.cc-reject:hover{background:var(--mint)}
.cc-accept{background:var(--lime);color:var(--ink);border-color:var(--lime)}
.cc-accept:hover{background:var(--ink);color:var(--lime);border-color:var(--ink)}
.cc-btn:focus-visible{outline:2px solid var(--emerald);outline-offset:2px}

/* The floating WhatsApp button sits bottom-right and would cover the buttons
   while a decision is pending, so it is suppressed until one is made. */
html.cc-open #waFloat{opacity:0;visibility:hidden;pointer-events:none}

@media(max-width:700px){
  .cc-inner{flex-direction:column;align-items:stretch;gap:14px;padding:16px}
  /* flex:1 1 320px is right on a row, but in a column it makes the copy grow to
     fill and the banner swallowed half the viewport. Size it to its content. */
  .cc-copy{flex:0 0 auto;font-size:14px}
  .cc-actions{width:100%}
  .cc-btn{flex:1 1 0;padding:13px 12px}
}

/* Mobile footer composition.
   Desktop is untouched. At 640px the approved CSS drops to two columns, which
   crushes the brand block against the link lists and leaves the legal row on a
   single overflowing line - "Cookie preferences" ran off the viewport and sat
   under the floating WhatsApp button. Restacked into the four readable blocks
   with real dividers, and the legal links now wrap with genuine gaps. */
@media(max-width:640px){
  .foot-grid{grid-template-columns:1fr;gap:34px;padding-bottom:32px}
  .foot-regions{margin-top:26px}
  .foot-bot{flex-direction:column;align-items:flex-start;gap:18px;padding-top:22px;
    border-top:1px solid var(--line);
    /* clears the floating WhatsApp button, which is 56px plus its offset */
    padding-bottom:76px}
  .foot-bot>span:first-child{line-height:1.65}
  /* The approved markup separates these with text middots, which cannot wrap
     sensibly. Hidden, and replaced by real flex gaps. */
  /* Let these wrap into as many rows as they need, with real vertical rhythm.
     Forcing four links onto one line is what pushed them off the viewport. */
  .foot-bot>span:last-child{display:flex;flex-wrap:wrap;gap:14px 20px;width:100%}
  .foot-bot>span:last-child>*{white-space:nowrap}
  .foot-bot>span:first-child{margin-bottom:4px}
}
/* The middot separators are decorative; they should never be read out or
   counted as a link. */
@media(max-width:640px){.foot-bot .sep{display:none}}

/* Card dividers must be straight lines, not curled outlines.
   .niche and .panel each carry border-bottom together with border-radius:18px.
   A bottom-only border follows the radius, so both ends curl upward and the
   divider renders as a shallow rounded rectangle floating under the card -
   which is the stray outline visible under "See how we help ..." on mobile.
   The radius is needed for the hover fill, so the border is replaced with an
   inset line drawn edge to edge. */
/* And every CTA underline must hug its own text, not span its container.
   .link-arrow is inline-flex with white-space:nowrap, so it is content-width
   wherever it is laid out normally. But inline-flex loses to a parent grid's
   justify-items:stretch and to a column flex container's align-items:stretch,
   and this component sits inside both all over the site. Where that happens
   the 1px border runs the entire container width under a short label - most
   visibly as the second of two parallel rules under "See how we help Home
   Services" on mobile, 20px above the card divider, but measured on 36
   route/width combinations: every location page and /work/ at desktop (a
   592px rule under a 118px "View preview"), all four /web-design/ children at
   both widths, and the homepage at mobile.
   width:fit-content restores the component's intended width in every layout
   context and is a no-op wherever it was already correct. */
.link-arrow{width:fit-content}

.niche{position:relative;border-bottom:0 !important}
.niche::after{content:"";position:absolute;left:0;right:0;bottom:0;
  height:1px;background:var(--line);pointer-events:none}

/* Legal pages: centre the measure.
   The body was a lone 68ch column hugging the left of a 1340px wrap, under a
   centred hero — which is why the page read as broken rather than merely
   narrow. Centring it matches the hero and makes the composition deliberate. */
.legal-body{margin-inline:auto}
.legal-body>p:first-child{margin-bottom:26px;color:var(--slate);font-size:14px}

/* Stacked panels: drop the trailing rule.
   .panels is three across on desktop, so each panel's bottom border reads as a
   shared baseline under the row. At 640px they stack into one column and each
   border becomes a loose full-width rule — with the last one floating in space
   with nothing beneath it. Keeping them as separators BETWEEN panels and
   dropping the final one is the fix; removing all of them would lose the
   separation the stacked layout needs. */


/* Desktop footer legal row.
   The links and their middot separators were set with plain word-spacing, so
   they read as one compressed run. Real gaps, and the separators are spaced
   away from the text rather than touching it. */
.foot-bot>span:last-child{display:flex;flex-wrap:wrap;align-items:center;gap:6px 14px}
.foot-bot .sep{color:var(--line);user-select:none}
.foot-bot>span:last-child>a,.foot-bot>span:last-child>button{white-space:nowrap}
/* Declared AFTER the desktop rule on purpose. The mobile block further up this
   file has the same specificity, so whichever comes last wins - and the desktop
   gap was overriding the mobile one at 390px. */
@media(max-width:640px){
  .foot-bot>span:last-child{gap:14px 20px}
}

/* Skip link: off-screen until focused, then a solid forest chip with lime text
   at the top-left. Uses the approved tokens, so it cannot inherit a retired
   colour the way the previous implementation did. */
.skip-link{position:absolute;left:-9999px;top:0;z-index:10000;
  background:var(--forest);color:var(--lime);font-family:var(--body);font-weight:600;
  font-size:15px;padding:12px 20px;border-radius:0 0 12px 0;text-decoration:none}
.skip-link:focus{left:0;outline:2px solid var(--lime);outline-offset:-4px}\nmain:focus{outline:none}

/* Footer "Cookie preferences" is a button because it opens the banner rather
   than navigating. Styled to be indistinguishable from the legal links it sits
   with, so it reads as one row. */
.foot-cc{font:inherit;font-size:13.5px;color:var(--slate);background:none;border:0;
  padding:0;cursor:pointer;text-decoration:none}
.foot-cc:hover{color:var(--ink)}
.foot-cc:focus-visible{outline:2px solid var(--emerald);outline-offset:2px}

/* Form status. Success and error are equally visible — an error that looks
   like a hint is how a lost enquiry goes unnoticed. */
.form-status{margin:14px 0 0;font-size:14.5px;line-height:1.55;padding:10px 12px;
  border-radius:8px;border:1px solid transparent}
.form-status.is-sending{color:var(--slate)}
.form-status.is-ok{color:#14532d;background:#dcfce7;border-color:#86efac}
.form-status.is-err{color:#7f1d1d;background:#fee2e2;border-color:#fca5a5}
