/* ==========================================================================
   Tonecraft Piano Works — INTERIOR PAGE DESIGN SYSTEM
   assets/css/tcp-interior.css   ·   v1.9.4 (2026-09-13)

   v1.9.4: About bio standfirst set in italic and given a soft gradient
   hairline beneath it (--tcp-rule-grad-soft).

   v1.9.2: .tcp-page-hero-plate moved clear of the fixed tick nav.

   v1.9.1: section 9's tick-nav rules wrapped in :where() and its on-dark
   block removed — they were outranking the contrast engine's classes.
   style.css is now the only file declaring tick-nav contrast states.

   v1.9.0: section 9's tick-nav resting colours raised and re-pointed at
   the sitewide --tcp-tick-* Control Panel knobs in style.css, and the
   .is-over-dark state it had always documented is now actually driven by
   a script (assets/js/tcp-tick-nav-contrast.js).

   WHAT THIS FILE IS
   -----------------
   The front page (front-page.php + the front-page rules already in
   style.css) is the visual foundation for this site. Every other page
   had drifted off it — plainer headers, centered text, no entrance
   animation, gold-edged glass cards, tighter/flatter typography. This
   file is the single place that pulls all of those pages back onto the
   front page's system.

   It is enqueued ONLY on non-front-page views (see
   tcp_enqueue_interior_assets() in functions.php), which is why nothing
   in here needs to be defensively scoped away from the home page — it
   never loads there. The front page is deliberately untouched by this
   round of work.

   WHAT IT ESTABLISHES
   -------------------
   1. A dark, matte "page hero" band at the top of every interior page,
      with a soft-light lighting wash (same family as the front page's
      hero gradient, dialed back), left-justified, framed with an
      eyebrow tick.
   2. A single heading rhythm — eyebrow tick → display headline →
      Poppins lede — reused everywhere, matching the front page's
      Services / The Craft / Contact section heads.
   3. Matte hairline framing for every card, tier, list and grid on the
      site, replacing the gold-edged, blurred, rounded "glass" cards.
      NO gold borders. NO backdrop-filter. NO gloss.
   4. Entrance animation + easing on every page, driven by
      assets/js/tcp-interior.js, using the same .tcp-anim-fade /
      .tcp-anim-slide-up utilities and the same cubic-bezier the front
      page already uses.
   5. Alga (added to the Adobe Fonts kit Sept 2026) introduced as the
      third voice in the type system — interior page-hero headlines,
      pull quotes and numerals — while Fraunces stays the section-
      heading face and Poppins stays the body face, exactly as on the
      front page.
   6. A fix for the blog/archive templates (rendered by Astra, not by a
      theme template we control), which were tucking their content up
      underneath the fixed header.

   HOUSE RULES OBSERVED
   --------------------
   · No serif UI type; Poppins everywhere a sans is wanted.
   · Letter-spacing / tracking never tighter than +0.01em, anywhere —
     that is the base value, applied globally below.
   · Matte only. No glass, no gloss, no blur, no glare.
   ========================================================================== */

:root {
  /* ======================================================================
     ======================================================================
     CSS CONTROL PANEL — tcp-interior.css
     Every adjustable knob for the interior pages lives here, grouped by
     feature area, per the project's CSS Control Panel convention. Add
     new controls here rather than inline in a component rule.
     ======================================================================
     ====================================================================== */

  /* ---- Type ----
     --tcp-font-accent    the third voice: Alga, from the Adobe Fonts
       kit (ilb2wyz). High-contrast display serif with real italics.
       Used for interior page-hero headlines, pull quotes, and large
       numerals. Falls back to Fraunces (the front page's display face)
       so a kit failure degrades to the existing look rather than to a
       browser default.
     --tcp-hero-title-font  which face the interior page-hero <h1>
       uses. Set to var(--tcp-font-display) to put those headlines back
       on Fraunces and match the front page exactly — this one switch
       is the whole Alga/Fraunces decision.
     --tcp-track-base     the standing sitewide minimum tracking.
       NEVER set below 0.01em. Applied on body + headings below.
     --tcp-track-eyebrow  tracking for the uppercase eyebrow/label
       micro-type. Matches the front page's .tcp-eyebrow (.28em).
     --tcp-track-display  tracking for large display headlines. Alga is
       tighter-fitting than Fraunces at size, so this opens it slightly
       rather than letting it close up. */
  --tcp-font-accent: "alga", "Fraunces", Georgia, serif;
  --tcp-hero-title-font: var(--tcp-font-accent);
  --tcp-track-base: 0.01em;
  --tcp-track-eyebrow: 0.28em;
  --tcp-track-display: 0.015em;

  /* ---- Interior page hero (the dark band at the top of every page) ----
     --tcp-phero-min-h        min-height of the band. Deliberately NOT
       full viewport height — these are content pages, not the home
       page. clamp() so it scales with the viewport but never collapses.
     --tcp-phero-pad-top      space above the headline block. The fixed
       header is 100px tall (--tcp-header-height, style.css), so this
       adds clearance BELOW it, it does not include it — the calc on
       .tcp-page-header does that.
     --tcp-phero-pad-bottom   space below the block before the band ends.
     --tcp-phero-base         the band's flat base color. A step darker
       than --tcp-charcoal so the lighting wash has somewhere to go.
     --tcp-phero-light-x/-y   where the soft-light "key light" sits in
       the band, as a percentage of the band. Default is upper-right,
       the same direction the front page's hero light comes from.
     --tcp-phero-light        strength of that key light, 0–1. This is
       a soft-light blend, not an opacity overlay — it lifts the base
       color rather than washing white over it, which is what keeps it
       matte. Raise gently; above ~0.5 it starts to look lit rather
       than insinuated.
     --tcp-phero-floor        strength of the downward darkening that
       grounds the bottom of the band, 0–1.
     --tcp-phero-grain        opacity of the faint tonal break-up that
       keeps a large flat dark area from banding on wide monitors.
       Set to 0 to remove it entirely. */
  --tcp-phero-min-h: clamp(340px, 44vh, 500px);
  --tcp-phero-pad-top: clamp(54px, 7vh, 92px);
  --tcp-phero-pad-bottom: clamp(56px, 8vh, 104px);
  --tcp-phero-base: #3b3c3d;
  --tcp-phero-light-x: 78%;
  --tcp-phero-light-y: 14%;
  --tcp-phero-light: 0.34;
  --tcp-phero-floor: 0.5;
  --tcp-phero-grain: 0.05;

  /* ---- Interior light sections ----
     The home page alternates #FFFFFF and --tcp-cream. On the interior
     pages the cream was reading as a flat, chalky band, so the alt
     background here is a cooler, greyer parchment and every light
     section gets the same gentle soft-light wash the hero band does —
     just much weaker. Both are interior-only: .tcp-bg-cream on the
     FRONT page still resolves to --tcp-cream, because this file never
     loads there.

     --tcp-int-bg-alt         the alt (formerly cream) section fill.
     --tcp-int-bg-plain       the plain section fill.
     --tcp-int-light          strength of the soft-light wash over a
       light section, 0–1. Very low by design — this should read as
       "the room has a window", not as a gradient.
     --tcp-int-light-x/-y     where that wash originates.
     --tcp-int-sec-pad-top / -bottom   vertical rhythm for interior
       sections. Front page uses 150px/90px; interior pages run a
       little tighter since they carry more sections per page. */
  --tcp-int-bg-alt: #edeae4;
  --tcp-int-bg-plain: #ffffff;
  --tcp-int-light: 0.5;
  --tcp-int-light-x: 76%;
  --tcp-int-light-y: 6%;
  --tcp-int-sec-pad-top: clamp(84px, 9vw, 128px);
  --tcp-int-sec-pad-bottom: clamp(72px, 8vw, 108px);

  /* ---- Hairline framing (replaces every gold / glass card edge) ----
     The front page frames things with thin, muted, matte lines that
     are open at both ends — the Services card grid and the stat row.
     That is the whole visual language for framing on this site now.

     --tcp-rule-ink      the flat hairline color.
     --tcp-rule-ink-soft a lighter step, for secondary divisions.
     --tcp-rule-grad     the gradient hairline — stronger at the left
       edge, fading out to the right. Used via border-image on the top
       rule of card-style blocks so the frame reads as drawn rather
       than boxed.
     --tcp-card-hover-bg the card hover fill. Monochromatic to the
       background by design (no accent hue), same principle as the
       front page's --tcp-service-hover-bg.
     --tcp-card-lift     how far a card rises on hover, px. */
  --tcp-rule-ink: rgba(74, 75, 76, 0.22);
  --tcp-rule-ink-soft: rgba(74, 75, 76, 0.13);
  --tcp-rule-grad: linear-gradient(90deg, rgba(74, 75, 76, 0.34) 0%, rgba(74, 75, 76, 0.16) 48%, rgba(74, 75, 76, 0.04) 100%);
  /* v1.9.4: a lighter sibling of --tcp-rule-grad that actually reaches
     zero alpha, so it fades out cleanly instead of ending on a faint
     but visible edge. For soft in-content divisions rather than card
     framing — currently the About bio's standfirst rule. */
  --tcp-rule-grad-soft: linear-gradient(90deg, rgba(74, 75, 76, 0.20) 0%, rgba(74, 75, 76, 0.10) 45%, rgba(74, 75, 76, 0) 88%);
  --tcp-card-hover-bg: #e4dfd6;
  --tcp-card-lift: 4px;

  /* ---- Buttons ----
     Per client direction: the primary button is burgundy with gold
     type on it, sitewide, on every interior page.
     --tcp-btn-gold-text  the gold used for button labels. A step
       brighter than --tcp-gold so it holds legible contrast against
       the burgundy fill rather than sinking into it. */
  --tcp-btn-gold-text: #dbb757;

  /* ---- Entrance animation ----
     Matches the front page's feel: elements ease up from below while
     fading in, staggered so a section resolves in sequence instead of
     all at once. tcp-interior.js reads none of these directly — it
     only adds .is-visible; everything below is pure CSS.

     --tcp-rise-dist      how far an element travels up, px.
     --tcp-rise-dur       the travel/fade duration.
     --tcp-rise-dur-slow  duration for large display headlines, which
       read better moving a touch slower than body copy.
     --tcp-slide-dist     horizontal travel for the hero's lateral
       entrance (the front page's headline drifts sideways as it
       fades in — this is that).
     --tcp-stagger        delay added per element within a group, ms.
       tcp-interior.js sets --tcp-i (the element's index) and the
       delay below multiplies the two. */
  --tcp-rise-dist: 30px;
  --tcp-rise-dur: 0.85s;
  --tcp-rise-dur-slow: 1.1s;
  --tcp-slide-dist: 34px;
  --tcp-stagger: 90ms;
}

/* ==========================================================================
   1. BASELINE — tracking, type, and the shared container
   The standing house rule is that NOTHING on this site is set tighter
   than +0.01em. Applying it at the root of the interior pages means a
   new component inherits it instead of having to remember it.
   ========================================================================== */

body {
  letter-spacing: var(--tcp-track-base);
}

h1, h2, h3, h4, h5, h6 {
  letter-spacing: var(--tcp-track-display);
}

/* ---- Container / left edge ----
   This is the single biggest reason the interior pages didn't read as
   the same site as the home page. The front page's sections are full
   bleed with a 5vw side gutter, so a headline's left edge sits at
   ~5% of the viewport. The interior pages wrapped everything in a
   centred 1100px .tcp-container, which on a wide monitor put that
   same left edge out around 22% — every page starting in a different
   place.

   Rather than strip .tcp-container out of six templates (and risk
   breaking the page-specific JS that queries inside it), the container
   is neutralised HERE: inside an interior section it becomes a plain
   full-width pass-through, and the section's own 5vw padding does the
   gutter, exactly as on the front page. Line length is then held per
   element by a ch-based max-width rather than by the wrapper — which
   is what the front page does too (its body copy caps at 640px inside
   a full-bleed section).

   .tcp-container OUTSIDE an interior section (the footer, for
   instance) keeps its normal centred behaviour from style.css. */
.tcp-section-light > .tcp-container,
.tcp-page-header > .tcp-container,
.tcp-about-bio > .tcp-container,
.tcp-about-credentials > .tcp-container,
.tcp-about-area > .tcp-container,
.tcp-about-cta > .tcp-container,
.tcp-contact-main > .tcp-container {
  max-width: none;
  width: 100%;
  margin: 0;
  padding: 0;
}

/* The sections that carry their own container rather than inheriting
   .tcp-section-light's padding need the gutter stated. 5vw matches the
   front page exactly. */
.tcp-about-bio,
.tcp-about-credentials,
.tcp-about-area,
.tcp-about-cta,
.tcp-contact-main {
  padding-left: 5vw;
  padding-right: 5vw;
}

/* ==========================================================================
   2. PAGE HERO — the dark band at the top of every interior page
   .tcp-page-header is the existing class every interior template
   already puts on its intro section, so upgrading it here means those
   templates inherit the new treatment without markup changes; the
   templates additionally add .tcp-page-hero for the elements that are
   genuinely new (eyebrow, actions row).

   Construction, bottom to top:
     · flat base color                      (--tcp-phero-base)
     · ::before — soft-light key light + floor darkening + grain
     · ::after  — the gradient hairline that closes the band
     · content, lifted above both with z-index
   mix-blend-mode: soft-light on the light layer is what keeps this
   matte: it modulates the base tone instead of laying a white film
   over it, which is what a plain rgba(255,255,255,…) overlay does and
   why that always ends up looking glossy.
   ========================================================================== */

.tcp-page-header {
  position: relative;
  isolation: isolate;
  display: flex;
  flex-direction: column;
  justify-content: flex-end;
  min-height: var(--tcp-phero-min-h);
  /* The fixed header is 100px and sits ON TOP of this band, so its
     height has to be added to the top padding or the eyebrow ends up
     underneath it. --tcp-header-height comes from style.css's Control
     Panel; the fallback keeps this correct if this file is ever loaded
     standalone. */
  padding-top: calc(var(--tcp-header-height, 100px) + var(--tcp-phero-pad-top));
  padding-bottom: var(--tcp-phero-pad-bottom);
  /* 5vw side gutter — the same one the front page's sections use, so a
     page-hero headline's left edge lands exactly where the front
     page's section headlines do. */
  padding-left: 5vw;
  padding-right: 5vw;
  text-align: left;
  background-color: var(--tcp-phero-base);
  color: var(--tcp-cream);
  overflow: hidden;
}

/* Lighting. Three stacked layers in one paint:
   1. the key light, upper-right by default
   2. a wide, very soft counter-light from the lower-left so the band
      doesn't read as lit from exactly one point
   3. the floor — a downward darkening that grounds the band and gives
      the headline something to sit on. */
.tcp-page-header::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 0;
  pointer-events: none;
  background:
    radial-gradient(ellipse 90% 120% at var(--tcp-phero-light-x) var(--tcp-phero-light-y),
      rgba(255, 255, 255, var(--tcp-phero-light)) 0%,
      rgba(255, 255, 255, calc(var(--tcp-phero-light) * 0.38)) 34%,
      rgba(255, 255, 255, 0) 68%),
    radial-gradient(ellipse 120% 90% at 8% 96%,
      rgba(255, 255, 255, calc(var(--tcp-phero-light) * 0.3)) 0%,
      rgba(255, 255, 255, 0) 60%);
  mix-blend-mode: soft-light;
}

/* The floor + the closing hairline. Kept on ::after (normal blend) so
   the darkening is a true darkening rather than a soft-light lift. */
.tcp-page-header::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 0;
  pointer-events: none;
  background:
    linear-gradient(180deg,
      rgba(28, 28, 29, 0.1) 0%,
      rgba(28, 28, 29, 0) 42%,
      rgba(28, 28, 29, calc(var(--tcp-phero-floor) * 0.55)) 100%),
    linear-gradient(90deg,
      rgba(28, 28, 29, calc(var(--tcp-phero-floor) * 0.36)) 0%,
      rgba(28, 28, 29, 0) 54%);
  border-bottom: 1px solid transparent;
  border-image: linear-gradient(90deg,
      rgba(201, 163, 59, 0.42) 0%,
      rgba(201, 163, 59, 0.16) 38%,
      rgba(244, 239, 230, 0.06) 100%) 1;
}

.tcp-page-header > * {
  position: relative;
  z-index: 1;
}

/* ---- Page-hero typography ---- */

.tcp-page-header .tcp-eyebrow {
  color: var(--tcp-gold) !important;
  letter-spacing: var(--tcp-track-eyebrow);
  margin-bottom: clamp(18px, 2.4vw, 26px);
}

.tcp-page-header .tcp-eyebrow .tcp-rule {
  width: 60px;
  background: linear-gradient(90deg, var(--tcp-gold), transparent);
}

.tcp-page-header h1 {
  font-family: var(--tcp-hero-title-font);
  font-weight: 400;
  /* Alga carries more stroke contrast than Fraunces, so it holds a
     slightly larger setting without shouting. */
  font-size: clamp(2.5rem, 5.6vw, 4.2rem);
  line-height: 1.06;
  letter-spacing: var(--tcp-track-display);
  color: var(--tcp-cream) !important;
  margin: 0;
  /* Wide enough that the authored <br> line breaks are the only breaks —
     a tighter cap here silently re-wrapped the last word onto a third
     line on every page. */
  max-width: 26ch;
}

/* The italic accent on an interior headline picks up the same gold
   the front page uses on "Piano Works" — same device, same colour,
   applied one page deeper. */
.tcp-page-header h1 .tcp-italic-accent {
  font-style: italic;
  font-weight: 400;
  color: var(--tcp-gold);
}

.tcp-page-header .tcp-page-subtitle {
  font-family: var(--tcp-font-primary);
  font-weight: 300;
  font-size: clamp(1rem, 1.35vw, 1.12rem);
  /* Generous leading relative to the size, per direction — body copy
     on this site should breathe, not stack. */
  line-height: 1.85;
  letter-spacing: var(--tcp-track-base);
  color: rgba(244, 239, 230, 0.76);
  max-width: 56ch;
  margin: clamp(20px, 2.6vw, 30px) 0 0;
  text-align: left;
}

/* Optional actions row under a page-hero headline. */
.tcp-page-hero-actions {
  display: flex;
  flex-wrap: wrap;
  gap: 16px;
  margin-top: clamp(28px, 3.4vw, 42px);
}

/* A small right-aligned plate caption, same idea as the front page's
   .tcp-plate-label in the hero's bottom corner.

   v1.9.2: shifted left by --tcp-ticknav-clearance (style.css Control
   Panel). It was sitting at the same right offset as the fixed tick
   nav, so on every interior page the caption rendered directly under
   the nav's lower items — "AARON SANDNER, RPT · TRAVERSE CITY" behind
   SERVICE AREA on About, the service marks behind REBUILDING on
   Services, and so on. The front page is deliberately untouched: its
   own .tcp-plate-label sits at the bottom of a full-height hero, well
   clear of the vertically-centred nav. */
.tcp-page-hero-plate {
  position: absolute;
  right: calc(clamp(20px, 5vw, 40px) + var(--tcp-ticknav-clearance, 220px));
  bottom: clamp(18px, 2.4vw, 28px);
  z-index: 1;
  font-family: var(--tcp-font-primary);
  font-size: 0.62rem;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: rgba(244, 239, 230, 0.34);
}

@media (max-width: 920px) {
  .tcp-page-hero-plate {
    display: none;
  }
  .tcp-page-header h1 {
    max-width: none;
  }
}

/* ==========================================================================
   3. LIGHT SECTIONS — rhythm, lighting wash, and the shared heading block
   ========================================================================== */

/* Every interior template puts .tcp-section-light on its page-hero
   section as well as on its body sections, so each rule that would
   otherwise repaint the dark hero band — padding, background — excludes
   it explicitly. (Specificity alone wouldn't do it: these sit later in
   the file than section 2, so they'd win a tie.) */
.tcp-section-light:not(.tcp-page-header) {
  position: relative;
  isolation: isolate;
  padding-top: var(--tcp-int-sec-pad-top);
  padding-bottom: var(--tcp-int-sec-pad-bottom);
  /* The side gutter is stated EXPLICITLY here, not inherited from
     style.css's "padding: 150px 5vw 90px" shorthand, because a
     page-specific stylesheet can (and did) redeclare the shorthand with
     zero side padding — services.css's ".tcp-svc-triage-section
     { padding: 60px 0 }" was doing exactly that. Combined with the
     container neutraliser in section 1, that left the FAQ triage block
     running edge to edge with no left or right margin at all while
     every other section on the page sat at the 5vw gutter.
     Declaring left/right as their own longhands here means this file
     (which always prints last, see functions.php) wins that collision
     for every interior section, whatever its own page CSS does with the
     shorthand. */
  padding-left: 5vw;
  padding-right: 5vw;
  color: var(--tcp-charcoal);
}

/* The interior palette shift. .tcp-bg-cream keeps its class name (the
   templates all use it) but resolves to the cooler parchment here — the
   flat cream was reading chalky at this scale on the inner pages. */
.tcp-section-light:not(.tcp-page-header).tcp-bg-cream { background-color: var(--tcp-int-bg-alt); }
.tcp-section-light:not(.tcp-page-header).tcp-bg-white { background-color: var(--tcp-int-bg-plain); }

/* …and the hero band stays dark whichever background class the template
   happened to put on it. */
.tcp-page-header.tcp-bg-cream,
.tcp-page-header.tcp-bg-white {
  background-color: var(--tcp-phero-base);
}

/* The same soft-light logic as the page hero, at a fraction of the
   strength — just enough to keep a large light area from reading as a
   flat fill. Skipped on the page hero itself (it has its own, above). */
.tcp-section-light:not(.tcp-page-header)::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 0;
  pointer-events: none;
  background: radial-gradient(ellipse 110% 90% at var(--tcp-int-light-x) var(--tcp-int-light-y),
    rgba(255, 255, 255, var(--tcp-int-light)) 0%,
    rgba(255, 255, 255, calc(var(--tcp-int-light) * 0.4)) 40%,
    rgba(255, 255, 255, 0) 72%);
  mix-blend-mode: soft-light;
}

.tcp-section-light:not(.tcp-page-header) > * {
  position: relative;
  z-index: 1;
}

/* ---- The heading block, reused on every interior section ----
   eyebrow tick → display headline → Poppins lede → optional serif
   sub-statement. This is the front page's Services/Craft/Contact head,
   lifted intact. */

.tcp-section-head {
  max-width: 760px;
  margin-bottom: clamp(44px, 5vw, 68px);
}

.tcp-section-head .tcp-eyebrow {
  margin-bottom: 18px;
  letter-spacing: var(--tcp-track-eyebrow);
}

.tcp-section-light h2 {
  font-family: var(--tcp-font-display);
  font-weight: 500;
  font-size: clamp(2rem, 4.2vw, 3.1rem);
  line-height: 1.1;
  letter-spacing: var(--tcp-track-display);
  color: var(--tcp-charcoal) !important;
  margin: 0;
}

.tcp-section-light h3 {
  letter-spacing: var(--tcp-track-display);
}

.tcp-section-light .tcp-sub,
.tcp-section-light .tcp-section-head > p,
.tcp-section-light .tcp-lede {
  font-family: var(--tcp-font-primary);
  font-weight: 300;
  font-size: 1.04rem;
  line-height: 1.9;
  letter-spacing: var(--tcp-track-base);
  color: rgba(74, 75, 76, 0.72);
  max-width: 68ch;
  margin-top: clamp(18px, 2.2vw, 26px);
}

/* ---- About bio standfirst (v1.9.4) ----
   The paragraph directly under "Aaron Sandner" is a standfirst, not body
   copy — it summarises the bio that follows. Italic separates the two
   voices so the reader can see that at a glance rather than having to
   read both to work it out.

   The hairline below it closes what was an unusually large unmarked gap
   between the standfirst and the first body paragraph. It uses the soft
   gradient token so it fades to nothing well before the text measure
   ends — a division, not a boundary. Scoped to .tcp-about-bio on
   purpose: every other .tcp-section-head on the site runs straight into
   its content and should keep doing so. */
.tcp-about-bio .tcp-section-head {
  position: relative;
  padding-bottom: clamp(26px, 3vw, 36px);
  /* Trimmed from the shared clamp(44px, 5vw, 68px): the rule now does
     the separating, so the raw whitespace beneath it can come down. */
  margin-bottom: clamp(28px, 3.2vw, 42px);
}

.tcp-about-bio .tcp-section-head::after {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  height: 1px;
  background: var(--tcp-rule-grad-soft);
}

.tcp-about-bio .tcp-section-head .tcp-sub {
  font-style: italic;
}

/* Serif statement line under a lede — the front page's
   .tcp-svc-substatement, made available on every interior page. */
.tcp-statement {
  font-family: var(--tcp-font-display);
  font-weight: 500;
  font-size: clamp(1.3rem, 2.4vw, 1.7rem) !important;
  line-height: 1.3;
  letter-spacing: var(--tcp-track-display);
  color: var(--tcp-charcoal) !important;
  opacity: 1 !important;
  max-width: 40ch;
  margin-top: 16px !important;
}

.tcp-section-light .tcp-italic-accent {
  color: var(--tcp-burgundy);
  font-family: var(--tcp-font-accent);
}

/* ==========================================================================
   4. HAIRLINE FRAMING — the sitewide replacement for gold/glass edges
   Two shapes, both matte, both drawn rather than boxed:
     .tcp-framed-row   a grid whose cells are divided by thin verticals
                       and capped top and bottom — the front page's
                       stat row. Open at both outer ends.
     .tcp-framed-card  a block with a gradient hairline across its top
                       (and a matching one at the bottom on the last
                       row) — the front page's Services grid.
   Existing per-page card classes are mapped onto these further down so
   the pages don't all need new class names in their markup.
   ========================================================================== */

.tcp-framed-card,
.tcp-area-tier,
.tcp-svc-card,
.tcp-shop-card,
.tcp-sched-step,
.tcp-credential {
  position: relative;
  display: block;
  /* Gradient hairline top rule. border-image paints the gradient into
     the 1px border box; border-top-style must be solid for it to
     render at all. */
  border: 0;
  border-top: 1px solid transparent;
  border-image: var(--tcp-rule-grad) 1;
  border-radius: 0 !important;
  background-color: transparent;
  /* No blur. No glass. Ever. */
  backdrop-filter: none !important;
  -webkit-backdrop-filter: none !important;
  box-shadow: none;
  padding: 26px 20px 30px;
  margin: 0 -20px;
  text-decoration: none;
  color: inherit;
  transition:
    opacity var(--tcp-rise-dur) var(--tcp-ease),
    transform 0.35s var(--tcp-ease),
    background-color 0.35s var(--tcp-ease),
    box-shadow 0.35s var(--tcp-ease);
}

/* Hover is only meaningful where the card is actually a link or a
   control — a static tier block shouldn't lift under the cursor. */
a.tcp-framed-card:hover,
a.tcp-framed-card:focus-visible,
a.tcp-shop-card:hover,
a.tcp-shop-card:focus-visible,
.tcp-svc-card:hover,
.tcp-svc-card:focus-within,
.tcp-shop-card:hover,
.tcp-shop-card:focus-within {
  background-color: var(--tcp-card-hover-bg);
  transform: translateY(calc(var(--tcp-card-lift) * -1));
  box-shadow: 0 16px 34px -18px rgba(74, 75, 76, 0.3);
}

/* Card interior type — same scale/colour relationships as the front
   page's service cards: italic serif numeral, Fraunces title, Poppins
   body a step lighter than the title. */
.tcp-framed-card h3,
.tcp-area-tier h3,
.tcp-svc-card h3,
.tcp-shop-card h3,
.tcp-sched-step h3 {
  font-family: var(--tcp-font-display) !important;
  font-weight: 500;
  font-size: 1.3rem;
  line-height: 1.28;
  letter-spacing: var(--tcp-track-display);
  color: var(--tcp-charcoal) !important;
  margin: 14px 0 12px;
}

.tcp-framed-card p,
.tcp-area-tier p,
.tcp-svc-card p,
.tcp-shop-card p,
.tcp-sched-step p {
  font-family: var(--tcp-font-primary);
  font-weight: 300;
  font-size: 0.95rem;
  line-height: 1.78;
  letter-spacing: var(--tcp-track-base);
  color: rgba(74, 75, 76, 0.68);
  margin-top: 0;
  transition: color 0.35s var(--tcp-ease);
}

/* The numeral that leads a card — burgundy, italic, display face.
   Straight off the front page's .tcp-card-num. */
.tcp-card-num,
.tcp-framed-num,
.tcp-sched-step-num {
  display: block;
  font-family: var(--tcp-font-accent);
  font-style: italic;
  font-weight: 400;
  font-size: 1.15rem;
  letter-spacing: var(--tcp-track-display);
  color: var(--tcp-burgundy);
}

/* Tier blocks (service-area three-tier, About credentials) keep the
   burgundy heading the front page gives them. */
.tcp-area-tier h3 {
  color: var(--tcp-burgundy) !important;
  font-size: 1.15rem;
  margin: 0 0 12px;
}

.tcp-area-tiers {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: clamp(28px, 3.4vw, 44px);
  margin-top: 8px;
}

.tcp-area-tier {
  padding: 24px 20px 8px;
}

@media (max-width: 920px) {
  .tcp-area-tiers { grid-template-columns: 1fr; }
}

/* ---- Framed row: capped top and bottom, divided by verticals, open
   at both outer ends. The front page's stat row, generalised. ---- */
.tcp-framed-row {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  border-top: 1px solid var(--tcp-rule-ink);
  border-bottom: 1px solid var(--tcp-rule-ink);
  margin-top: clamp(44px, 5vw, 64px);
}

.tcp-framed-row > * {
  padding: 34px 28px;
  border-left: 1px solid var(--tcp-rule-ink);
  border-image: none;
}

.tcp-framed-row > *:first-child {
  border-left: none;
  padding-left: 0;
}

@media (max-width: 920px) {
  .tcp-framed-row { grid-template-columns: 1fr; }
  .tcp-framed-row > * {
    border-left: none;
    border-top: 1px solid var(--tcp-rule-ink);
    padding-left: 0;
    padding-right: 0;
  }
  .tcp-framed-row > *:first-child { border-top: none; }
}

/* A large numeral inside a framed row — About's credentials, any
   future stat block. Alga at size, in burgundy. */
.tcp-framed-stat {
  display: block;
  font-family: var(--tcp-font-accent);
  font-weight: 400;
  font-size: clamp(2.3rem, 4vw, 3.3rem);
  line-height: 1;
  letter-spacing: var(--tcp-track-display);
  color: var(--tcp-burgundy);
}

.tcp-framed-stat-label {
  display: block;
  margin-top: 14px;
  font-family: var(--tcp-font-primary);
  font-weight: 300;
  font-size: 0.84rem;
  line-height: 1.65;
  letter-spacing: var(--tcp-track-base);
  color: rgba(74, 75, 76, 0.62);
}

/* ---- The "trained by" style strip: a quiet lead-in label on the left,
   serif marks on the right, separated from what's above it by a rule.
   Front page's .tcp-trained-strip, made reusable. ---- */
.tcp-mark-strip {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 20px;
  padding-top: 44px;
  margin-top: 44px;
}

.tcp-mark-strip .tcp-mark-lead {
  font-family: var(--tcp-font-primary);
  font-size: 0.68rem;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: rgba(74, 75, 76, 0.45);
}

.tcp-mark-strip .tcp-marks {
  display: flex;
  flex-wrap: wrap;
  gap: clamp(24px, 3.6vw, 44px);
}

.tcp-mark-strip .tcp-marks span {
  font-family: var(--tcp-font-accent);
  font-size: 1.2rem;
  line-height: 1.6;
  letter-spacing: 0.03em;
  color: rgba(74, 75, 76, 0.58);
}

/* ---- Pull quote ---- */
.tcp-pullquote {
  font-family: var(--tcp-font-accent) !important;
  font-style: italic;
  font-weight: 400;
  font-size: clamp(1.25rem, 2.3vw, 1.65rem) !important;
  line-height: 1.55 !important;
  letter-spacing: var(--tcp-track-display);
  color: var(--tcp-charcoal) !important;
  opacity: 1 !important;
  /* !important because .tcp-about-bio p (a class + an element) outranks
     this single class, and would otherwise stretch the quote to the
     full body measure. */
  max-width: 48ch !important;
  margin: clamp(38px, 4.4vw, 56px) 0 !important;
  padding-left: clamp(20px, 2.6vw, 32px);
  border-left: 2px solid transparent;
  border-image: linear-gradient(180deg, var(--tcp-burgundy), rgba(96, 24, 40, 0.08)) 1;
}

/* ==========================================================================
   5. BUTTONS — burgundy fill, gold type, matte, sitewide
   ========================================================================== */

.tcp-btn {
  font-family: var(--tcp-font-primary);
  letter-spacing: 0.16em;
  border-radius: 0;
  box-shadow: none;
}

.tcp-btn-primary,
.tcp-btn-primary span {
  color: var(--tcp-btn-gold-text) !important;
}

.tcp-btn-primary {
  background: var(--tcp-burgundy) !important;
  border-color: var(--tcp-burgundy) !important;
}

.tcp-btn-primary:hover,
.tcp-btn-primary:focus-visible {
  border-color: var(--tcp-gold) !important;
}

/* Outline variant on a light section: burgundy edge, burgundy type,
   fills burgundy with gold type on hover. Matte throughout. */
.tcp-section-light .tcp-btn-secondary,
.tcp-section-light .tcp-btn:not(.tcp-btn-primary) {
  border-color: rgba(96, 24, 40, 0.45);
  color: var(--tcp-burgundy);
  background: transparent;
}

.tcp-section-light .tcp-btn:not(.tcp-btn-primary)::before {
  background: var(--tcp-burgundy);
  mix-blend-mode: normal;
}

.tcp-section-light .tcp-btn:not(.tcp-btn-primary):hover,
.tcp-section-light .tcp-btn:not(.tcp-btn-primary):focus-visible {
  border-color: var(--tcp-burgundy);
  color: var(--tcp-btn-gold-text);
}

/* On the dark page-hero band the outline button reads in cream and
   fills burgundy/gold on hover, matching the header CTA's behaviour. */
.tcp-page-header .tcp-btn:not(.tcp-btn-primary) {
  border-color: rgba(244, 239, 230, 0.5);
  color: var(--tcp-cream);
}

.tcp-page-header .tcp-btn:not(.tcp-btn-primary)::before {
  background: var(--tcp-burgundy);
  mix-blend-mode: normal;
}

.tcp-page-header .tcp-btn:not(.tcp-btn-primary):hover,
.tcp-page-header .tcp-btn:not(.tcp-btn-primary):focus-visible {
  border-color: var(--tcp-gold);
  color: var(--tcp-btn-gold-text);
}

/* Quiet text link with an arrow — the front page's "See all services →" */
.tcp-link-more {
  display: inline-block;
  margin-top: clamp(30px, 3.6vw, 44px);
  font-family: var(--tcp-font-primary);
  font-weight: 500;
  font-size: 0.82rem;
  letter-spacing: 0.08em;
  color: var(--tcp-burgundy);
  text-decoration: none;
  transition: color 0.3s var(--tcp-ease), transform 0.3s var(--tcp-ease);
}

.tcp-link-more:hover {
  color: var(--tcp-gold);
  transform: translateX(3px);
}

/* ==========================================================================
   6. ENTRANCE ANIMATION
   .tcp-anim-fade / .tcp-anim-slide-up are already defined in style.css
   and are what the front page uses. The rules below extend that set
   with the lateral drift the front page's hero headline has, a slower
   curve for display headlines, and per-element stagger driven by a
   --tcp-i index that assets/js/tcp-interior.js writes onto each
   element as it observes it.

   Everything here is gated on html.tcp-js, a class an inline script in
   header.php sets before first paint. Without JS the class is never
   added, every rule below no-ops, and the page renders fully visible —
   no content is ever animation-dependent.
   ========================================================================== */

html.tcp-js .tcp-anim-fade,
html.tcp-js .tcp-anim-slide-up,
html.tcp-js .tcp-anim-slide-in,
html.tcp-js .tcp-anim-rise {
  transition-delay: calc(var(--tcp-i, 0) * var(--tcp-stagger));
}

html.tcp-js .tcp-anim-slide-up {
  transform: translateY(var(--tcp-rise-dist));
  transition-duration: var(--tcp-rise-dur);
}

/* The resting state has to be restated at this specificity. style.css
   already declares ".tcp-anim-slide-up.is-visible { transform: none }",
   but the rule above adds an element to the selector (html) and so
   outranks it — without this, an element would fade in correctly and
   then stay stuck 30px below where it belongs, permanently. */
html.tcp-js .tcp-anim-slide-up.is-visible {
  transform: translateY(0);
}

/* Lateral drift-in — the move the front page's hero headline makes.
   Used on interior page-hero headlines and section headings. */
html.tcp-js .tcp-anim-slide-in {
  opacity: 0;
  transform: translate3d(calc(var(--tcp-slide-dist) * -1), 0, 0);
  transition:
    opacity var(--tcp-rise-dur-slow) var(--tcp-ease),
    transform var(--tcp-rise-dur-slow) var(--tcp-ease);
  transition-delay: calc(var(--tcp-i, 0) * var(--tcp-stagger));
  will-change: opacity, transform;
}

html.tcp-js .tcp-anim-slide-in.is-visible {
  opacity: 1;
  transform: translate3d(0, 0, 0);
}

/* A combined rise + drift, for large display headlines. */
html.tcp-js .tcp-anim-rise {
  opacity: 0;
  transform: translate3d(calc(var(--tcp-slide-dist) * -0.5), var(--tcp-rise-dist), 0);
  transition:
    opacity var(--tcp-rise-dur-slow) var(--tcp-ease),
    transform var(--tcp-rise-dur-slow) var(--tcp-ease);
  transition-delay: calc(var(--tcp-i, 0) * var(--tcp-stagger));
  will-change: opacity, transform;
}

html.tcp-js .tcp-anim-rise.is-visible {
  opacity: 1;
  transform: translate3d(0, 0, 0);
}

/* The eyebrow's gradient tick draws itself in rather than just fading —
   a small thing, but it's the detail that makes a section head feel
   composed instead of dropped in. */
html.tcp-js .tcp-anim-fade .tcp-rule,
html.tcp-js .tcp-anim-slide-in .tcp-rule,
html.tcp-js .tcp-anim-rise .tcp-rule {
  transform-origin: left center;
  transform: scaleX(0);
  transition: transform 0.7s var(--tcp-ease);
  transition-delay: calc((var(--tcp-i, 0) * var(--tcp-stagger)) + 0.12s);
}

html.tcp-js .is-visible .tcp-rule,
html.tcp-js .tcp-anim-fade.is-visible .tcp-rule {
  transform: scaleX(1);
}

/* Motion preference wins over all of it. */
@media (prefers-reduced-motion: reduce) {
  html.tcp-js .tcp-anim-fade,
  html.tcp-js .tcp-anim-slide-up,
  html.tcp-js .tcp-anim-slide-in,
  html.tcp-js .tcp-anim-rise,
  html.tcp-js .tcp-anim-fade .tcp-rule,
  html.tcp-js .tcp-anim-slide-in .tcp-rule,
  html.tcp-js .tcp-anim-rise .tcp-rule {
    opacity: 1 !important;
    transform: none !important;
    transition: none !important;
  }
}

/* ==========================================================================
   7. PER-PAGE MAPPING
   The interior templates each grew their own local class names before
   this system existed. Rather than rename markup across six templates
   (and break anything keyed off those names in page-specific JS), the
   old names are mapped onto the shared system here.
   ========================================================================== */

/* ---- About ---- */

.tcp-about-bio {
  padding-top: var(--tcp-int-sec-pad-top);
  padding-bottom: var(--tcp-int-sec-pad-bottom);
}

/* The bio measure was 760px inside a centred container, which left the
   copy as a narrow strip pinned mid-page. The wrapper is neutralised in
   section 1 along with every other interior container; line length is
   held per paragraph in ch below instead, which is how the front page
   does it. */

.tcp-about-bio p {
  font-family: var(--tcp-font-primary);
  font-weight: 300;
  font-size: 1.06rem;
  /* Generous leading relative to the size, per direction. */
  line-height: 1.95;
  letter-spacing: var(--tcp-track-base);
  color: rgba(74, 75, 76, 0.76);
  max-width: 78ch;
  margin: 0 0 clamp(22px, 2.6vw, 30px);
}

.tcp-about-differentiator {
  font-family: var(--tcp-font-accent) !important;
  font-style: italic;
  font-size: 1.14rem !important;
  line-height: 1.75 !important;
  color: var(--tcp-burgundy) !important;
  opacity: 1 !important;
  max-width: 62ch !important;
  margin-top: 4px !important;
}

.tcp-about-credentials {
  padding-top: var(--tcp-int-sec-pad-top);
  padding-bottom: var(--tcp-int-sec-pad-bottom);
}

.tcp-credentials-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 0;
  text-align: left;
  border-top: 1px solid var(--tcp-rule-ink);
  border-bottom: 1px solid var(--tcp-rule-ink);
  margin-top: clamp(44px, 5vw, 64px);
}

.tcp-credential {
  border: 0;
  border-left: 1px solid var(--tcp-rule-ink);
  border-image: none;
  border-radius: 0;
  padding: 34px 28px;
  margin: 0;
  min-width: 0;
}

.tcp-credential:first-child {
  border-left: none;
  padding-left: 0;
}

.tcp-credential-stat {
  display: block;
  font-family: var(--tcp-font-accent);
  font-weight: 400;
  font-size: clamp(2.3rem, 4vw, 3.3rem);
  line-height: 1;
  letter-spacing: var(--tcp-track-display);
  color: var(--tcp-burgundy);
}

.tcp-credential-label {
  display: block;
  margin-top: 14px;
  font-family: var(--tcp-font-primary);
  font-weight: 300;
  font-size: 0.84rem;
  line-height: 1.7;
  letter-spacing: var(--tcp-track-base);
  color: rgba(74, 75, 76, 0.62);
  opacity: 1;
}

@media (max-width: 920px) {
  .tcp-credentials-grid { grid-template-columns: 1fr; }
  .tcp-credential {
    border-left: none;
    border-top: 1px solid var(--tcp-rule-ink);
    padding-left: 0;
    padding-right: 0;
  }
  .tcp-credential:first-child { border-top: none; }
}

.tcp-about-area {
  padding-top: var(--tcp-int-sec-pad-top);
  padding-bottom: var(--tcp-int-sec-pad-bottom);
  text-align: left;
}

/* style.css caps this container at 700px and centres it, which pushed
   the whole Service Area block into the middle of the page while every
   other section started at the 5vw gutter. Overridden back to the
   shared full-bleed behaviour. */
.tcp-about-area > .tcp-container {
  max-width: none;
  margin: 0;
}

.tcp-about-cta {
  text-align: left;
  padding-top: var(--tcp-int-sec-pad-top);
  padding-bottom: var(--tcp-int-sec-pad-bottom);
}

/* ---- Services ---- */

/* The category cards were the one place gold and glass both survived:
   a gold 1px border, a 7px radius, and a 14px backdrop blur. All three
   are gone — these now carry the same drawn gradient hairline and matte
   fill as every other card on the site (base rule in section 4; the
   overrides below are only what's specific to this card). */
.tcp-svc-card {
  padding: 26px 22px 24px;
  margin: 0;
  scroll-margin-top: var(--tcp-scroll-margin, 135px);
}

.tcp-svc-card p.tcp-svc-blurb {
  font-size: 0.94rem;
  line-height: 1.78;
  color: rgba(74, 75, 76, 0.68);
  opacity: 1;
}

/* The grid was auto-fit/minmax(280px), which on a wide monitor laid the
   six services out five-across — a different rhythm to the front page's
   three-across Services grid, which is the block this page is supposed
   to be the expansion of. Pinned to three columns to match, stepping
   down to two and then one. */
.tcp-svc-card-grid {
  grid-template-columns: repeat(3, 1fr);
  gap: clamp(24px, 3vw, 40px);
}

@media (max-width: 1100px) {
  .tcp-svc-card-grid { grid-template-columns: repeat(2, 1fr); }
}

@media (max-width: 720px) {
  .tcp-svc-card-grid { grid-template-columns: 1fr; }
}

/* Bookend the bottom row with a matching rule so the grid reads as
   "a line above and a line below", the way the front page's Services
   grid does — without it the last row has only the line it shares with
   the row above and the block trails off. Same for the product grid. */
.tcp-svc-card-grid > :nth-child(n + 4),
.tcp-shop-grid > :nth-child(n + 5) {
  border-bottom: 1px solid var(--tcp-rule-ink-soft);
}

@media (max-width: 1100px) {
  .tcp-svc-card-grid > :nth-child(n + 4) { border-bottom: 0; }
  .tcp-svc-card-grid > :nth-child(n + 5) { border-bottom: 1px solid var(--tcp-rule-ink-soft); }
}

@media (max-width: 720px) {
  .tcp-svc-card-grid > *,
  .tcp-shop-grid > * { border-bottom: 0; }
}

/* The "Elite Performance Solutions" lockup sits inside a .tcp-section-head
   now, so it carries the shared eyebrow above it. Its own hard charcoal
   underline was the last boxed-in edge on the page — swapped for the
   same drawn gradient hairline every other division uses, and the
   flex baseline row is relaxed so the eyebrow, headline, byline and
   statement stack the way a section head does everywhere else. */
.tcp-svc-section-heading {
  display: block;
  border-bottom: 0;
  padding-bottom: 0;
  scroll-margin-top: var(--tcp-scroll-margin, 135px);
}

.tcp-svc-section-heading h2 {
  font-size: clamp(2rem, 4.2vw, 3.1rem);
  display: inline-flex;
}

.tcp-svc-section-heading .tcp-svc-by {
  display: block;
  margin-top: 10px;
  font-size: 0.72rem;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: rgba(74, 75, 76, 0.5);
  opacity: 1;
}

/* Triage pills: the gold edge becomes the same muted hairline, and
   the active/hover state is burgundy with gold type, consistent with
   the button system above. */
.tcp-svc-pill {
  border: 1px solid var(--tcp-rule-ink) !important;
  border-radius: 0 !important;
  background: transparent !important;
  font-family: var(--tcp-font-primary);
  letter-spacing: var(--tcp-track-base);
  box-shadow: none !important;
}

.tcp-svc-pill:hover,
.tcp-svc-pill.is-active {
  background: var(--tcp-burgundy) !important;
  border-color: var(--tcp-burgundy) !important;
  color: var(--tcp-btn-gold-text) !important;
}

/* The triage answer panel. It was a stark white box with a hard 3px
   burgundy edge, set smaller and tighter than any other body copy on
   the site. Now: no fill, a gradient burgundy rule down the left the
   same way .tcp-pullquote is drawn, and the site's standard body
   measure, size and leading so the answer reads like the rest of the
   page rather than like a system message. */
.tcp-svc-triage-answer {
  background: transparent;
  border-left: 2px solid transparent;
  border-image: linear-gradient(180deg, var(--tcp-burgundy), rgba(96, 24, 40, 0.08)) 1;
  border-radius: 0;
  padding: 6px 0 6px clamp(20px, 2.4vw, 30px);
  margin-top: clamp(26px, 3vw, 36px);
  font-family: var(--tcp-font-primary);
  font-weight: 300;
  font-size: 1.02rem;
  line-height: 1.9;
  letter-spacing: var(--tcp-track-base);
  color: rgba(74, 75, 76, 0.78);
  max-width: 78ch;
}

/* "Get a Solution, Contact Us" — was a small grey rounded chip that
   read as a browser default sitting inside otherwise composed copy.
   Now the same squared burgundy-outline → burgundy-fill-with-gold-type
   treatment every other secondary control on the site uses, sized as
   the micro-type it is and dropped onto its own line so it stops
   crowding the last sentence of the answer. */
.tcp-svc-triage-cta {
  display: inline-block;
  margin: 16px 0 0;
  padding: 10px 18px;
  background: transparent;
  border: 1px solid rgba(96, 24, 40, 0.45);
  border-radius: 0;
  color: var(--tcp-burgundy);
  font-family: var(--tcp-font-primary);
  font-size: 0.68rem;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  white-space: nowrap;
  transition: background 0.3s var(--tcp-ease), border-color 0.3s var(--tcp-ease),
    color 0.3s var(--tcp-ease), transform 0.3s var(--tcp-ease);
}

.tcp-svc-triage-cta:hover,
.tcp-svc-triage-cta:focus-visible {
  background: var(--tcp-burgundy);
  border-color: var(--tcp-burgundy);
  color: var(--tcp-btn-gold-text);
  transform: translateY(-2px);
}

/* The follow-up chips ("Moved to a new home") — squared off and given
   the same gold-on-burgundy active state as the triage pills above
   them, so the two rows read as one control set instead of two. */
.tcp-svc-follow-pill {
  background: transparent;
  border: 1px solid rgba(96, 24, 40, 0.45);
  border-radius: 0;
  letter-spacing: var(--tcp-track-base);
  padding: 12px 18px;
}

.tcp-svc-follow-pill:hover,
.tcp-svc-follow-pill.is-active {
  background: var(--tcp-burgundy);
  border-color: var(--tcp-burgundy);
  color: var(--tcp-btn-gold-text);
}

.tcp-svc-followup-row {
  gap: 12px;
  margin-top: clamp(20px, 2.4vw, 28px);
}

/* The collapsed full-FAQ index divider — was a gold hairline. */
.tcp-svc-faq-index {
  border-top: 1px solid var(--tcp-rule-ink) !important;
}

/* Italic accents on the services page were gold on a light background,
   which reads washed out; burgundy is the accent colour for type on
   light, per the front page. */
.tcp-svc-italic {
  font-family: var(--tcp-font-accent);
  color: var(--tcp-burgundy);
}

.tcp-services-differentiator {
  font-family: var(--tcp-font-accent);
  font-style: italic;
  color: var(--tcp-burgundy);
  text-align: left;
  max-width: 62ch;
  margin: 24px 0 0;
}

/* ---- Commerce ---- */

.tcp-shop-grid {
  gap: clamp(24px, 3vw, 40px);
}

.tcp-shop-card {
  padding: 24px 20px 26px;
  margin: 0;
  border: 0;
  border-top: 1px solid transparent;
  border-image: var(--tcp-rule-grad) 1;
}

.tcp-shop-card-img,
.tcp-img-placeholder {
  border-radius: 0 !important;
  box-shadow: none !important;
}

.tcp-img-placeholder {
  background: rgba(74, 75, 76, 0.05);
  border: 1px solid var(--tcp-rule-ink-soft);
  color: rgba(74, 75, 76, 0.4);
  font-family: var(--tcp-font-primary);
  font-size: 0.68rem;
  letter-spacing: 0.16em;
  text-transform: uppercase;
}

.tcp-shop-card-foot {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 16px;
  margin-top: 18px;
  padding-top: 16px;
  border-top: 1px solid var(--tcp-rule-ink-soft);
}

.tcp-shop-price {
  font-family: var(--tcp-font-accent);
  font-style: italic;
  color: var(--tcp-burgundy);
  letter-spacing: var(--tcp-track-display);
}

.tcp-shop-link {
  font-family: var(--tcp-font-primary);
  font-size: 0.78rem;
  letter-spacing: 0.08em;
  color: var(--tcp-burgundy);
  text-decoration: none;
  transition: color 0.3s var(--tcp-ease), transform 0.3s var(--tcp-ease);
}

.tcp-shop-link:hover {
  color: var(--tcp-gold);
}

.tcp-commerce-disclosure {
  font-family: var(--tcp-font-primary);
  font-size: 0.88rem;
  line-height: 1.85;
  letter-spacing: var(--tcp-track-base);
  color: rgba(74, 75, 76, 0.58);
  max-width: 62ch;
  margin-top: clamp(18px, 2.2vw, 26px);
}

/* ---- Scheduling ---- */

.tcp-sched-step {
  padding: 26px 20px 28px;
  margin: 0;
}

.tcp-sched-steps {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: clamp(24px, 3vw, 40px);
  margin-top: 8px;
}

@media (max-width: 920px) {
  .tcp-sched-steps { grid-template-columns: 1fr; }
}

/* ---- Brokerage ---- */

.tcp-brokerage-listing,
.tcp-brokerage-card {
  border-radius: 0 !important;
  box-shadow: none !important;
  backdrop-filter: none !important;
  -webkit-backdrop-filter: none !important;
}

/* ---- Contact ---- */

.tcp-contact-main {
  padding-top: var(--tcp-int-sec-pad-top);
  padding-bottom: var(--tcp-int-sec-pad-bottom);
}

.tcp-contact-grid {
  gap: clamp(40px, 5vw, 72px);
}

.tcp-contact-info h2 {
  font-size: clamp(1.5rem, 2.4vw, 1.9rem) !important;
  margin-bottom: 20px;
}

.tcp-contact-info h2:not(:first-child) {
  margin-top: clamp(38px, 4vw, 54px);
  padding-top: clamp(30px, 3.4vw, 42px);
  border-top: 1px solid transparent;
  border-image: var(--tcp-rule-grad) 1;
}

.tcp-contact-info p {
  font-family: var(--tcp-font-primary);
  font-weight: 300;
  font-size: 0.98rem;
  line-height: 1.9;
  letter-spacing: var(--tcp-track-base);
  color: rgba(74, 75, 76, 0.72);
  margin-bottom: 10px;
}

/* The Phone/Email reveal buttons: squared off and given the same gold-
   on-burgundy hover type as every other primary control. */
.tcp-contact-btn {
  border-radius: 0;
  border-color: rgba(96, 24, 40, 0.5);
  box-shadow: none;
}

.tcp-contact-btn:hover,
.tcp-contact-btn:focus-visible {
  background: var(--tcp-burgundy);
  border-color: var(--tcp-gold);
  color: var(--tcp-btn-gold-text);
}

.tcp-contact-btn .tcp-cbtn-label,
.tcp-contact-btn .tcp-cbtn-value {
  letter-spacing: var(--tcp-track-base);
}

.tcp-contact-btn .tcp-cbtn-label {
  letter-spacing: 0.16em;
}

/* WPForms sits inside the Contact page's light section — squared,
   matte, hairline-framed, same as the rest of the site. */
.wpforms-container .wpforms-field input[type="text"],
.wpforms-container .wpforms-field input[type="email"],
.wpforms-container .wpforms-field input[type="tel"],
.wpforms-container .wpforms-field input[type="url"],
.wpforms-container .wpforms-field select,
.wpforms-container .wpforms-field textarea {
  border: 1px solid var(--tcp-rule-ink) !important;
  border-radius: 0 !important;
  background: rgba(255, 255, 255, 0.7) !important;
  box-shadow: none !important;
  font-family: var(--tcp-font-primary) !important;
  font-weight: 300 !important;
  letter-spacing: var(--tcp-track-base) !important;
  color: var(--tcp-charcoal) !important;
  transition: border-color 0.3s var(--tcp-ease), background 0.3s var(--tcp-ease);
}

/* Not "label.wpforms-field-label" — WPForms renders a grouped field's
   label as a <legend>, which that selector silently skipped. */
.wpforms-container .wpforms-field .wpforms-field-label {
  font-family: var(--tcp-font-primary) !important;
  font-weight: 400 !important;
  font-size: 0.72rem !important;
  letter-spacing: 0.14em !important;
  text-transform: uppercase !important;
  color: rgba(74, 75, 76, 0.7) !important;
}

.wpforms-container .wpforms-submit {
  border-radius: 0 !important;
  background: var(--tcp-burgundy) !important;
  border: 1px solid var(--tcp-burgundy) !important;
  color: var(--tcp-btn-gold-text) !important;
  font-family: var(--tcp-font-primary) !important;
  font-size: 0.72rem !important;
  letter-spacing: 0.16em !important;
  text-transform: uppercase !important;
  padding: 14px 28px !important;
  box-shadow: none !important;
  transition: border-color 0.35s var(--tcp-ease), transform 0.35s var(--tcp-ease);
}

.wpforms-container .wpforms-submit:hover {
  border-color: var(--tcp-gold) !important;
  transform: translateY(-2px);
}

/* ==========================================================================
   8. BLOG / ARCHIVE / SEARCH / 404
   These render through Astra's own templates, not through anything in
   this theme, so their markup can't be given the classes above. Two
   problems to solve:
     (a) the content started immediately below the top of the viewport,
         tucked underneath the 100px fixed header. Per direction, the
         minimum clearance between the bottom of the header and the top
         of the content is 40px; 72px is used here, inside the 60–80px
         range that was preferred.
     (b) no entrance animation, and Astra's default type didn't match.
   body.blog / .archive / .search / .single / .error404 are the classes
   WordPress itself puts on <body>, so this targets exactly those views
   and nothing else.
   ========================================================================== */

/* --tcp-blog-gap is the clearance below the header. Control Panel entry
   kept local to this section since it applies to nothing else. */
body.blog,
body.archive,
body.search,
body.single,
body.error404 {
  /* Astra's blog grid puts its own ~30px of row offset above the first
     article, on top of whatever is set here — so this value is the
     clearance MINUS that offset. 42px lands the top of the first post
     about 72px below the bottom of the fixed header, which is the
     target. Nudge this to move it; the measured result is roughly
     this value + 30. */
  --tcp-blog-gap: 42px;
}

body.blog #primary,
body.archive #primary,
body.search #primary,
body.single #primary,
body.error404 #primary,
body.blog .site-content > .ast-container,
body.archive .site-content > .ast-container,
body.search .site-content > .ast-container,
body.single .site-content > .ast-container,
body.error404 .site-content > .ast-container {
  padding-top: calc(var(--tcp-header-height, 100px) + var(--tcp-blog-gap));
  /* Astra puts a 64px margin-top on #primary of its own. Left in place
     it stacks on top of the clearance above, so the real gap below the
     header came out at ~136px instead of the 72px set here. Zeroed so
     --tcp-blog-gap is the whole answer and adjusting it actually moves
     the content by the amount you'd expect. */
  margin-top: 0;
}

body.blog .entry-title,
body.archive .entry-title,
body.search .entry-title,
body.single .entry-title {
  font-family: var(--tcp-font-display) !important;
  font-weight: 500 !important;
  letter-spacing: var(--tcp-track-display) !important;
  color: var(--tcp-charcoal) !important;
}

body.blog .entry-title a,
body.archive .entry-title a,
body.search .entry-title a {
  color: var(--tcp-charcoal) !important;
  text-decoration: none;
  transition: color 0.3s var(--tcp-ease);
}

body.blog .entry-title a:hover,
body.archive .entry-title a:hover,
body.search .entry-title a:hover {
  color: var(--tcp-burgundy) !important;
}

body.blog .entry-content p,
body.archive .entry-content p,
body.single .entry-content p {
  font-family: var(--tcp-font-primary);
  font-weight: 300;
  font-size: 1.02rem;
  line-height: 1.9;
  letter-spacing: var(--tcp-track-base);
  color: rgba(74, 75, 76, 0.76);
}

/* Astra's post cards get the same matte hairline framing as the rest
   of the site — no box, no shadow, no radius. */
body.blog #primary article,
body.archive #primary article,
body.search #primary article {
  border: 0 !important;
  border-top: 1px solid transparent !important;
  border-image: var(--tcp-rule-grad) 1 !important;
  border-radius: 0 !important;
  box-shadow: none !important;
  background: transparent !important;
  padding-top: clamp(28px, 3.2vw, 40px) !important;
}

/* Astra-rendered views are auto-tagged for the entrance reveal by
   tcp-interior.js (it can't be done in markup here) — this is the
   pre-paint hidden state for exactly the elements it tags, so there's
   no flash of visible-then-hidden content. */
html.tcp-js body.blog #primary article,
html.tcp-js body.archive #primary article,
html.tcp-js body.search #primary article,
html.tcp-js body.blog .ast-archive-description,
html.tcp-js body.archive .ast-archive-description,
html.tcp-js body.single #primary article > .entry-header,
html.tcp-js body.single #primary article > .entry-content > * {
  opacity: 0;
  transform: translateY(var(--tcp-rise-dist));
  transition:
    opacity var(--tcp-rise-dur) var(--tcp-ease),
    transform var(--tcp-rise-dur) var(--tcp-ease);
  transition-delay: calc(var(--tcp-i, 0) * var(--tcp-stagger));
}

html.tcp-js body.blog #primary article.is-visible,
html.tcp-js body.archive #primary article.is-visible,
html.tcp-js body.search #primary article.is-visible,
html.tcp-js body.blog .ast-archive-description.is-visible,
html.tcp-js body.archive .ast-archive-description.is-visible,
html.tcp-js body.single #primary article > .entry-header.is-visible,
html.tcp-js body.single #primary article > .entry-content > *.is-visible {
  opacity: 1;
  transform: translateY(0);
}

@media (prefers-reduced-motion: reduce) {
  html.tcp-js XXNOPEXX body.archive #primary article,
  html.tcp-js body.search #primary article,
  html.tcp-js body.blog .ast-archive-description,
  html.tcp-js body.archive .ast-archive-description,
  html.tcp-js body.single #primary article > .entry-header,
  html.tcp-js body.single #primary article > .entry-content > * {
    opacity: 1 !important;
    transform: none !important;
    transition: none !important;
  }
}

/* ==========================================================================
   9. INNER TICK NAV
   The inner pages' right-hand tick nav sits over light sections, so it
   uses the on-light colours. style.css keys this off body.theme-light,
   which only the front page's scroll handler sets — on the interior
   pages nothing ever sets it, so the nav was rendering in its on-dark
   cream. Stated directly here instead, since these pages are always
   light below the hero band.
   ========================================================================== */

/* No-JS fallback only — :where() keeps this at near-zero specificity so
   the per-link .is-over-dark / .is-over-light classes in style.css always
   win. v1.9.1: these were unwrapped, which meant this file (loading after
   style.css) beat the contrast classes on a specificity tie and forced
   charcoal ticks over the dark page hero. */
:where(.tcp-tick-nav) a { color: rgba(36, 28, 20, var(--tcp-tick-text-rest-alpha, 0.88)); }
:where(.tcp-tick-nav) .tcp-tick { background: rgba(36, 28, 20, var(--tcp-tick-rest-alpha, 0.78)); }
:where(.tcp-tick-nav) a:hover .tcp-tick,
:where(.tcp-tick-nav) a.is-active .tcp-tick { background: var(--tcp-burgundy); }
:where(.tcp-tick-nav) a.is-active { color: var(--tcp-burgundy); }

/* The on-dark state lives in style.css now, as a PER-LINK class rather
   than a nav-level one — see the "Live per-link contrast" block there.
   Nav-level classing could not work here: the nav is taller than the page
   hero band, so its top and bottom items sit on different backgrounds at
   the same time. Nothing on-dark is declared in this file any more, so it
   cannot silently override the engine. */

/* ==========================================================================
   10. RESPONSIVE
   ========================================================================== */

@media (max-width: 920px) {
  .tcp-page-header {
    min-height: 0;
    padding-top: calc(var(--tcp-header-height, 100px) + clamp(40px, 7vh, 64px));
    padding-bottom: clamp(44px, 7vh, 72px);
  }

  .tcp-section-head {
    margin-bottom: clamp(32px, 5vw, 48px);
  }

  .tcp-mark-strip {
    flex-direction: column;
    align-items: flex-start;
    gap: 14px;
  }
}

@media (max-width: 560px) {
  .tcp-page-header h1 {
    font-size: clamp(2rem, 8.6vw, 2.6rem);
  }

  .tcp-page-hero-actions {
    flex-direction: column;
    align-items: stretch;
  }

  .tcp-page-hero-actions .tcp-btn {
    justify-content: center;
  }

  .tcp-framed-card,
  .tcp-area-tier,
  .tcp-svc-card,
  .tcp-shop-card,
  .tcp-sched-step {
    margin: 0;
    padding-left: 0;
    padding-right: 0;
  }
}

/* ==========================================================================
   Change log
   --------------------------------------------------------------------------
   v1.8.0 (2026-09-13) — File created. Sitewide interior-page overhaul
     bringing every non-front page onto the front page's visual system:
     dark soft-light page-hero bands, the shared eyebrow/headline/lede
     heading block, matte hairline framing replacing all gold and glass
     card edges, burgundy/gold buttons, Alga introduced as the third
     type voice, entrance animation and easing on every page, and a
     header-clearance fix for the Astra-rendered blog/archive views.
   v1.8.2 (2026-09-13) — Services page margin fix. The FAQ triage
     section was running edge to edge: services.css redeclares its
     padding as a shorthand with zero side padding, which zeroed the
     gutter that the rest of the page inherits from style.css. The
     interior section rule (section 3) now states padding-left/right as
     their own longhands so this file always wins that collision, for
     every interior section, whatever its page CSS does. Also brought
     the triage answer panel, its "Contact Us" CTA and the follow-up
     chips onto the site's type and control system — they were the last
     three components still on browser-default sizing and rounded grey
     chip styling.
   ========================================================================== */
