/* ==========================================================================
   Sanctuary v2, page-scoped styles: contact.html. Loads AFTER styles.css and
   only extends it. Every value traces to design/brands/sanctuary.md (the kit)
   or to a locked value already in styles.css. Inner pages are CALM: static
   world-light, no world flips, no pinned stacks (kit: signature is home only).
   House rule: no em or en dashes anywhere in this file.
   ========================================================================== */

/* ---- Page hero (system vocabulary from the home hero) ---- */
.page-hero {
  padding: 96px 48px 64px;   /* kit: section pads {76, 96, 128}; page gutter 48 */
  text-align: center;
}
.page-eyebrow {
  font-size: 24px;           /* locked system: hero eyebrow 24px (styles.css .hero-eyebrow) */
  font-weight: 400;
  opacity: .82;              /* locked system: eyebrow sits quieter than the h1 */
}
.page-h1 {
  font-size: 80px;           /* kit: hero h1 80px (ref typeScale) */
  line-height: 1.1;          /* kit: ref h1 88px at 80 = 1.1 */
  letter-spacing: -2px;      /* kit: ref h1 letter-spacing -2px */
  font-weight: 400;          /* kit: hierarchy by SIZE at weight 400 */
  margin: 20px auto 0;
}
.you {
  color: var(--accent);      /* kit: accent = the "you." lockup, a sanctioned small saturated moment */
}
.page-lead {
  max-width: 760px;          /* derived: calm lead measure inside the ref 1344 content box */
  margin: 32px auto 0;
  font-size: 20px;           /* derived: one step over body 16 (locked sheet-row 20 is the same step) */
  line-height: 1.6;
}

/* ---- Primary contact card ---- */
.contact-primary {
  padding: 0 48px 76px;      /* kit: page gutter 48; section pad 76 */
}
.primary-card {
  border-radius: 32px;       /* kit: cards flat filled, radius 32, border NONE, shadow NONE */
  padding: 48px;             /* locked system: footer card pad 48 */
  max-width: 1344px;         /* kit: ref widest content box 1344 */
  margin: 0 auto;
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 32px;                 /* locked system: card gap 32 */
}
.cell-label {
  font-size: 16px;           /* kit: body 16 */
  color: var(--muted-ink);   /* locked system: muted labels (styles.css .col-head) */
  margin-bottom: 8px;        /* derived: half the base step 16 */
}
.cell-value {
  font-size: 26px;           /* locked system: card caption scale 26 (styles.css .card-cap) */
  line-height: 1.3;          /* locked system: caption leading */
  overflow-wrap: anywhere;   /* engineering: no horizontal overflow at 375 */
}
a.cell-value { transition: opacity .15s ease; } /* locked system: link hover treatment (styles.css .col a) */
a.cell-value:hover { opacity: .7; }

/* ---- Offices grid ---- */
.offices {
  padding: 76px 48px 0;      /* kit: section pad 76 */
}
.offices .display { margin-bottom: 48px; } /* kit: head-to-grid step 48 */
.office-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 32px;                 /* locked system: card gap 32 */
  max-width: 1344px;         /* kit: ref widest content box 1344 */
  margin: 0 auto;
}
.office-card {
  border-radius: 32px;       /* kit: card radius 32, no border, no shadow */
  padding: 32px;             /* locked system: card pad 32 (styles.css .card-cap) */
  display: flex;
  flex-direction: column;
}
.office-card h3 {
  font-size: 24px;           /* locked system: eyebrow scale 24 as card head; weight stays 400 */
  font-weight: 400;
  letter-spacing: -0.5px;    /* derived: light display tracking at the 24 step */
}
.office-addr {
  font-size: 16px;           /* kit: body 16 */
  line-height: 1.6;          /* derived: address leading, one step over body 1.5 */
  margin-top: 12px;          /* locked system: nav-right gap 12 as the tight step */
}
.office-links {
  display: flex;
  flex-direction: column;
  gap: 6px;                  /* locked system: nav-item gap 6 as the tightest link step */
  margin-top: 24px;          /* kit: radius scale member 24 as the block step */
  padding-top: 20px;
}
.office-links a {
  font-size: 16px;           /* kit: body 16 */
  text-decoration: underline;         /* derived: contact links must read as live; ink stays the link color (kit: exact accent never carries body text) */
  text-underline-offset: 3px;
  text-decoration-thickness: 1px;
  overflow-wrap: anywhere;   /* engineering: no horizontal overflow at 375 */
  transition: opacity .15s ease;      /* locked system: link hover treatment */
}
.office-links a:hover { opacity: .7; }

/* ---- Portal + write-to-us cards: honest entries only ---- */
.contact-actions {
  padding: 96px 48px 32px;   /* kit: section pad 96 */
}
.action-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 32px;                 /* locked system: card gap 32 */
  max-width: 1344px;         /* kit: ref widest content box 1344 */
  margin: 0 auto;
}
.action-card {
  border-radius: 32px;       /* kit: card radius 32, no border, no shadow */
  padding: 48px;             /* locked system: footer card pad 48 */
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  min-height: 300px;         /* derived: holds the two cards level, about half a ref card height 571 */
}
.action-card h2 {
  font-size: 32px;           /* locked system: mobile display step 32 reused as card display type */
  font-weight: 400;          /* kit: hierarchy by SIZE at weight 400 */
  letter-spacing: -0.8px;    /* locked system: mobile display tracking */
}
.action-card p {
  font-size: 16px;           /* kit: body 16 */
  line-height: 1.5;          /* locked system: body leading */
  max-width: 420px;          /* derived: calm measure inside the card */
  margin-top: 16px;          /* kit: spacing base 16 */
}
.action-card .pill { margin-top: auto; }
.pill-red {
  background: var(--accent-cta); /* kit: primary pill = accent-cta with white text, 5.86:1 AA */
  color: #FFFFFF;
}
.pill-red:hover {
  background: #AE1217;       /* kit: accent-cta hover state */
  opacity: 1;
}
.pill-soft {
  background: var(--line);   /* Round-13: secondary pill = light gray line fill with ink text */
  color: var(--ink);
}

/* ---- Mobile (locked breakpoint 820; kit: mobile gutter 20, h1 28) ---- */
@media (max-width: 1100px) {
  .office-grid { grid-template-columns: repeat(2, 1fr); } /* derived: two-up before the single column */
  .primary-card { grid-template-columns: 1fr; }
}
@media (max-width: 820px) {
  .page-hero { padding: 56px 20px 40px; } /* kit: mobile gutter 20 */
  .page-eyebrow { font-size: 16px; }      /* locked system: mobile eyebrow 16 */
  .page-h1 {
    font-size: 28px;         /* kit: mobile h1 28px */
    letter-spacing: -0.7px;  /* locked system: mobile h1 tracking fingerprint, rounded */
  }
  .page-lead { font-size: 16px; margin-top: 20px; }
  .contact-primary { padding: 0 20px 48px; }
  .primary-card { padding: 32px 24px; gap: 24px; }
  .cell-value { font-size: 20px; }        /* locked system: sheet-row scale 20 */
  .offices { padding: 48px 20px 0; }
  .offices .display { margin-bottom: 32px; }
  .office-grid { grid-template-columns: 1fr; gap: 16px; } /* kit: spacing base 16 on mobile */
  .contact-actions { padding: 64px 20px 16px; }
  .action-grid { grid-template-columns: 1fr; gap: 16px; }
  .action-card { padding: 32px 24px; min-height: 0; }
  .action-card .pill { margin-top: 32px; }
  .action-card h2 { font-size: 24px; letter-spacing: -0.5px; } /* locked system: eyebrow scale 24 */
}

/* ==========================================================================
   Inner-page revamp (2026-07-11, Thomas verdict: inner pages alive, facts real).
   Catalog components re-tokened to the kit; every effect is JS-gated
   progressive enhancement, so no JS and reduced motion keep the calm page.
   ========================================================================== */

/* ---- catalog 016 AnimatedNumber: numeral slot in the offices heading ---- */
.count {
  display: inline-block;
  text-align: center;
  font-variant-numeric: tabular-nums; /* engineering: the digit holds width while the spring rolls */
}

/* ---- Staggered scroll reveals (JS adds .pre-reveal only below the fold; no-JS never hides) ---- */
@media (prefers-reduced-motion: no-preference) {
  .pre-reveal {
    opacity: 0;
    transform: translateY(26px);
  }
  .pre-reveal.is-in {
    opacity: 1;
    transform: none;
    transition: opacity .65s var(--ease-house), transform .65s var(--ease-house); /* kit: primary house curve */
  }
}

/* ---- catalog 011 Tilt Card: subtle tilt + cream sheen on the office cards (JS drives the vars) ---- */
.office-card {
  position: relative;
  overflow: hidden;          /* the sheen respects the 32px card radius */
}
.office-card::after {
  /* catalog glare re-toned: cream sheen, never a shadow (kit: cards carry no shadow) */
  content: "";
  position: absolute;
  inset: 0;
  border-radius: 32px;
  background: radial-gradient(circle at var(--glx, 50%) var(--gly, 50%), rgba(255, 255, 255, .34) 0%, rgba(255, 255, 255, 0) 70%);
  opacity: 0;
  transition: opacity .2s ease-out; /* catalog: easeOut .2s */
  pointer-events: none;
}
.office-card.tilting::after { opacity: 1; }
.office-card .office-links { position: relative; z-index: 1; } /* links stay clickable over the sheen layer edge cases */

/* ---- catalog 020 Interactive Gradient, CSS variant, on the portal card ----
   Three kit-pastel blobs on the coral fill: two drift on keyframes, one follows
   the pointer via --gx/--gy (contact.js). Every blob is a LIGHTER tint of the
   coral card (blush, sand, cream), so ink text contrast only ever improves. */
@property --gx { syntax: "<percentage>"; inherits: false; initial-value: 30%; }
@property --gy { syntax: "<percentage>"; inherits: false; initial-value: 25%; }
.grad-card { position: relative; overflow: hidden; }
.grad-card > * { position: relative; z-index: 1; }
.grad-bg {
  position: absolute;
  inset: 0;
  z-index: 0;
  pointer-events: none;
}
.grad-bg i {
  position: absolute;
  inset: -20%;               /* blobs overscan the card so drift never shows an edge */
  display: block;
}
.grad-follow {
  background: radial-gradient(circle at var(--gx) var(--gy), var(--card-blush) 0%, rgba(240, 240, 240, 0) 55%);
  transition: --gx .6s ease-out, --gy .6s ease-out; /* catalog spring settle, CSS-typed variant */
}
.grad-a {
  background: radial-gradient(circle at 82% 18%, var(--card-sand) 0%, rgba(235, 235, 235, 0) 48%);
  animation: grad-drift-a 18s ease-in-out infinite alternate;
}
.grad-b {
  background: radial-gradient(circle at 12% 88%, rgba(245, 245, 245, .85) 0%, rgba(245, 245, 245, 0) 42%);
  animation: grad-drift-b 26s ease-in-out infinite alternate;
}
@keyframes grad-drift-a {
  from { transform: translate(0, 0); }
  to   { transform: translate(-7%, 9%); }
}
@keyframes grad-drift-b {
  from { transform: translate(0, 0); }
  to   { transform: translate(8%, -7%); }
}

/* ---- catalog 013 Icon Slide In: pill CTAs, arrow slides in + fill bubble blooms (pure CSS) ---- */
.pill-slide {
  position: relative;
  overflow: hidden;
}
.pill-slide .pill-label {
  position: relative;
  z-index: 2;
  transition: transform .5s cubic-bezier(.34, 1.08, .64, 1); /* catalog spring {bounce .1, .5s} */
}
.pill-slide .pill-arrow {
  position: absolute;
  z-index: 2;
  top: 50%;
  margin-top: -7px;
  right: -20px;              /* catalog: icon parks offscreen right */
  opacity: 0;
  transition: right .5s cubic-bezier(.34, 1.08, .64, 1), opacity .35s ease;
}
.pill-slide::before {
  /* catalog fill bubble: a circle blooms from bottom center to flood the pill */
  content: "";
  position: absolute;
  z-index: 1;
  left: 50%;
  bottom: -8px;
  width: 8px;
  height: 8px;
  border-radius: 96px;
  transform: translateX(-50%);
  background: var(--pill-bubble, rgba(26, 26, 26, .12));
  transition: width .5s cubic-bezier(.34, 1.08, .64, 1), height .5s cubic-bezier(.34, 1.08, .64, 1), bottom .5s cubic-bezier(.34, 1.08, .64, 1);
}
.pill-slide:hover::before,
.pill-slide:focus-visible::before {
  width: 130%;
  height: 240px;
  bottom: -70px;
}
.pill-slide:hover .pill-arrow,
.pill-slide:focus-visible .pill-arrow { right: 16px; opacity: 1; }
.pill-slide:hover .pill-label,
.pill-slide:focus-visible .pill-label { transform: translateX(-11px); }
.pill-red.pill-slide { --pill-bubble: #AE1217; }        /* kit: accent-cta hover state as the bloom */
.pill-red.pill-slide:hover { background: var(--accent-cta); } /* the bubble carries the hover, not the flat swap */
.pill-soft.pill-slide { --pill-bubble: var(--card-coral); }   /* kit pastel; ink on coral holds 4.6:1 */

/* ---- Reduced motion: kill every revamp effect (tilt and reveals are JS-gated off;
        the gradient freezes to its resting frame; pill states snap instantly) ---- */
@media (prefers-reduced-motion: reduce) {
  .grad-a, .grad-b { animation: none; }
  .grad-follow,
  .pill-slide .pill-label,
  .pill-slide .pill-arrow,
  .pill-slide::before,
  .office-card::after,
  .count { transition: none; }
}

/* ==========================================================================
   Richness layer (2026-07-12, Thomas verdict: inner pages too plain, under-use
   the catalog). Self-contained under the site CSP (no external tiles, scripts,
   or frames): the map is an inline SVG locator of Zimbabwe, real boundary and
   real city coordinates, re-tokening catalog 155 Multi Location Map (circle
   markers, hover expand, click popup, cluster count). House rule: no em dashes.
   ========================================================================== */

/* ---- catalog 155 Multi Location Map: inline-SVG Zimbabwe locator centrepiece ---- */
.offices-map {
  padding: 76px 48px 0;      /* kit: section pad 76; page gutter 48 */
}
.map-frame {
  position: relative;
  max-width: 1040px;
  margin: 0 auto;
  border-radius: 32px;       /* kit: card radius 32, no border, no shadow */
  padding: 24px;
  background:
    radial-gradient(120% 120% at 50% 0%, var(--card-cream) 0%, var(--world-light) 70%);
  overflow: hidden;
}
/* catalog 062 Border Beam: a soft accent rim glow that follows the pointer along
   the frame edge (map-frame masks to a ring, contact.js writes --bx / --by). */
.map-beam {
  position: absolute;
  inset: 0;
  border-radius: 32px;
  padding: 2px;
  pointer-events: none;
  background: radial-gradient(180px circle at var(--bx, 50%) var(--by, 0%), var(--accent) 0%, rgba(238, 29, 35, 0) 62%);
  -webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
          mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
  -webkit-mask-composite: xor;
          mask-composite: exclude;
  opacity: 0;
  transition: opacity .35s ease;
  z-index: 3;
}
.map-frame.beam-on .map-beam { opacity: .85; }
.zw-map {
  display: block;
  width: 100%;
  height: auto;
  position: relative;
  z-index: 1;
}
.zw-shape {
  fill: url(#zw-fill);
  stroke: var(--accent-cta);
  stroke-width: 2;
  stroke-opacity: .5;
  stroke-linejoin: round;
}
.zw-pin { cursor: pointer; }
.zw-pin .pin-mark {
  transform-box: fill-box;
  transform-origin: center;
  transition: transform .3s var(--ease-house); /* catalog: circle marker hover expand */
}
.zw-pin:hover .pin-mark,
.zw-pin:focus-visible .pin-mark,
.zw-pin.is-active .pin-mark { transform: scale(1.28); } /* catalog radius 10 -> ~13 */
.zw-pin:focus { outline: none; }
.zw-pin:focus-visible .pin-dot { stroke: var(--ink); }
.pin-halo {
  fill: var(--accent);
  opacity: .16;
  transform-box: fill-box;
  transform-origin: center;
}
@media (prefers-reduced-motion: no-preference) {
  .pin-halo { animation: pin-pulse 2.6s ease-in-out infinite; }
  .zw-pin:nth-of-type(2) .pin-halo { animation-delay: .4s; }
  .zw-pin:nth-of-type(3) .pin-halo { animation-delay: .8s; }
  .zw-pin:nth-of-type(4) .pin-halo { animation-delay: 1.2s; }
  .zw-pin:nth-of-type(5) .pin-halo { animation-delay: 1.6s; }
}
@keyframes pin-pulse {
  0%, 100% { transform: scale(1); opacity: .16; }
  50%      { transform: scale(1.5); opacity: .05; }
}
.pin-dot {
  fill: var(--accent-cta);   /* kit: saturated accent moment on the markers */
  stroke: var(--surface);    /* kit: cream ring, like the ref circle marker white ring */
  stroke-width: 3;
}
.pin-badge circle { fill: var(--ink); }
.pin-badge text {
  fill: var(--ink-inverse);
  font-size: 20px;
  font-weight: 400;
  text-anchor: middle;
  dominant-baseline: central;
}
.pin-label {
  fill: var(--ink);
  font-size: 25px;
  font-weight: 400;
  letter-spacing: -.4px;
  paint-order: stroke;
  stroke: var(--surface);    /* a cream halo keeps labels legible over the fill */
  stroke-width: 5;
  stroke-linejoin: round;
}
/* JS popup card (catalog 155 popup: name bold + address softer) */
.map-tip {
  position: absolute;
  z-index: 4;
  max-width: 260px;
  padding: 12px 16px;
  border-radius: 16px;
  background: var(--surface);
  color: var(--ink);
  pointer-events: none;
  opacity: 0;
  transform: translate(-50%, -8px);
  transition: opacity .18s ease, transform .18s ease;
  box-shadow: 0 6px 20px rgba(26, 26, 26, .16);
}
.map-tip.show { opacity: 1; transform: translate(-50%, -14px); }
.map-tip .tip-name { font-size: 16px; margin-bottom: 2px; }
.map-tip .tip-addr { font-size: 14px; color: var(--muted-ink); line-height: 1.4; }
.map-hint {
  text-align: center;
  font-size: 14px;           /* locked system: legal-row scale 14 */
  color: var(--muted-ink);
  margin-top: 20px;
}
/* office card highlighted when its marker is hovered (ring, not a drop shadow) */
.office-card.map-active { box-shadow: 0 0 0 2px var(--accent-cta); }
.office-card { scroll-margin-top: 110px; } /* the fixed nav never covers a jumped-to card */

/* ---- catalog 119 Copy Email: a pill that copies the address on click and flips
        to a Copied state, then resets (contact.js). Re-tokened to the kit soft pill. ---- */
.copy-email {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  margin-top: 16px;
  padding: 10px 18px;
  border: none;
  border-radius: 96px;       /* kit: pill radius 96 */
  background: var(--line);    /* kit: secondary fill */
  color: var(--ink);
  font: inherit;
  font-size: 15px;
  cursor: pointer;
  transition: background-color .4s cubic-bezier(.25, .1, .25, 1); /* catalog copy spring */
  -webkit-tap-highlight-color: transparent;
}
.copy-email:hover { background: var(--card-blush); }
.copy-email svg { width: 16px; height: 16px; flex: none; }
.copy-email .ce-check { display: none; }
.copy-email.copied { background: var(--card-blush); color: var(--accent-cta); }
.copy-email.copied .ce-copy { display: none; }
.copy-email.copied .ce-check { display: inline-flex; }

/* ---- catalog 047 WhatsApp Chat Button: opens a wa.me thread to the info line.
        The recognizable brand green + glyph are load-bearing, so they stay
        (a small saturated affordance). FLAGGED: confirm the info line is
        WhatsApp-active before send (see the build return). ---- */
.wa-btn {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  margin-top: 16px;
  padding: 11px 20px;
  border-radius: 96px;       /* kit: pill radius 96 */
  background: var(--accent-cta); /* kit red CTA (was WhatsApp green; recolored to a Call button 2026-07-12) */
  color: #FFFFFF;
  font: inherit;
  font-size: 15px;
  font-weight: 400;
  text-decoration: none;
  transition: opacity .2s ease, transform .1s ease; /* catalog: opacity .9 hover, 1px lift */
}
.wa-btn:hover { opacity: .9; }
.wa-btn:active { transform: translateY(1px); }
.wa-btn svg { width: 18px; height: 18px; flex: none; }
.primary-actions { display: flex; flex-wrap: wrap; gap: 12px; }

/* ---- Mobile for the richness layer ---- */
@media (max-width: 820px) {
  .offices-map { padding: 48px 20px 0; }
  .map-frame { padding: 14px; border-radius: 24px; }
  .pin-label { font-size: 34px; stroke-width: 6; } /* the SVG shrinks with the frame, so labels step up in viewBox units */
  .map-tip { max-width: 200px; }
  .primary-actions { margin-top: 4px; }
}

/* ---- Reduced motion for the richness layer: markers hold still, the beam still
        appears (opacity only), the copy pill snaps state. ---- */
@media (prefers-reduced-motion: reduce) {
  .pin-halo { animation: none; }
  .zw-pin .pin-mark, .map-tip, .copy-email { transition: none; }
}

/* ==========================================================================
   Shared footer support: catalog 058 Hover Text Highlight on the footer link
   columns. The markup is copied verbatim from index.html (shared footer);
   its styling lives in home.css, so it is mirrored here token-for-token so the
   shared footer behaves identically on this page. Pure CSS, no runtime.
   ========================================================================== */
.hl-links a { position: relative; }
.hl-links a::after {
  content: "";
  position: absolute;
  left: 0; bottom: -2px;
  width: 100%; height: 2px;
  border-radius: 2px;
  background: var(--accent);
  transform: scaleX(0);
  transform-origin: left center;
  transition: transform .3s var(--ease-house);
}
.hl-links a:hover::after,
.hl-links a:focus-visible::after { transform: scaleX(1); }
@media (prefers-reduced-motion: reduce) {
  .hl-links a::after { transition: none; }
}


/* catalog 155 Leaflet map (2026-07-12): container + kit-toned markers + popup */
.lmap { width: 100%; height: 100%; min-height: 480px; border-radius: 24px; overflow: hidden; z-index: 0; background: var(--surface); }
.lmap-marker { background: transparent; border: 0; }
.lmap-dot { position: absolute; inset: 0; width: 18px; height: 18px; margin: 3px; border-radius: 50%; background: var(--accent); box-shadow: 0 0 0 4px rgba(238,29,35,.22), 0 2px 6px rgba(26,26,26,.35); }
.lmap-badge { position: absolute; top: -8px; right: -8px; min-width: 18px; height: 18px; padding: 0 4px; border-radius: 9px; background: var(--ink); color: #fff; font-size: 11px; line-height: 18px; text-align: center; font-weight: 500; }
.leaflet-popup-content-wrapper { border-radius: 16px; background: var(--surface); color: var(--ink); box-shadow: 0 6px 24px rgba(26,26,26,.20); }
.leaflet-popup-content { margin: 12px 16px; font-size: 14px; line-height: 1.5; }
.leaflet-popup-content a { color: var(--accent); text-decoration: underline; }
.leaflet-popup-tip { background: var(--surface); }
.leaflet-container { font: inherit; }
.leaflet-control-attribution { font-size: 10px; background: rgba(245,245,245,.8); }
