/* ================================================================
   SITE CHROME  ·  shared page styles on top of tokens.css.
   Header, nav, footer, pill cluster, page scaffolding.
   Linked by every built page; component tokens live in tokens.css.
   ================================================================ */

* { box-sizing: border-box; }
html { scroll-behavior: smooth; }
body { margin: 0; font-family: var(--font-mono); background: var(--ink); }

/* ---------- fixed header: wordmark + inline nav + CTA + hamburger ---------- */
.site-header {
  position: fixed;
  top: 0; left: 0; right: 0;
  z-index: 45;
  background: color-mix(in srgb, var(--ink) 95%, transparent);
  backdrop-filter: blur(6px);
  transition: box-shadow 0.3s ease;
  --band-bg: var(--ink);
  --band-fg: var(--bone);
  --band-accent: var(--accent-dark);
  --fg-40: color-mix(in srgb, var(--bone) 40%, transparent);
  --fg-60: color-mix(in srgb, var(--bone) 60%, transparent);
  color: var(--bone);
}
.site-header.scrolled { box-shadow: 0 4px 24px color-mix(in srgb, var(--ink) 60%, transparent); }
.site-header-inner {
  max-width: 80rem;
  margin: 0 auto;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1.5rem;
  padding: 1.25rem 1.5rem;
}

/* text wordmark, Montserrat 900, no tagline */
.wordmark {
  font-family: var(--font-display);
  font-weight: 900;
  font-size: 1rem;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  color: var(--bone);
  text-decoration: none;
  white-space: nowrap;
}

.header-nav { display: none; align-items: center; gap: 1.75rem; }
@media (min-width: 960px) { .header-nav { display: flex; } }
.header-nav a {
  font-family: var(--font-sans);
  font-weight: 700;
  font-size: var(--text-eyebrow);
  text-transform: uppercase;
  letter-spacing: var(--track-widest);
  color: var(--fg-60);
  text-decoration: none;
  transition: color 0.2s ease;
}
.header-nav a:hover { color: var(--accent-dark); }

.header-actions { display: flex; align-items: center; gap: 1rem; }
.btn-cta--header { display: none; padding: 0.75rem 1.5rem; }
@media (min-width: 640px) { .btn-cta--header { display: inline-block; } }

/* ---------- page scaffolding ---------- */
/* first band under the fixed header carries the offset */
.page-hero .band-inner { padding-top: 9rem; }
.section-intro { max-width: 46rem; margin-top: 1.25rem; }
.section-head .type-h2 { margin-top: 0.75rem; }
.hero-sub { max-width: 42rem; margin-top: 2rem; }
.hero-cta-row { display: flex; flex-wrap: wrap; align-items: center; gap: 1.5rem; margin-top: 2.5rem; }
.faq-wrap { max-width: 46rem; margin-top: 2.5rem; }

.grid-2, .grid-3 {
  display: grid;
  grid-template-columns: 1fr;
  gap: 2rem;
  margin-top: 3rem;
}
@media (min-width: 700px) { .grid-2, .grid-3 { grid-template-columns: 1fr 1fr; } }
@media (min-width: 1024px) { .grid-3 { grid-template-columns: repeat(3, 1fr); } }

/* ---------- price presentation ---------- */
.card--static { cursor: default; }
.card--static:hover { transform: none; border-color: var(--fg-10); }
.price-card { max-width: 30rem; margin-top: 2.5rem; }
.price-figure {
  font-family: var(--font-display);
  font-weight: 900;
  font-size: clamp(1.75rem, 4vw, 2.5rem);
  text-transform: uppercase;
  letter-spacing: -0.02em;
  line-height: 1.1;
  margin: 0 0 1rem;
}
.price-mono {
  font-family: var(--font-mono);
  font-weight: 500;
  font-size: 1.5rem;
  letter-spacing: 0.02em;
  color: var(--band-accent);
  line-height: 1.3;
  margin: 0 0 1rem;
}

/* visible DRAFT stamp for prices not yet approved */
.chip-draft {
  display: inline-block;
  vertical-align: middle;
  margin-left: 0.75rem;
  padding: 0.2rem 0.6rem;
  border: 2px solid var(--band-accent);
  color: var(--band-accent);
  font-family: var(--font-sans);
  font-weight: 700;
  font-size: 0.7rem;
  letter-spacing: 0.1em;
  text-transform: uppercase;
}

/* ---------- placeholder + embed slots (pre-copy build) ---------- */
/* .copy-slot is a MARKUP HOOK ONLY. It was a build-time device that grayed
   out [COPY PENDING] placeholder text at 40 percent. The real copy replaced
   the placeholder text but kept the class, so the old color rule was
   dimming every heading and paragraph on the live site. This class must
   NEVER set color again. Style copy through .type-* classes instead. */
/* Live scheduler panel. The Calendly iframe is requested with our own dark
   appearance parameters (see the data-url in src/book.html), so it paints the
   same ink as the page. Never a dashed outline and never a bone slab.

   NO border and NO radius on this slot, on purpose. Calendly centres its own
   bordered card inside the iframe, so a border of ours drew a second, wider
   rectangle around it and, worse, marked out the slack ink below the card as
   visible dead space. With no border the slot is invisible: the booking card
   simply sits on the page and any slack reads as page background.
   Measured live 2026-08-09: Calendly's desktop card is 663px tall, so the
   desktop height below is that plus a small headroom, never a guess.
   No padding either: the slot hugs the widget on all four sides.

   TWO rules below are both load bearing. Remove either and the widget
   collapses to the 150px iframe default, showing only its header strip:
     1. the container needs a DEFINITE height. Calendly ships the iframe
        with height="100%", and a percentage height against an auto height
        parent resolves to auto, so the iframe falls back to the 150px HTML
        default and the parent then sizes itself to that iframe.
     2. the iframe needs an explicit height rule of OURS. Calendly's
        widget.js loads no stylesheet of its own on this page, so without
        this rule nothing sizes that iframe and nothing clears the
        inline-element baseline gap under it.
   Measured on the live page 2026-08-09: iframe was 150px tall, widget 155px,
   slot 287px, and Calendly's own UI scrolled inside the 150px box.

   Mobile first, the stacked Calendly layout needs more room than desktop. */
/* The scheduler ships in Calendly's own LIGHT theme, so this slot is the
   frame that makes a light block look deliberate on an ink band: a bone
   panel with padding around the white widget, matching the site's light
   band color rather than raw white. Reason for the light theme is written
   out in full in src/book.html above the embed. Short version: Calendly
   renders its input fields on a hard white background it will not theme,
   and reuses one text color for both the card copy and the typed field
   text, so no value clears AA on both surfaces at once. */
.embed-slot {
  margin-top: 2.5rem;
  background: var(--bone);
  border-radius: var(--radius-card);
  padding: 0.75rem;
  overflow-x: auto;
}
.embed-slot .calendly-inline-widget {
  display: block;
  width: 100%;
  min-width: 320px;
  height: 1180px;
  min-height: 1180px;
}
.embed-slot .calendly-inline-widget iframe {
  display: block;
  width: 100%;
  height: 100%;
  border: 0;
}
@media (min-width: 700px) {
  /* 663px measured content plus headroom for the times column state. */
  .embed-slot .calendly-inline-widget { height: 700px; min-height: 700px; }
  .embed-slot { padding: 1.25rem; }
}

/* Quiet alternative route under the scheduler, not a competing CTA. */
.embed-fallback {
  margin-top: 1.25rem;
  font-size: 0.9375rem;
  color: var(--fg-60);
}
.embed-fallback a {
  color: inherit;
  text-decoration: underline;
  text-underline-offset: 3px;
}
.embed-fallback a:hover { color: var(--band-fg); }

/* ---------- on-page form ---------- */
.page-form { max-width: 30rem; margin-top: 2.5rem; }
.page-form > * + * { margin-top: 1.75rem; }
.form-msg { display: none; text-align: center; }
.modal-title-row { display: flex; align-items: flex-start; justify-content: space-between; gap: 1rem; margin-bottom: 1.5rem; }
.modal-fields > * + * { margin-top: 1.5rem; }

/* ---------- footer ---------- */
.site-footer-inner {
  max-width: 80rem;
  margin: 0 auto;
  padding: 4rem 1.5rem;
}
.footer-grid {
  display: grid;
  grid-template-columns: 1fr;
  gap: 2.5rem;
}
@media (min-width: 700px) { .footer-grid { grid-template-columns: 1fr 1fr; } }
@media (min-width: 1100px) { .footer-grid { grid-template-columns: 1.4fr 1fr 1fr 1fr 1fr; } }
.footer-head {
  font-family: var(--font-sans);
  font-weight: 700;
  font-size: var(--text-eyebrow);
  text-transform: uppercase;
  letter-spacing: var(--track-widest);
  color: var(--band-fg);
  margin: 0 0 1rem;
}
.footer-links { display: flex; flex-direction: column; gap: 0.6rem; }
.footer-links a {
  font-family: var(--font-mono);
  font-size: var(--text-eyebrow);
  color: var(--fg-60);
  text-decoration: none;
  transition: color 0.2s ease;
}
.footer-links a:hover { color: var(--band-accent); }
.footer-line { font-family: var(--font-mono); font-size: var(--text-eyebrow); color: var(--fg-60); margin: 1.25rem 0 0; }
.footer-col--brand .wordmark { color: var(--band-fg); }

/* ================================================================
   SCROLL ENTRANCE MOTION  (approved 2026-08-09)
   Fade in and rise 12px on viewport entry, 350ms ease-out.
   Classes are added ONLY by /assets/motion.js (never in markup)
   and self-remove after the transition so the card hover lift in
   tokens.css keeps working. Fully disabled under
   prefers-reduced-motion here AND in motion.js.
   ================================================================ */
.ah-reveal { opacity: 0; transform: translateY(12px); }
.ah-reveal.ah-in {
  opacity: 1;
  transform: translateY(0);
  transition: opacity 350ms ease-out, transform 350ms ease-out;
}
@media (prefers-reduced-motion: reduce) {
  .ah-reveal, .ah-reveal.ah-in { opacity: 1; transform: none; transition: none; }
}

/* ================================================================
   MICRO-INTERACTION POLISH  (approved 2026-08-09)
   Subtle hover/press/focus states on top of tokens.css. Transform,
   opacity, color and shadow ONLY, so nothing reflows. All movement
   is disabled in the prefers-reduced-motion block at the bottom.
   ================================================================ */

/* 1 · buttons: lift on hover, press flat on click, soft acid glow */
.btn-cta {
  transition: background-color 0.2s ease, transform 0.18s ease, box-shadow 0.18s ease;
}
.btn-cta:hover {
  transform: translateY(-2px);
  box-shadow: 0 6px 18px color-mix(in srgb, var(--accent-dark) 30%, transparent);
}
.btn-cta:active { transform: translateY(0); box-shadow: none; }
.btn-chip {
  transition: color 0.2s ease, border-color 0.2s ease, transform 0.18s ease;
}
.btn-chip:hover { transform: translateY(-2px); }
.btn-chip:active { transform: translateY(0); }

/* 2 · cards: 2px accent top edge slides in from the left, layered
   over the existing lift. Sits on the border line, zero reflow. */
.card::before {
  content: "";
  position: absolute;
  top: -2px; left: -2px; right: -2px;
  height: 2px;
  background: var(--band-accent);
  transform: scaleX(0);
  transform-origin: left;
  transition: transform 0.25s var(--ease-out-soft);
  pointer-events: none;
}
.card:hover::before { transform: scaleX(1); }
.card--static::before { content: none; }

/* 3 · header nav: acid underline slides in from the left; the
   current page keeps it (aria-current set by /assets/motion.js).
   Vertical padding on an inline link never reflows the line. */
.header-nav a {
  padding-bottom: 3px;
  background-image: linear-gradient(var(--accent-dark), var(--accent-dark));
  background-repeat: no-repeat;
  background-size: 0% 2px;
  background-position: 0 100%;
  transition: color 0.2s ease, background-size 0.25s var(--ease-out-soft);
}
.header-nav a:hover { background-size: 100% 2px; }
.header-nav a[aria-current="page"] { color: var(--bone); background-size: 100% 2px; }
.nav-link[aria-current="page"] { color: var(--accent-dark); }

/* 4 · card-link label nudges right on card hover. The arrow is a
   text entity inside the span, so the whole label moves. Spans only:
   every .card-link in the markup is a span inside an <a class="card">. */
span.card-link { display: inline-block; transition: transform 0.2s var(--ease-out-soft); }
.card:hover span.card-link { transform: translateX(4px); }

/* 5 · body-copy links: underline slides in from the left, arrow
   (the ::after glyph) nudges right */
.link-arrow {
  padding-bottom: 2px;
  background-image: linear-gradient(currentColor, currentColor);
  background-repeat: no-repeat;
  background-size: 0% 1px;
  background-position: 0 100%;
  transition: color 0.2s ease, background-size 0.25s var(--ease-out-soft);
}
.link-arrow:hover { text-decoration: none; background-size: 100% 1px; }
.link-arrow::after { display: inline-block; transition: transform 0.2s var(--ease-out-soft); }
.link-arrow:hover::after { transform: translateX(4px); }

/* 6 · keyboard focus: visible acid ring on everything interactive */
a:focus-visible,
button:focus-visible,
input:focus-visible,
textarea:focus-visible {
  outline: 2px solid var(--band-accent, var(--accent-dark));
  outline-offset: 3px;
}

/* 7 · form fields: border eases to accent, plus a small accent edge
   just left of the field while focused (outset shadow, no reflow) */
.field { transition: border-color 0.2s ease, box-shadow 0.2s ease; }
.field:focus { box-shadow: -6px 0 0 -2px var(--band-accent, var(--accent-dark)); }

/* 9 · floating pills: same lift-and-press as the buttons */
.pill {
  transition: background-color 0.2s ease, border-color 0.2s ease, transform 0.18s ease;
}
.pill:hover { transform: translateY(-2px); }
.pill:active { transform: translateY(0); }

/* 8 + guard · smooth anchor scrolling is set on html at the top of
   this file; under reduced motion it goes instant, and every polish
   movement above is stripped while color/underline states remain. */
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  .btn-cta, .btn-chip, .pill, .card::before, span.card-link,
  .link-arrow, .link-arrow::after, .header-nav a, .field {
    transition: none;
  }
  .btn-cta:hover, .btn-chip:hover, .pill:hover { transform: none; }
  .btn-cta:hover { box-shadow: none; }
  .card:hover span.card-link, .link-arrow:hover::after { transform: none; }
  .card::before, .card:hover::before { transform: scaleX(1); opacity: 0; }
  .card:hover::before { opacity: 1; }
}
