/* ═══════════════════════════════════════════════════
   COMPONENTS — shared across sections
═══════════════════════════════════════════════════ */

/* ═══════════════════════════════════════════════════
   KEYBOARD FOCUS
   The theme relied on the browser default, which differs between
   browsers and disappears against the blue CTA fill. A white ring with
   an offset sits on the page background instead of the element's own
   colour, so it stays visible on every control.

   :focus-visible rather than :focus — the ring appears for keyboard
   navigation and stays out of the way of mouse clicks.
═══════════════════════════════════════════════════ */
:focus-visible {
  outline: 2px solid var(--c-text-1);
  outline-offset: 3px;
}

/* Inputs already signal focus with their own border and ring. */
.form-input:focus-visible { outline: none }

/* ── SKIP LINK ──
   Without it, reaching the content past the navigation takes about
   fourteen tab stops on every page. Off-screen until focused. */
.skip-link {
  position: absolute;
  top: var(--sp-4);
  left: -9999px;
  z-index: 10000;
  padding: var(--sp-3) var(--sp-5);
  background: var(--c-bg-2);
  border: 1px solid var(--c-accent);
  border-radius: var(--r-sm);
  color: var(--c-text-1);
  font-size: var(--fs-300);
  font-weight: var(--fw-semibold);
  text-decoration: none;
}
.skip-link:focus { left: var(--sp-4) }

/* The skip target takes focus without showing a ring around the whole page. */
#main:focus { outline: none }

/* Labels that only screen readers need — the heading WordPress puts above
   pagination, for one. Clipped rather than display:none, which would take it
   out of the accessibility tree along with the layout. */
.screen-reader-text {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}

/* ── SCROLL REVEAL ── */
.reveal {
  opacity: 0;
  transform: translateY(32px);
  transition: opacity var(--dur-slow) var(--ease-out),
              transform var(--dur-slow) var(--ease-out);
}
.reveal.visible { opacity: 1; transform: translateY(0) }
.reveal-d1 { transition-delay: .1s }
.reveal-d2 { transition-delay: .2s }
.reveal-d3 { transition-delay: .3s }
.reveal-d4 { transition-delay: .4s }
.reveal-d5 { transition-delay: .5s }
.reveal-fade { opacity: 0; transition: opacity .8s ease }
.reveal-fade.visible { opacity: 1 }

/* ── BUTTONS ── */
.btn-p {
  display: inline-flex; align-items: center; gap: var(--sp-2);
  padding: 11px 28px;
  border-radius: var(--r-md);
  background: var(--c-accent-strong);
  color: #fff;
  font-family: var(--f-body);
  font-size: var(--fs-300);
  font-weight: var(--fw-semibold);
  letter-spacing: .01em;
  border: none;
  text-decoration: none;
  transition: background var(--dur-base), transform var(--dur-fast), box-shadow var(--dur-base);
}
.btn-p:hover {
  background: var(--c-accent-hover);
  transform: translateY(-2px);
  box-shadow: 0 12px 32px rgba(var(--c-accent-rgb), .45);
}

/* Desktop only. Below 640 the sections that stack their buttons already give
   them the full width, and a floor of 200px inside a narrow card — the hero's
   own CTA is one — would push it past its container. 641 rather than a
   max-width query because this adds a rule for wide screens instead of undoing
   one for narrow ones; it is the only min-width query in the theme. */
@media (min-width: 641px) {
  .btn-p {
    min-width: 200px;
    justify-content: center;
  }
}
.btn-g {
  display: inline-flex; align-items: center; gap: var(--sp-2);
  /* 11px against .btn-p's 11px, minus the 1px border this one carries,
     so the two buttons come out the same height side by side. */
  padding: 10px 24px;
  border-radius: var(--r-md);
  background: transparent;
  color: var(--c-text-3);
  font-family: var(--f-body);
  font-size: var(--fs-300);
  font-weight: var(--fw-medium);
  border: 1px solid var(--c-border);
  text-decoration: none;
  transition: color var(--dur-base), border-color var(--dur-base);
}
.btn-g:hover { color: var(--c-text-1); border-color: var(--c-border-hover) }

/* ── EYEBROW LABEL ──
   One spacing rule for the whole project. Every section used to set its own —
   16px here, 20px there, 28px in the hero — and each also had to restate
   display:block, because margin-bottom does nothing on an inline element and a
   span is inline. Both now belong to the label itself. */
.lbl {
  display: block;
  margin: 0 0 var(--sp-5);
  font-family: var(--f-body);
  font-size: var(--fs-100);
  font-weight: var(--fw-semibold);
  letter-spacing: var(--ls-wider);
  text-transform: uppercase;
  color: var(--c-accent);
}

/* ── SECTION HEADING ──
   One rule for every "this is what this band of the page is about" heading,
   on the home page and on the service pages alike. It used to be eight copies
   of the same six declarations in eight stylesheets, which is how two of them
   ended up 8px and 4px away from the rest without anybody deciding that.

   It lives here rather than in the section files because section stylesheets
   are enqueued after this one and depend on it: a font-size left behind in
   any of them would quietly win on equal specificity and the drift would come
   straight back.

   Section files keep their own margins — spacing below a heading is the
   section's business, its size is not.

   The clamp stops at 46px rather than reaching --fs-700's 52. Page titles
   (.article-h1, .prose-h1, .cs-h1, .e404-h1) do take --fs-700, so a page's own
   title still outranks the headings inside it. ── */
.problem-h2,
.svc-c-h2,
.process-a-h2,
.articles-h2,
.sc-section-h2,
.work-b-h2,
.cta-f-h2,
.sp-section-h2 {
  font-family: var(--f-display);
  font-size: clamp(28px, 3.2vw, 46px);
  font-weight: var(--fw-black);
  letter-spacing: -.045em;
  line-height: 1.05;
  color: var(--c-text-1);
}

/* ── "VIEW ALL" LINK — used by work and articles ── */
.work-a-link {
  font-size: var(--fs-200);
  color: var(--c-accent);
  font-weight: var(--fw-semibold);
  text-decoration: none;
  transition: opacity var(--dur-base);
}
.work-a-link:hover { opacity: .7 }

/* ── FORM PRIMITIVES ── */
.form-field { display: flex; flex-direction: column; gap: 6px }
.form-label {
  font-size: var(--fs-200);
  font-weight: var(--fw-semibold);
  color: var(--c-text-3);
  letter-spacing: .04em;
  line-height: 1.7;
  margin-bottom: 0;
}
.form-input {
  background: var(--c-bg-3);
  border: 1px solid var(--c-border);
  border-radius: var(--r-md);
  padding: 12px 16px;
  font-family: var(--f-body);
  font-size: var(--fs-300);
  color: var(--c-text-2);
  outline: none;
  resize: none;
  transition: border-color var(--dur-base), box-shadow var(--dur-base);
}
.form-input::placeholder { color: var(--c-text-4) }
.form-input:focus {
  border-color: var(--c-accent);
  box-shadow: 0 0 0 3px var(--c-focus-ring);
}
.form-textarea { min-height: 100px }
.form-submit {
  width: 100%;
  padding: 14px;
  border-radius: var(--r-md);
  background: var(--c-accent-strong);
  color: #fff;
  font-family: var(--f-body);
  font-size: var(--fs-300);
  font-weight: var(--fw-semibold);
  letter-spacing: .01em;
  border: none;
  transition: background var(--dur-base), transform var(--dur-fast), box-shadow var(--dur-base);
}
/* Matched to .btn-p rather than kept as its own thing. Both are the primary
   action inside page content, and two different lifts read as an accident
   instead of a decision. The header CTA keeps its quieter hover on purpose:
   it sits in sticky chrome, where a button that jumps is a button that
   nags. */
.form-submit:hover {
  background: var(--c-accent-hover);
  transform: translateY(-2px);
  box-shadow: 0 12px 32px rgba(var(--c-accent-rgb), .45);
}
/* Sits under a submit button and needs air between the two. The source
   carried this as an inline margin, which the port dropped along with the
   other inline styles. */
.form-note {
  margin-top: var(--sp-3);
  font-size: var(--fs-200);
  color: var(--c-text-4);
  line-height: 1.4;
  text-align: center;
}
.form-note a { color: var(--c-text-3) }
.form-note a:hover { color: var(--c-accent) }

/* The honeypot. Moved out of sight rather than display:none — a bot worth
   worrying about skips a hidden field, and the point is that it does not.
   Kept out of the tab order in the markup, so nobody using a keyboard lands
   in it either. */
.form-hp {
  position: absolute;
  left: -9999px;
  width: 1px;
  height: 1px;
  overflow: hidden;
}

/* The result of a submission. Two states, and the failed one has to be
   readable rather than decorative: it carries the address the visitor needs
   in order not to lose what they wrote. */
.form-result {
  margin-bottom: var(--sp-5);
  padding: var(--sp-4) var(--sp-5);
  border-radius: var(--r-md);
  border: 1px solid var(--c-border);
  font-size: var(--fs-200);
  line-height: 1.6;
}
.form-result--ok {
  background: var(--c-success-soft);
  border-color: rgba(var(--c-success-rgb), .35);
  color: var(--c-text-2);
}
.form-result--bad {
  background: rgba(245, 158, 11, .10);
  border-color: rgba(245, 158, 11, .35);
  color: var(--c-text-2);
}
.form-result a { color: var(--c-accent) }

/* ── IMAGE PLACEHOLDER ── */
.img-ph {
  position: relative;
  overflow: hidden;
  background: linear-gradient(145deg, var(--c-bg-3) 0%, var(--c-bg-4) 100%);
}
.img-ph::before {
  content: '';
  position: absolute;
  inset: 0;
  z-index: 0;
  pointer-events: none;
  opacity: .55;
  background-image:
    linear-gradient(var(--c-border) 1px, transparent 1px),
    linear-gradient(90deg, var(--c-border) 1px, transparent 1px);
  background-size: 28px 28px;
}

/* ── BREADCRUMBS.
   Shared by the service category pages and, later, the service pages —
   which is why it sits here rather than in a section stylesheet. ── */
.sp-breadcrumb {
  max-width: var(--container);
  margin: 0 auto;
  padding: var(--sp-5) var(--container-pad);
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--sp-2);
  font-size: var(--fs-200);
  font-weight: var(--fw-medium);
  color: var(--c-text-4);
}
.sp-breadcrumb a { color: var(--c-text-4); text-decoration: none; transition: color var(--dur-base) }
.sp-breadcrumb a:hover { color: var(--c-accent) }
.sp-breadcrumb-sep { opacity: .4 }
.sp-breadcrumb-cur { color: var(--c-text-3) }

@media (max-width: 640px) {
  .sp-breadcrumb { padding: var(--sp-4) var(--sp-6) }
}

/* ── BACK TO TOP ── */
#btt {
  position: fixed; bottom: var(--sp-8); right: var(--sp-8); z-index: 500;
  width: 44px; height: 44px;
  border-radius: var(--r-md);
  background: var(--c-bg-2);
  border: 1px solid var(--c-border);
  color: var(--c-text-3);
  display: grid; place-items: center;
  opacity: 0; pointer-events: none;
  transform: translateY(10px);
  box-shadow: 0 4px 20px var(--c-shadow-md);
  transition: opacity var(--dur-base), transform var(--dur-base),
              background var(--dur-base), border-color var(--dur-base), color var(--dur-base);
}
#btt.visible { opacity: 1; pointer-events: auto; transform: translateY(0) }
#btt:hover {
  background: rgba(var(--c-accent-rgb), .15);
  border-color: rgba(var(--c-accent-rgb), .35);
  color: var(--c-accent);
}
#btt svg { width: 16px; height: 16px }

/* ── KEYFRAMES ── */
@keyframes ticker    { from { transform: translateX(0) } to { transform: translateX(-50%) } }
@keyframes pulse-dot { 0%, 100% { opacity: 1; transform: scale(1) } 50% { opacity: .4; transform: scale(.7) } }
@keyframes float-y   { 0%, 100% { transform: translateY(0) } 50% { transform: translateY(-10px) } }
@keyframes line-grow { from { transform: scaleX(0); transform-origin: left } to { transform: scaleX(1); transform-origin: left } }
@keyframes glow-in   { from { opacity: 0; transform: scale(.96) } to { opacity: 1; transform: scale(1) } }
@keyframes count-in  { from { opacity: 0; transform: translateY(14px) } to { opacity: 1; transform: none } }
@keyframes shimmer   { 0% { background-position: -200% 0 } 100% { background-position: 200% 0 } }

/* ═══════════════════════════════════════════════════
   CUSTOM CURSOR — fine pointers only.
   On touch there is no cursor to replace, and hiding the
   native pointer on controls hurts usability.
═══════════════════════════════════════════════════ */
@media (pointer: fine) {
  body { cursor: none }
  a, button, input, textarea, select, label { cursor: none }

  #cur {
    position: fixed; z-index: 9999;
    width: 10px; height: 10px;
    background: var(--c-accent);
    border-radius: 50%;
    pointer-events: none;
    transform: translate(-50%, -50%);
    transition: width var(--dur-fast), height var(--dur-fast), background var(--dur-fast);
  }
  #cur-ring {
    position: fixed; z-index: 9998;
    width: 30px; height: 30px;
    border: 1.5px solid var(--c-accent);
    border-radius: 50%;
    opacity: .45;
    pointer-events: none;
    transform: translate(-50%, -50%);
    transition: width var(--dur-fast) var(--ease-out), height var(--dur-fast), border-color .12s;
  }
  body.c-hover #cur      { width: 6px; height: 6px; background: var(--c-text-1) }
  body.c-hover #cur-ring { width: 42px; height: 42px; border-color: var(--c-text-1); opacity: .3 }
  body.c-cta   #cur      { width: 42px; height: 42px; background: var(--c-accent); opacity: .1 }
  body.c-cta   #cur-ring { width: 42px; height: 42px; border-color: var(--c-accent) }
}

/* Coarse pointers keep the native cursor and never render the custom one. */
@media not (pointer: fine) {
  #cur, #cur-ring { display: none }
}
