/* ============================================================================
   theme.css - JT's Home Repair. Design language: "Contractor / Blueprint".
   Ported from the client-approved build in
   ..\..\Website Upgrade\html-rebuild\jts-custom-css.css (approved 2026-05-28).
   Loads AFTER base.css, which it may restyle but never strip.

   Cool slate palette, squared industrial corners, solid blue eyebrow chips,
   photo-top service cards with a blue number badge, left-anchored hero on a
   blue base bar, dark slate bands carrying a faint blueprint grid.

   Fonts (Fjalla One + Manrope) load via <link> in header.php. Never @import.
   ============================================================================ */

:root {
  color-scheme: light;   /* light-only build, decided deliberately */

  /* ---- Spark seed contract. Mirrored in site-config.php -> theme. ---- */
  --brand-primary:    #003399;   /* JT logo royal blue */
  --brand-accent:     #3D7BE0;
  --brand-neutral:    #14222E;
  --brand-bg:         #ECF1F4;
  --brand-on-primary: #FFFFFF;

  /* ---- Derived color roles. Ratios measured with contrast.py. ---- */
  --color-primary:       #003399;
  --color-primary-hover: #00276F;
  --color-accent:        #3D7BE0;   /* non-text only: fills, rules, icon strokes */
  --color-accent-text:   #003399;   /* 10.86:1 on white, 9.54:1 on #ECF1F4, white on it 10.86:1 */
  --focus-ring:          #003399;   /* 10.86:1 on white */

  --color-text:       #14222E;      /* 14.22:1 on #ECF1F4 */
  --color-text-muted: #56646F;      /* 6.09:1 on white, 5.35:1 on #ECF1F4 */
  --color-bg:         #FFFFFF;
  --color-bg-alt:     #ECF1F4;
  --color-border:     #7E8D9B;      /* 3.40:1 on white - the 1.4.11 bar for input borders */
  --color-rule:       #D6DEE4;      /* decorative hairline only, never a component boundary */

  /* Lifted blue for text on the dark band. #3D7BE0 is only 3.94:1 there. */
  --color-on-dark:        #FFFFFF;  /* 16.18:1 on #14222E */
  --color-on-dark-muted:  #C3CDD6;
  --color-accent-on-dark: #5B8FE8;  /* 5.04:1 on #14222E */

  --color-green:      #08A136;      /* 3.41:1 on white - CHECKMARK GLYPHS ONLY, never text */
  --color-green-dark: #007D26;

  --font-display: "Fjalla One", "Arial Narrow", Arial, sans-serif;
  --font-sans:    "Manrope", system-ui, -apple-system, "Segoe UI", Roboto, Arial, sans-serif;

  --sp-1: .25rem;  --sp-2: .5rem;   --sp-3: .75rem;  --sp-4: 1rem;
  --sp-5: 1.25rem; --sp-6: 1.5rem;  --sp-8: 2rem;    --sp-10: 2.5rem;
  --sp-12: 3rem;   --sp-16: 4rem;   --sp-20: 5rem;   --sp-24: 6rem;

  --content-max: 1240px;
  --reading-max: 44rem;
  --radius-sm: 3px;
  --radius-md: 6px;

  --shadow-sm: 0 1px 3px rgba(20,34,46,.08);
  --shadow:    0 10px 26px rgba(20,34,46,.12);
  --shadow-lg: 0 22px 48px rgba(20,34,46,.20);

  --dur-fast: 150ms;
  --dur-base: 250ms;
  --dur-slow: 600ms;
  --ease:     cubic-bezier(.4, 0, .2, 1);
  --ease-out: cubic-bezier(.16, 1, .3, 1);

  --grid-line: rgba(255,255,255,.05);   /* blueprint grid on dark bands */
}

/* ----------------------------------------------------------------------------
   GLOBAL
   ---------------------------------------------------------------------------- */
body {
  font-family: var(--font-sans);
  color: var(--color-text);
  background: var(--color-bg);
  line-height: 1.65;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

h1, h2, h3, h4 {
  font-family: var(--font-display);
  font-weight: 400;
  line-height: 1.12;
  letter-spacing: .01em;
}

a { color: var(--color-accent-text); text-decoration: none; }
a:hover { text-decoration: underline; text-underline-offset: 3px; }

.container {
  max-width: var(--content-max);
  margin-inline: auto;
  padding-inline: var(--sp-5);
}

.skip-link { background: var(--color-primary); color: #fff; }

/* ----------------------------------------------------------------------------
   HEADER + NAV  (chrome: lives OUTSIDE .jts-page, so it must use --color-*,
   never the --c-* tokens, which only resolve inside the page namespace)
   ---------------------------------------------------------------------------- */
.site-header {
  background: #fff;
  border-bottom: 3px solid var(--color-primary);
  position: sticky;
  top: 0;
  z-index: 50;
}
.site-header__inner {
  max-width: var(--content-max);
  margin-inline: auto;
  padding: 0 var(--sp-5);
  min-height: 7.125rem;              /* 114px = the 98px logo + breathing room */
  display: flex;
  align-items: stretch;
  justify-content: space-between;
  gap: var(--sp-6);
}
.brand { display: inline-flex; align-items: center; gap: var(--sp-3); }
/* 98px is the 58px original plus 70%, per client direction. Height is carried
   by min-height on the bar, not by padding, so nav items run its full height:
   the active underline meets the header rule and the dropdown hangs off the bar
   instead of opening 46px inside it.

   On small screens the padding gives way before the logo does - the logo is the
   part the client cares about. 420px was the wrong split (it put iPhone Plus and
   Pro Max either side of a 14px step), so the phone step is at 480px and is
   LARGER than the value it replaces, in a shorter bar. */
/* aspect-ratio pins the render square at every breakpoint, so a logo is never
   stretched by a height-only rule. object-fit keeps the art inside it. */
.brand__logo { height: 98px; width: auto; aspect-ratio: 1 / 1; object-fit: contain; }
@media (max-width: 900px) {
  .site-header__inner { min-height: 5.875rem; }   /* 94px */
  .brand__logo { height: 78px; }
}
@media (max-width: 480px) {
  .site-header__inner { min-height: 5.25rem; }    /* 84px */
  .brand__logo { height: 68px; }
}
/* Landscape phones: 113px of a 360px-tall viewport was 31% of the screen. */
@media (max-height: 480px) and (orientation: landscape) {
  .site-header__inner { min-height: 3.5rem; }
  .brand__logo { height: 48px; }
}
.nav-toggle { align-self: center; }

.nav-desktop ul {
  display: flex;
  align-items: center;
  gap: var(--sp-6);
  list-style: none;
  margin: 0;
  padding: 0;
}
.nav-desktop a {
  display: block;
  padding: var(--sp-2) 0;
  color: var(--color-text);
  font-weight: 700;
  font-size: .9375rem;
  letter-spacing: .02em;
  text-transform: uppercase;
  border-bottom: 3px solid transparent;
}
.nav-desktop a:hover { color: var(--color-accent-text); text-decoration: none; }
.nav-desktop a[aria-current="page"] {
  color: var(--color-accent-text);
  border-bottom-color: var(--color-primary);
}
.nav-desktop a.cta {
  background: var(--color-primary);
  color: #fff;
  padding: var(--sp-3) var(--sp-5);
  border-radius: var(--radius-sm);
  border-bottom: none;
}
.nav-desktop a.cta:hover { background: var(--color-primary-hover); }

/* display:flex is load-bearing: as a block, .nav-desktop stretched to 114px but
   its <ul> stayed 49px at the top, gluing the nav to the header's top edge with
   65px of white below it. That was worse than the 43px underline gap it was
   meant to fix. */
.nav-desktop { display: flex; }
.nav-desktop ul { align-items: stretch; }
.nav-desktop > ul > li { display: flex; align-items: stretch; }
.nav-desktop a { display: flex; align-items: center; padding-block: 0; }
.nav-desktop a.cta { align-self: center; padding: var(--sp-3) var(--sp-5); }
.nav-desktop .dropdown a { padding: var(--sp-2) var(--sp-4); }

.nav-desktop .has-dropdown { position: relative; }
.nav-desktop .dropdown {
  position: absolute;
  top: 100%;
  left: 0;
  min-width: 15rem;
  background: #fff;
  border: 1px solid var(--color-rule);
  border-top: 3px solid var(--color-primary);
  box-shadow: var(--shadow);
  list-style: none;
  margin: 0;
  padding: var(--sp-2) 0;
  display: none;
}
.nav-desktop .has-dropdown:hover > .dropdown,
.nav-desktop .has-dropdown:focus-within > .dropdown { display: block; }
.nav-desktop .dropdown a {
  padding: var(--sp-2) var(--sp-4);
  text-transform: none;
  font-weight: 600;
  border-bottom: none;
}
.nav-desktop .dropdown a:hover { background: var(--color-bg-alt); }

.nav-toggle {
  display: none;
  align-items: center;
  justify-content: center;
  background: var(--color-primary);
  color: #fff;
  border: none;
  border-radius: var(--radius-sm);
  cursor: pointer;
}
.nav-toggle svg { width: 24px; height: 24px; }

@media (max-width: 900px) {
  .nav-desktop { display: none; }
  .nav-toggle { display: inline-flex; }
}

/* Drawer LOOK only. Its open/close machinery lives in base.css section 7. */
.nav-mobile {
  background: var(--brand-neutral);
  color: #fff;
  padding: var(--sp-3) var(--sp-5) var(--sp-8);
  overflow-y: auto;
  overscroll-behavior: contain;
}
/* Sticky, not absolute. As an absolute child of the scrollport it left the
   screen entirely once Services was expanded and the drawer scrolled, leaving
   no visible way to close. Sticky also frees the 64px of top padding that only
   existed to clear it, which matters on a landscape phone. */
.nav-mobile__close {
  position: sticky;
  top: 0;
  z-index: 2;
  display: block;
  width: 44px;
  margin-left: auto;
  margin-right: calc(-1 * var(--sp-2));
  background: var(--brand-neutral);
  border: none;
  color: #fff;
  font-size: 2rem;
  line-height: 1;
  cursor: pointer;
}
.nav-mobile ul { list-style: none; margin: 0; padding: 0; }
.nav-mobile > ul > li { border-bottom: 1px solid rgba(255,255,255,.12); }
.nav-mobile a {
  display: block;
  padding: var(--sp-3) 0;
  color: #fff;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: .02em;
}
.nav-mobile a[aria-current="page"] { color: var(--color-accent-on-dark); }
.nav-mobile summary {
  padding: var(--sp-3) 0;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: .02em;
  cursor: pointer;
}
.nav-mobile details ul { padding-left: var(--sp-4); }
.nav-mobile details a { text-transform: none; font-weight: 500; }

/* ----------------------------------------------------------------------------
   BREADCRUMBS
   ---------------------------------------------------------------------------- */
.breadcrumbs {
  font-size: .875rem;
  color: var(--color-text-muted);
  padding-block: var(--sp-4);
}
.breadcrumbs ol { list-style: none; display: flex; flex-wrap: wrap; gap: var(--sp-2); margin: 0; padding: 0; }
.breadcrumbs li + li::before { content: "/"; margin-right: var(--sp-2); color: var(--color-border); }

/* Breadcrumb trail inside the page body. The chassis rule above is the generic
   chrome version; this one uses the --c-* page tokens and the trail sits in its
   own thin band directly under the hero, separated by a hairline so it reads as
   wayfinding rather than a second navigation bar.

   Rendered on all 39 pages that call set_breadcrumbs(). Home and 404 are
   deliberately excluded. */
.jts-crumbs { border-bottom: 1px solid var(--c-rule); background: var(--c-surface); }
.jts-page .jts-crumbs .breadcrumbs { padding-block: var(--sp-3); font-size: .8125rem; color: var(--c-ink-2); }
.jts-page .jts-crumbs .breadcrumbs ol { align-items: center; }
.jts-page .jts-crumbs .breadcrumbs a {
  color: var(--c-brand);
  text-decoration: none;
  /* padding keeps each crumb a 24px+ tap target on a phone */
  padding-block: var(--sp-2);
  border-bottom: 1px solid transparent;
}
.jts-page .jts-crumbs .breadcrumbs a:hover { border-bottom-color: currentColor; }
.jts-page .jts-crumbs .breadcrumbs li + li::before { color: var(--c-rule); }
.jts-page .jts-crumbs .breadcrumbs [aria-current="page"] {
  color: var(--c-ink);
  font-weight: 600;
  /* Article crumbs carry the full <h1>, which is the right thing to hand a
     screen reader and to put in the BreadcrumbList. Only the VISUAL length is
     capped: text-overflow hides nothing from assistive tech or from Google,
     unlike truncating the string itself - which is what the article generator
     used to do, shipping "...Starting a Bathroom Renov" into both. */
  display: inline-block;
  max-width: 100%;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  vertical-align: bottom;
}
/* The last crumb is its own flex row so its "/" separator stays glued to it.
   Left as a plain list item, a long article title that wraps to a second line
   left the "/" stranded alone on the line above, reading as a stray character.
   min-width:0 is what lets the title actually shrink so the ellipsis engages -
   without it a flex item refuses to go below its content width. */
.jts-page .jts-crumbs .breadcrumbs ol > li:last-child {
  min-width: 0;
  display: flex;
  align-items: baseline;
}

/* ----------------------------------------------------------------------------
   BUTTONS (shared by chrome and page)
   ---------------------------------------------------------------------------- */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--sp-2);
  padding: var(--sp-3) var(--sp-6);
  border: 2px solid transparent;
  border-radius: var(--radius-sm);
  font-family: var(--font-display);
  font-size: 1rem;
  letter-spacing: .03em;
  text-transform: uppercase;
  cursor: pointer;
  transition: transform var(--dur-fast) var(--ease), background var(--dur-fast) var(--ease);
}
.btn:hover { text-decoration: none; transform: translateY(-2px); }
.btn-primary { background: var(--color-primary); color: #fff; }
.btn-primary:hover { background: var(--color-primary-hover); }
.btn-ghost { background: transparent; color: var(--color-accent-text); border-color: var(--color-primary); }
.btn-ghost:hover { background: var(--color-primary); color: #fff; }
.btn-on-dark { background: #fff; color: var(--color-accent-text); }
.btn-on-dark:hover { background: var(--color-bg-alt); }
.btn-lg { padding: var(--sp-4) var(--sp-8); font-size: 1.0625rem; }

/* ----------------------------------------------------------------------------
   FORMS
   ---------------------------------------------------------------------------- */
.form { display: grid; gap: var(--sp-5); max-width: 42rem; }
.form-grid { display: grid; gap: var(--sp-5); }
@media (min-width: 640px) { .form-grid { grid-template-columns: 1fr 1fr; } }
.form-row { display: grid; gap: var(--sp-2); }
.form label { font-weight: 700; font-size: .9375rem; }
.form input, .form textarea, .form select {
  width: 100%;
  padding: var(--sp-3) var(--sp-4);
  background: #fff;
  border: 2px solid var(--color-border);
  border-radius: var(--radius-sm);
  color: var(--color-text);
}
.form textarea { min-height: 9rem; resize: vertical; }
.form input:focus, .form textarea:focus, .form select:focus { border-color: var(--color-primary); }
.form .hp { position: absolute; left: -9999px; width: 1px; height: 1px; overflow: hidden; }
.field-error { color: #B3261E; font-weight: 600; margin-top: var(--sp-1); }
.form-status { font-weight: 700; }
.form-status:empty { display: none; }
.form-status[data-state="error"] { color: #B3261E; }
.form-status[data-state="ok"]    { color: var(--color-green-dark); }
.form input[aria-invalid="true"],
.form select[aria-invalid="true"],
.form textarea[aria-invalid="true"] { border-color: #B3261E; }

/* The contact form's radio group is a <fieldset> and nothing styled it, so it
   rendered with the UA's 2px groove border drawn straight through the wrapped
   legend on any phone. */
.form fieldset { border: 0; padding: 0; margin: 0; min-inline-size: 0; }
.form legend {
  padding: 0;
  font-weight: 700;
  font-size: .9375rem;
  line-height: 1.4;
  margin-bottom: var(--sp-2);
}

/* Radios were 13x13 with 25px labels - a third of the 44px target floor. */
.radio-row { display: flex; flex-wrap: wrap; gap: var(--sp-3) var(--sp-4); }
.radio-row label {
  display: inline-flex;
  align-items: center;
  gap: var(--sp-2);
  font-weight: 500;
  min-height: 44px;
  padding: var(--sp-2) var(--sp-4);
  border: 2px solid var(--color-border);
  border-radius: var(--radius-sm);
  cursor: pointer;
}
.radio-row label:has(input:checked) { border-color: var(--color-primary); }
.radio-row input { width: 22px; height: 22px; flex: none; accent-color: var(--color-primary); }

/* ----------------------------------------------------------------------------
   FOOTER
   ---------------------------------------------------------------------------- */
.site-footer {
  background: var(--brand-neutral);
  color: var(--color-on-dark);
  padding-top: var(--sp-16);
  background-image:
    linear-gradient(var(--grid-line) 1px, transparent 1px),
    linear-gradient(90deg, var(--grid-line) 1px, transparent 1px);
  background-size: 40px 40px, 40px 40px;
}
/* Logo and tagline sit centred on their own row above the link columns. */
.site-footer__top {
  max-width: var(--content-max);
  margin-inline: auto;
  padding: 0 var(--sp-5) var(--sp-12);
  text-align: center;
}
.site-footer__top .brand { display: inline-flex; }
.site-footer__top .brand__logo { height: 150px; width: auto; aspect-ratio: 1 / 1; object-fit: contain; }
.site-footer__tagline {
  color: var(--color-on-dark-muted);
  margin-top: var(--sp-5);
  margin-inline: auto;
  max-width: 44rem;
  font-size: 1.125rem;
}

.site-footer__grid {
  max-width: var(--content-max);
  margin-inline: auto;
  padding: 0 var(--sp-5) var(--sp-12);
  display: grid;
  gap: var(--sp-10) var(--sp-8);
  grid-template-columns: 1fr;
}
@media (min-width: 560px)  { .site-footer__grid { grid-template-columns: 1fr 1fr; } }
@media (min-width: 1024px) { .site-footer__grid { grid-template-columns: repeat(4, 1fr); } }
.site-footer__address { font-style: normal; line-height: 1.9; }
/* inline-block + padding: as a bare inline link the phone number measured
   117x22, under the 24px minimum target (WCAG 2.5.8), and it is the single
   most important tap on the page for a contractor's site. */
.site-footer__address a {
  display: inline-block;
  padding-block: var(--sp-2);
  color: var(--color-accent-on-dark);
  font-weight: 700;
}
.site-footer h2 {
  font-size: 1rem;
  text-transform: uppercase;
  letter-spacing: .08em;
  margin-bottom: var(--sp-4);
  color: #fff;
}
.site-footer ul { list-style: none; margin: 0; padding: 0; display: grid; gap: var(--sp-2); }
.site-footer a { color: var(--color-on-dark-muted); }
.site-footer a:hover { color: #fff; }
/* Service-area cities are not links. Same text colour as the link columns
   so the grid reads as one block, but no hover and no pointer. */
.site-footer__grid li > span { color: var(--color-on-dark-muted); }

.site-footer__social { display: flex; gap: var(--sp-3); margin-top: var(--sp-5); }
.site-footer__social a {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 44px;
  height: 44px;
  border: 1px solid rgba(255,255,255,.25);
  border-radius: var(--radius-sm);
}
.site-footer__social svg { width: 20px; height: 20px; }

.site-footer__bottom {
  border-top: 1px solid rgba(255,255,255,.14);
  padding: var(--sp-5);
  max-width: var(--content-max);
  margin-inline: auto;
  display: flex;
  flex-wrap: wrap;
  gap: var(--sp-3);
  justify-content: space-between;
  font-size: .875rem;
  color: var(--color-on-dark-muted);
}
.site-footer__credit a { color: var(--color-on-dark-muted); text-decoration: underline; }
/* Privacy and Terms sit beside the copyright, not in a grid column.
   inline-block + margin, not a flex gap: the copyright sentence and the
   links share one <span> so they wrap together as a unit on a phone. */
.site-footer__copy a {
  display: inline-block;
  margin-left: var(--sp-4);
  color: var(--color-on-dark-muted);
  text-decoration: underline;
  /* The bare line box measured 23px tall - 1px under the 24px minimum target
     (WCAG 2.5.8). Padding, not a height, so the text stays on the baseline of
     the copyright sentence it sits in. */
  padding-block: var(--sp-2);
}
.site-footer__copy a:hover { color: #fff; }
/* inline-block is load-bearing: base.css sets svg{display:block}, and a flex
   parent here would eat the spaces and render "Website Designby". */
.spark-mark {
  display: inline-block;
  width: 2.2em;
  height: 2.2em;
  margin-left: .15em;
  vertical-align: middle;
}

/* ----------------------------------------------------------------------------
   CONSENT NOTICE
   ---------------------------------------------------------------------------- */
.consent-banner[hidden] { display: none; }
.consent-banner {
  position: fixed;
  inset: auto 0 0 0;
  z-index: 60;
  background: var(--brand-neutral);
  color: #fff;
  padding: var(--sp-4) var(--sp-5);
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: center;
  gap: var(--sp-4);
  font-size: .9375rem;
}
.consent-banner a { color: var(--color-accent-on-dark); text-decoration: underline; }
.consent-banner button {
  background: var(--color-primary);
  color: #fff;
  border: none;
  border-radius: var(--radius-sm);
  padding: var(--sp-2) var(--sp-6);
  font-weight: 700;
  cursor: pointer;
}

/* ============================================================================
   .jts-page - THE PAGE NAMESPACE
   Everything below is scoped. The --c-* tokens resolve ONLY in here, which is
   why the header, footer and drawer above use --color-* instead.
   ============================================================================ */
.jts-page {
  --c-bg:            #ECF1F4;
  --c-surface:       #FFFFFF;
  --c-ink:           #14222E;
  --c-ink-2:         #56646F;
  --c-rule:          #D6DEE4;
  --c-brand:         #003399;
  --c-brand-dark:    #00276F;
  --c-brand-bright:  #3D7BE0;
  --c-brand-on-dark: #5B8FE8;
  --c-green:         #08A136;
  --c-band-dark:     #14222E;
  --c-on-dark:       rgba(255,255,255,.95);

  background: var(--c-bg);
  color: #2B3942;
}

/* ---- layout primitives ---- */
.jts-container { max-width: var(--content-max); margin-inline: auto; padding-inline: var(--sp-5); }
.jts-section { padding-block: var(--sp-20); }
.jts-section--tight { padding-block: var(--sp-12); }
.jts-surface { background: var(--c-surface); }
.jts-band { padding-block: var(--sp-16); }
.jts-band--muted { background: var(--c-bg); }
.jts-band--dark {
  background: var(--c-band-dark);
  color: var(--c-on-dark);
  background-image:
    linear-gradient(var(--grid-line) 1px, transparent 1px),
    linear-gradient(90deg, var(--grid-line) 1px, transparent 1px);
  background-size: 40px 40px, 40px 40px;
}
.jts-band__inner { max-width: var(--content-max); margin-inline: auto; padding-inline: var(--sp-5); }
.jts-mt-sm { margin-top: var(--sp-5); }
.jts-mt-lg { margin-top: var(--sp-10); }

/* ---- typography ---- */
/* Section label. This was a filled blue chip with white uppercase text, which
   read as a button - a non-interactive label inviting a click, sitting on pages
   that carry real buttons in the same colour. It is now a drafting marker:
   uppercase text between two short rules, no fill and no radius, which suits
   the blueprint language the rest of the page already uses and cannot be
   mistaken for a control. */
.jts-eyebrow {
  display: inline-flex;
  align-items: center;
  gap: var(--sp-3);
  background: none;
  padding: 0;
  border-radius: 0;
  color: var(--c-brand);                 /* 9.54:1 on the page bg, 10.86:1 on white */
  font-family: var(--font-display);
  font-size: .8125rem;
  letter-spacing: .18em;
  text-transform: uppercase;
  margin-bottom: var(--sp-5);
}
.jts-eyebrow::before,
.jts-eyebrow::after {
  content: "";
  flex: none;
  width: 1.5rem;
  height: 2px;
  background: currentColor;
}
/* Centre on its own margins, not on the parent's text-align: .jts-hero__copy
   never sets text-align, so an inline-flex marker there hugged the left edge
   while the headline above it was centred. */
.jts-eyebrow--center { display: flex; width: fit-content; margin-inline: auto; }

/* On a dark band the marker lifts to the on-dark blue (5.04:1). Over the hero
   photo it goes white: no blue holds a reliable ratio against an image. */
.jts-eyebrow--light,
.jts-band--dark .jts-eyebrow { color: var(--c-brand-on-dark); background: none; }

@media (max-width: 479px) {
  /* Measured wrapping at 320 / 360 / 390 - "Locally Owned - Central Arkansas"
     and friends go to two lines, which strands the flanking rules beside the
     first line and reads as broken. Clean from 414px up.

     Below 480 the rules come off. The label is still uppercase, letterspaced
     and brand-coloured, so it still reads as a section marker rather than a
     button - which was the whole point of the restyle. */
  .jts-eyebrow::before,
  .jts-eyebrow::after { display: none; }
  .jts-eyebrow { display: block; gap: 0; }
  .jts-eyebrow--center { width: auto; margin-inline: 0; text-align: center; }
}
.jts-hero .jts-eyebrow { color: #fff; }

.jts-display {
  font-family: var(--font-display);
  font-size: clamp(2.25rem, 5vw + 1rem, 4rem);
  line-height: 1.04;
  text-transform: uppercase;
  color: var(--c-ink);
}
.jts-display--lg { font-size: clamp(2.375rem, 6vw + 1rem, 4.75rem); }
.jts-display--center { text-align: center; }
.jts-display--inverse { color: #fff; }

.jts-h2 {
  font-family: var(--font-display);
  font-size: clamp(1.75rem, 2.4vw + 1rem, 2.6875rem);
  line-height: 1.14;
  color: var(--c-ink);
}
.jts-h2--inverse { color: #fff; }
.jts-h3 { font-family: var(--font-display); font-size: 1.3125rem; color: var(--c-ink); }

.jts-lead { font-size: 1.1875rem; line-height: 1.7; color: var(--c-ink-2); max-width: var(--reading-max); }
.jts-lead--center { margin-inline: auto; text-align: center; }
.jts-lead--inverse { color: rgba(255,255,255,.88); }
.jts-lead--muted { color: var(--c-ink-2); }
.jts-body { line-height: 1.75; max-width: var(--reading-max); }
.jts-body--center { margin-inline: auto; text-align: center; }
.jts-body--inverse { color: rgba(255,255,255,.88); }
.jts-muted { color: var(--c-ink-2); }

.jts-section__head { margin-bottom: var(--sp-10); }
.jts-section__head--center { text-align: center; }
.jts-section__head--center .jts-lead { margin-inline: auto; }

/* ---- checkmark lists. The green is 3.41:1, a NON-TEXT glyph color only. ---- */
.jts-checks { list-style: none; margin: var(--sp-6) 0 0; padding: 0; display: grid; gap: var(--sp-4); }
.jts-checks--2col { grid-template-columns: 1fr; }
@media (min-width: 720px) { .jts-checks--2col { grid-template-columns: 1fr 1fr; } }
.jts-checks li { position: relative; padding-left: var(--sp-8); }
.jts-checks li::before {
  content: "";
  position: absolute;
  left: 0;
  top: .45em;
  width: 1.125rem;
  height: .625rem;
  border-left: 3px solid var(--c-green);
  border-bottom: 3px solid var(--c-green);
  transform: rotate(-45deg);
}

/* ---- hero: left-anchored copy, blue base bar, left-weighted scrim ---- */
.jts-hero {
  position: relative;
  min-height: 34rem;
  display: flex;
  align-items: flex-end;
  overflow: hidden;
  background-color: var(--c-band-dark);   /* base under the photo + veil */
}
.jts-hero--inner { min-height: 24rem; }
.jts-hero__bg { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }
.jts-hero__veil {
  position: absolute;
  inset: 0;
  /* Was left-weighted (.88 -> .18 across), which suits left-anchored copy. The
     copy is centred and full-width, so the right end of every line sat on a .18
     scrim: measured 2.69:1 for the white headline and 1.23:1 for the accent
     word. Symmetric now, and darker at both edges than the old right edge. */
  background:
    linear-gradient(90deg, rgba(20,34,46,.80) 0%, rgba(20,34,46,.72) 50%, rgba(20,34,46,.80) 100%),
    linear-gradient(0deg, rgba(20,34,46,.75) 0%, rgba(20,34,46,0) 55%);
}
/* The blue base bar sits on the hero, not on the 1240px copy column: on the
   column it stopped 92px short of each edge above 1280 and only went full-bleed
   below it, so the same element meant two different things by viewport. */
.jts-hero { border-bottom: 10px solid var(--c-brand); }
.jts-hero__copy {
  position: relative;
  max-width: var(--content-max);
  margin-inline: auto;
  width: 100%;
  padding: var(--sp-20) var(--sp-5) var(--sp-16);
}
.jts-hero .jts-display { color: #fff; }
.jts-hero .jts-lead { color: rgba(255,255,255,.92); }
.jts-hero__ctas { display: flex; flex-wrap: wrap; gap: var(--sp-4); margin-top: var(--sp-8); }
.jts-btn-row { display: flex; flex-wrap: wrap; gap: var(--sp-4); margin-top: var(--sp-8); }
.jts-btn-row--center { justify-content: center; }

/* ---- accolades strip ---- */
.jts-accolades { background: #fff; border-bottom: 1px solid var(--c-rule); }
.jts-accolades__inner {
  max-width: var(--content-max);
  margin-inline: auto;
  padding: var(--sp-5);
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: center;
  gap: var(--sp-6);
}
.jts-accolades__label { font-weight: 700; color: var(--c-ink-2); }
.jts-accolades__seals { display: flex; align-items: center; gap: var(--sp-5); }
.jts-bbb-seal img { height: 42px; width: auto; }

/* ---- stats bar: dark slate + blueprint grid. The numbers are white, so the
        dark background is load-bearing, not decoration. ---- */
.jts-stats {
  padding-block: var(--sp-12);
  color: #fff;
  background-color: var(--c-band-dark);
  background-image:
    linear-gradient(var(--grid-line) 1px, transparent 1px),
    linear-gradient(90deg, var(--grid-line) 1px, transparent 1px);
  background-size: 30px 30px, 30px 30px;
}
.jts-stats__grid {
  display: grid;
  gap: var(--sp-8);
  grid-template-columns: repeat(2, 1fr);
  list-style: none;
  margin: 0;
  padding: 0;
}
@media (min-width: 900px) { .jts-stats__grid { grid-template-columns: repeat(4, 1fr); } }
.jts-stat__num { font-family: var(--font-display); font-size: clamp(2rem, 3vw + 1rem, 3rem); color: #fff; line-height: 1; }
.jts-stat__lbl {
  font-size: .6875rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: .14em;
  line-height: 1.35;
  color: rgba(255,255,255,.82);
}

/* ---- service cards: photo top, white body, blue number badge + top tab ---- */
.jts-services__grid { display: grid; gap: var(--sp-6); grid-template-columns: 1fr; }
@media (min-width: 640px)  { .jts-services__grid { grid-template-columns: repeat(2, 1fr); } }
@media (min-width: 1024px) { .jts-services__grid { grid-template-columns: repeat(4, 1fr); } }
.jts-services__grid--3 { grid-template-columns: 1fr; }
@media (min-width: 640px)  { .jts-services__grid--3 { grid-template-columns: repeat(2, 1fr); } }
@media (min-width: 1024px) { .jts-services__grid--3 { grid-template-columns: repeat(3, 1fr); } }

.jts-frost {
  position: relative;
  background: var(--c-surface);
  border: 1px solid var(--c-rule);
  border-top: 4px solid var(--c-brand);
  border-radius: var(--radius-sm);
  overflow: hidden;
  box-shadow: var(--shadow-sm);
  transition: transform var(--dur-base) var(--ease), box-shadow var(--dur-base) var(--ease);
  display: flex;
  flex-direction: column;
}
.jts-frost:hover { transform: translateY(-4px); box-shadow: var(--shadow); }
.jts-frost__img { width: 100%; aspect-ratio: 4 / 3; object-fit: cover; }
.jts-frost__panel { padding: var(--sp-8) var(--sp-6) var(--sp-6); position: relative; flex: 1; }
.jts-frost__num {
  position: absolute;
  top: calc(-1 * var(--sp-5));
  left: var(--sp-6);
  background: var(--c-brand);
  color: #fff;
  font-family: var(--font-display);
  font-size: 1rem;
  padding: var(--sp-2) var(--sp-3);
  border-radius: var(--radius-sm);
}
.jts-frost__title { font-family: var(--font-display); font-size: 1.25rem; color: var(--c-ink); margin-bottom: var(--sp-2); }
.jts-frost__desc { color: var(--c-ink-2); font-size: .9375rem; }
/* A bare div holding two buttons, so it never got the .jts-btn-row treatment:
   the buttons sat 3px apart and wrapped to ragged widths on phones. */
.jts-services__cta {
  margin-top: var(--sp-10);
  display: flex;
  flex-wrap: wrap;
  gap: var(--sp-4);
  justify-content: center;
}

/* ---- split: image on an offset blue accent block ---- */
.jts-split__inner {
  max-width: var(--content-max);
  margin-inline: auto;
  padding-inline: var(--sp-5);
  display: grid;
  gap: var(--sp-12);
  align-items: center;
  grid-template-columns: 1fr;
}
@media (min-width: 900px) { .jts-split__inner { grid-template-columns: 1fr 1fr; } }
.jts-split__media { position: relative; }
.jts-split__media::before {
  content: "";
  position: absolute;
  inset: var(--sp-6) calc(-1 * var(--sp-5)) calc(-1 * var(--sp-5)) var(--sp-6);
  background: var(--c-brand);
  border-radius: var(--radius-sm);
}
.jts-split__media img { position: relative; width: 100%; border-radius: var(--radius-sm); box-shadow: var(--shadow); }
@media (min-width: 900px) { .jts-split--reverse .jts-split__media { order: 2; } }
.jts-duo { display: grid; gap: var(--sp-8); grid-template-columns: 1fr; }
@media (min-width: 900px) { .jts-duo { grid-template-columns: 1fr 1fr; } }

/* ---- process steps ---- */
.jts-process__grid { display: grid; gap: var(--sp-6); grid-template-columns: 1fr; }
@media (min-width: 900px) { .jts-process__grid { grid-template-columns: repeat(3, 1fr); } }
.jts-step {
  background: var(--c-surface);
  border: 1px solid var(--c-rule);
  border-top: 4px solid var(--c-brand);
  border-radius: var(--radius-sm);
  padding: var(--sp-8) var(--sp-6) var(--sp-6);
  position: relative;
}
.jts-step__num {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 2.75rem;
  height: 2.75rem;
  background: var(--c-brand);
  color: #fff;
  font-family: var(--font-display);
  font-size: 1.375rem;
  border-radius: var(--radius-sm);
  margin-bottom: var(--sp-4);
}

/* ---- testimonials ---- */
.jts-quotes__grid { display: grid; gap: var(--sp-6); grid-template-columns: 1fr; }
/* 3 quotes: a 2-col grid orphans one, so stay single-column but cap the measure. */
@media (max-width: 899px) { .jts-quotes__grid { max-width: 34rem; margin-inline: auto; } }
@media (min-width: 900px) { .jts-quotes__grid { grid-template-columns: repeat(3, 1fr); } }
.jts-quote {
  background: var(--c-surface);
  border: 1px solid var(--c-rule);
  border-top: 4px solid var(--c-brand);
  border-radius: var(--radius-sm);
  padding: var(--sp-8) var(--sp-6) var(--sp-6);
  margin: 0;
}
.jts-quote__stars { color: var(--c-brand); letter-spacing: .1em; margin-bottom: var(--sp-3); }
.jts-quote__text { line-height: 1.7; }
.jts-quote__name { display: block; margin-top: var(--sp-4); font-weight: 700; color: var(--c-ink); font-style: normal; }

/* ---- FAQ accordion (native <details>, no JS) ---- */
.jts-faq { display: grid; gap: var(--sp-3); max-width: 52rem; margin-inline: auto; }
.jts-faq__item {
  background: var(--c-surface);
  border: 1px solid var(--c-rule);
  border-left: 4px solid var(--c-brand);
  border-radius: var(--radius-sm);
}
.jts-faq__item summary {
  cursor: pointer;
  padding: var(--sp-4) var(--sp-6);
  font-family: var(--font-display);
  font-size: 1.125rem;
  color: var(--c-ink);
  list-style: none;
  display: flex;
  justify-content: space-between;
  gap: var(--sp-4);
}
.jts-faq__item summary::-webkit-details-marker { display: none; }
.jts-faq__item summary::after { content: "+"; color: var(--c-brand); font-size: 1.5rem; line-height: 1; }
.jts-faq__item[open] summary::after { content: "-"; }
.jts-faq__answer { padding: 0 var(--sp-6) var(--sp-5); color: var(--c-ink-2); }

/* ---- gallery ---- */
.jts-gallery-group { margin-bottom: var(--sp-12); }
.jts-gallery-group__head { margin-bottom: var(--sp-5); }
.jts-gallery { display: grid; gap: var(--sp-4); grid-template-columns: 1fr; }
@media (min-width: 480px) { .jts-gallery { grid-template-columns: repeat(2, 1fr); } }
@media (min-width: 900px) { .jts-gallery--4 { grid-template-columns: repeat(4, 1fr); } }
.jts-gallery__tile {
  display: block;
  position: relative;
  width: 100%;
  aspect-ratio: 4 / 3;
  overflow: hidden;
  border-radius: var(--radius-sm);
  border: 1px solid var(--c-rule);
  cursor: zoom-in;
  color: #fff;
}
/* object-fit belongs on the <img>, not the link that wraps it. */
.jts-gallery__tile img { width: 100%; height: 100%; object-fit: cover; display: block; }

/* Hover/focus affordance. The tiles are links to a photo, so they need to say
   "this opens the picture" rather than just darken like a nav item. The plus is
   two gradients rather than an icon: 12 inline SVGs for pure decoration is 12
   more things to keep in sync. */
.jts-gallery__tile::before,
.jts-gallery__tile::after {
  content: "";
  position: absolute;
  opacity: 0;
  transition: opacity .18s ease;
}
.jts-gallery__tile::before { inset: 0; background: rgba(20, 34, 46, .55); }
.jts-gallery__tile::after {
  inset: 50% auto auto 50%;
  width: 44px; height: 44px;
  translate: -50% -50%;
  border: 2px solid currentColor;
  border-radius: 50%;
  background:
    linear-gradient(currentColor 0 0) center / 16px 2px no-repeat,
    linear-gradient(currentColor 0 0) center / 2px 16px no-repeat;
}
.jts-gallery__tile:hover::before, .jts-gallery__tile:hover::after,
.jts-gallery__tile:focus-visible::before, .jts-gallery__tile:focus-visible::after { opacity: 1; }
@media (prefers-reduced-motion: reduce) {
  .jts-gallery__tile::before, .jts-gallery__tile::after { transition: none; }
}

/* ---- full-size photo viewer (includes/lightbox.php) ---- */
.jts-lightbox {
  /* Reset the UA box so the dialog is just a full-screen stage. */
  width: 100%; max-width: 100%;
  height: 100%; max-height: 100%;
  margin: 0; padding: var(--sp-4);
  border: 0; background: transparent; overflow: hidden;
}
.jts-lightbox::backdrop { background: rgba(10, 18, 26, .92); }
.jts-lightbox__stage {
  height: 100%;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: var(--sp-2);
}
.jts-lightbox__figure {
  margin: 0;
  min-width: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--sp-4);
}
.jts-lightbox__figure picture { display: contents; }
.jts-lightbox__figure img {
  /* Never upscale: four of these originals are only 400px wide and stretching
     them to fill the viewport just shows the reader a blurry photo. */
  max-width: min(100%, 900px);
  max-height: 78vh;
  width: auto; height: auto;
  border-radius: var(--radius-sm);
  background: var(--color-band-dark);
}
.jts-lightbox__caption {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  justify-content: center;
  gap: var(--sp-2) var(--sp-4);
  max-width: 62ch;
  text-align: center;
  font-size: .9375rem;
  color: #C3CDD6;   /* 11.69:1 on the backdrop */
}
.jts-lightbox__count {
  font-family: var(--font-display);
  letter-spacing: .14em;
  font-size: .8125rem;
  color: #8FA3B4;   /* 7.24:1 on the backdrop */
}
.jts-lightbox__btn,
.jts-lightbox__close {
  flex: none;
  display: grid;
  place-items: center;
  width: 44px; height: 44px;
  padding: 0;
  border: 1px solid rgba(255,255,255,.28);
  border-radius: var(--radius-sm);
  background: rgba(255,255,255,.06);
  color: #fff;
  cursor: pointer;
}
.jts-lightbox__btn:hover,
.jts-lightbox__close:hover { background: rgba(255,255,255,.18); }
.jts-lightbox__btn svg,
.jts-lightbox__close svg { width: 22px; height: 22px; }
.jts-lightbox__close { position: absolute; top: var(--sp-4); right: var(--sp-4); }

@media (max-width: 560px) {
  /* No room for side arrows next to the photo on a phone - drop them under it
     and let swipe-free tapping do the work. */
  .jts-lightbox__stage { flex-wrap: wrap; align-content: center; }
  .jts-lightbox__figure { order: -1; flex-basis: 100%; }
  .jts-lightbox__figure img { max-height: 64vh; }
}

/* ---- resources / article cards ---- */
.jts-articles { display: grid; gap: var(--sp-6); grid-template-columns: 1fr; }
@media (min-width: 640px)  { .jts-articles { grid-template-columns: repeat(2, 1fr); } }
@media (min-width: 1024px) { .jts-articles { grid-template-columns: repeat(3, 1fr); } }
.jts-article {
  background: var(--c-surface);
  border: 1px solid var(--c-rule);
  border-top: 4px solid var(--c-brand);
  border-radius: var(--radius-sm);
  padding: var(--sp-8) var(--sp-6) var(--sp-6);
  display: flex;
  flex-direction: column;
  gap: var(--sp-3);
}
.jts-article__meta { font-size: .8125rem; letter-spacing: .08em; text-transform: uppercase; color: var(--c-ink-2); }
.jts-article__title { font-family: var(--font-display); font-size: 1.1875rem; line-height: 1.25; }
.jts-article__title a { color: var(--c-ink); }
.jts-article__title a:hover { color: var(--c-brand); }
.jts-article__excerpt { color: var(--c-ink-2); font-size: .9375rem; flex: 1; }

/* ---- long-form article body ---- */
.jts-prose { max-width: var(--reading-max); margin-inline: auto; }
.jts-prose > * + * { margin-top: var(--sp-5); }
.jts-prose h2 { font-family: var(--font-display); font-size: 1.625rem; color: var(--c-ink); margin-top: var(--sp-10); }
.jts-prose h3 { font-family: var(--font-display); font-size: 1.25rem; color: var(--c-ink); margin-top: var(--sp-8); }
.jts-prose ul, .jts-prose ol { padding-left: var(--sp-6); display: grid; gap: var(--sp-2); }
.jts-prose a { text-decoration: underline; text-underline-offset: 3px; }
.jts-prose strong { color: var(--c-ink); }

/* ---- contact band ---- */
.jts-contact__inner {
  max-width: var(--content-max);
  margin-inline: auto;
  padding-inline: var(--sp-5);
  display: grid;
  gap: var(--sp-12);
  grid-template-columns: 1fr;
}
@media (min-width: 900px) { .jts-contact__inner { grid-template-columns: 1fr 1fr; } }
.jts-contact__list { list-style: none; margin: var(--sp-6) 0 0; padding: 0; display: grid; gap: var(--sp-4); }
.jts-contact__list a { color: var(--c-brand); font-weight: 700; }
.jts-contact .jts-contact__list a,
.jts-band--dark .jts-contact__list a { color: var(--c-brand-on-dark); }
.jts-contact__areas { margin-top: var(--sp-8); }
.jts-areas-label { font-weight: 700; margin-bottom: var(--sp-2); }
.jts-form-slot {
  background: var(--c-surface);
  border-radius: var(--radius-sm);
  padding: var(--sp-8);
  color: var(--c-ink);
}
.jts-form-slot .form { max-width: none; }

/* ---- CSS-only reveal on scroll. No JavaScript anywhere in this design, by
        client request. base.css section 6 neutralises it for reduced motion. ---- */
@supports (animation-timeline: view()) {
  .jts-reveal {
    animation: jts-rise both;
    animation-timeline: view();
    animation-range: entry 0% entry 42%;
  }
}
@keyframes jts-rise {
  from { opacity: 0; transform: translateY(18px); }
  to   { opacity: 1; transform: translateY(0); }
}

/* ---- img() wraps every image in <picture>; display:contents keeps the <img>
        a direct grid/flex child so card and hero layouts are unaffected ---- */
picture { display: contents; }

/* ---- accent word inside a heading. Brand blue on light, white on dark, and
        the lifted blue over the hero photo where #003399 would go muddy. ---- */
.jts-display em, .jts-h2 em, .jts-h3 em { font-style: normal; color: var(--c-brand); }
/* #5B8FE8 measured 1.66:1 against the brightest part of the hero photo - the
   headline's accent words land on a white wall at the centre of the frame, which
   is exactly where the veil is lightest. #A9C6F5 on that same backdrop, with the
   veil centre now .72, measures 3.93:1 against a 3:1 bar for 44px text. */
.jts-hero .jts-display em { color: #A9C6F5; }
.jts-band--dark .jts-h2 em,
.jts-band--dark .jts-display em,
.jts-contact .jts-h2 em,
.jts-contact .jts-display em,
.jts-stat__num em { font-style: normal; color: #fff; }

/* ---- generic content card ---- */
.jts-card {
  background: var(--c-surface);
  border: 1px solid var(--c-rule);
  border-top: 3px solid var(--c-brand);
  border-radius: var(--radius-sm);
  padding: var(--sp-8) var(--sp-6);
  box-shadow: var(--shadow-sm);
}
.jts-card .jts-h3 { margin-top: 0; }

/* ---- split copy column ---- */
.jts-split__copy > * + * { margin-top: var(--sp-4); }

/* ---- stat cell ---- */
.jts-stat {
  display: flex;
  flex-direction: column;
  gap: var(--sp-2);
  padding-top: var(--sp-3);
  border-top: 3px solid var(--c-brand-bright);
  text-align: left;
}

/* ---- dark contact band ---- */
.jts-contact {
  color: #fff;
  padding-block: var(--sp-20);
  background-color: var(--c-band-dark);
  background-image:
    linear-gradient(var(--grid-line) 1px, transparent 1px),
    linear-gradient(90deg, var(--grid-line) 1px, transparent 1px);
  background-size: 30px 30px, 30px 30px;
}
.jts-contact .jts-eyebrow { background: none; color: var(--c-brand-on-dark); }   /* 5.04:1 on the dark band */
.jts-contact .jts-h2 { color: #fff; }
.jts-contact .jts-lead { color: rgba(255,255,255,.9); }
/* These two lists appear BOTH on the dark contact band and inside a white
   .jts-card on the contact page. They used to be hard-coded for the dark band,
   which rendered the labels and the service-area names white on white - the
   same NAP-card regression logged on 2026-07-22. Default to the light surface
   and flip to the knockout treatment only inside a dark context. */
.jts-contact__list li {
  padding: var(--sp-3) 0;
  border-bottom: 1px solid var(--c-rule);
  color: var(--c-ink);
}
.jts-contact__list li span.lbl {
  display: block;
  font-size: .6875rem;
  font-weight: 700;
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--c-ink-2);
  margin-bottom: var(--sp-1);
}
.jts-contact__areas {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: var(--sp-2) var(--sp-6);
  list-style: none;
  margin: var(--sp-3) 0 0;
  padding: 0;
}
.jts-contact__areas li { position: relative; padding-left: var(--sp-5); color: var(--c-ink); }
.jts-areas-label { color: var(--c-ink); }

.jts-contact .jts-contact__list li,
.jts-band--dark .jts-contact__list li { border-bottom-color: rgba(255,255,255,.14); color: rgba(255,255,255,.96); }
.jts-contact .jts-contact__list li span.lbl,
.jts-band--dark .jts-contact__list li span.lbl { color: rgba(255,255,255,.85); }
.jts-contact .jts-contact__areas li,
.jts-band--dark .jts-contact__areas li { color: rgba(255,255,255,.9); }
.jts-contact .jts-areas-label,
.jts-band--dark .jts-areas-label { color: #fff; }
.jts-contact__areas li::before {
  content: "";
  position: absolute;
  left: 0;
  top: .55em;
  width: 9px;
  height: 9px;
  background: var(--c-brand-bright);
  border-radius: 2px;
}

/* ---- non-button links on dark bands go white, out-specifying the global
        link colour, which would be #003399 and unreadable there ---- */
.jts-page .jts-contact a:not(.btn),
.jts-page .jts-band--dark a:not(.btn),
.jts-page .jts-stats a:not(.btn) { color: #fff; text-decoration: underline; }
.jts-page .jts-contact a:not(.btn):hover,
.jts-page .jts-band--dark a:not(.btn):hover,
.jts-page .jts-stats a:not(.btn):hover { color: var(--c-brand-on-dark); }

/* ============================================================================
   Audit fixes, 2026-09-18. Two read-only audits (desktop layout, mobile/tablet)
   measured these against the live site; every value below traces to a number in
   those reports.
   ============================================================================ */

/* The page templates nest these "__inner" wrappers inside a .jts-container that
   already owns the max-width and the 20px gutter, so those blocks sat 20px right
   of every other section and 40px narrower - the page's left edge visibly jogged
   in and out while scrolling. /about does not nest them, so the same dark band
   sat at two different left edges on different pages. At 320px the doubled
   gutter left only 240px of content. */
.jts-container .jts-band__inner,
.jts-container .jts-split__inner,
.jts-container .jts-contact__inner {
  max-width: none;
  padding-inline: 0;
}

/* class="jts-section jts-band" resolved to the band's 64px because .jts-band is
   later in the file at equal specificity, so those sections sat 16px tighter
   than their neighbours. Standalone .jts-band keeps its 64px. */
.jts-section.jts-band { padding-block: var(--sp-20); }

/* The offset accent block is fixed down-and-right, so on a reversed split it
   points out at the page margin instead of into the column gap - and lands on
   the viewport edge at 1024 now the doubled gutter above is gone. */
@media (min-width: 900px) {
  .jts-split--reverse .jts-split__media::before {
    inset: var(--sp-6) var(--sp-6) calc(-1 * var(--sp-5)) calc(-1 * var(--sp-5));
  }
}

/* 1024-1139 gives 4 cards of 224px and only a 174px text measure. Buy measure
   back from the padding rather than dropping to 3 columns, which would orphan
   a card out of 8. */
@media (min-width: 1024px) and (max-width: 1139px) {
  .jts-frost__panel { padding: var(--sp-8) var(--sp-4) var(--sp-5); }
  .jts-frost__num { left: var(--sp-4); }
}

/* Process steps were single-column all the way to 900, while the services grid
   and article cards go 2-up at 640 - so 640-899 was half one-column, half two. */
/* 768 gave 221px columns and a 173px measure - the headings filled 99% of it and
   one wrapped, leaving the three cards out of rhythm. 860 gives them room. */
@media (min-width: 860px) { .jts-process__grid { grid-template-columns: repeat(3, 1fr); } }

/* Skip-link and any in-page anchor must clear the sticky header. */
html { scroll-padding-top: 7.75rem; }
@media (max-width: 900px) { html { scroll-padding-top: 6.5rem; } }
@media (max-width: 480px) { html { scroll-padding-top: 5.75rem; } }

/* ---- phones ---- */
@media (max-width: 900px) {
  /* Footer and contact links were 22px tall on a 34px pitch. */
  .site-footer ul { gap: 0; }
  .site-footer ul a,
  .site-footer ul li > span { display: block; padding-block: var(--sp-3); }
  .jts-contact__list a { display: inline-flex; align-items: center; min-height: 44px; }
  .jts-bbb-seal { display: inline-flex; align-items: center; min-height: 44px; }
}

@media (max-width: 640px) {
  /* The home page ran to 15,949px at 320 - 28 screenfuls, over 1,100px of it
     pure section padding. */
  .jts-section        { padding-block: var(--sp-12); }
  .jts-section--tight { padding-block: var(--sp-8); }
  .jts-band,
  .jts-contact        { padding-block: var(--sp-10); }
  /* .jts-section.jts-band is (0,2,0) and unscoped, so without this it keeps its
     80px here and the two band sections breathe wider than every neighbour. */
  .jts-section.jts-band { padding-block: var(--sp-10); }
  .jts-section__head  { margin-bottom: var(--sp-6); }
  .jts-stats          { padding-block: var(--sp-8); }

  /* The hero carried 144px of vertical padding at every width; at 320 it was
     787px tall against a 568px screen. */
  .jts-hero__copy { padding-block: var(--sp-10) var(--sp-8); }

  .jts-stat__lbl { font-size: .75rem; letter-spacing: .1em; }
  .jts-accolades__inner { gap: var(--sp-3); padding: var(--sp-4) var(--sp-5); }
  .jts-accolades__label { font-size: .9375rem; }
  .jts-frost__desc,
  .jts-article__excerpt { font-size: 1rem; }
}

@media (max-width: 480px) {
  .jts-contact__areas { grid-template-columns: 1fr; }
  .jts-form-slot { padding: var(--sp-5); }
  .form button[type="submit"],
  .jts-form-slot .btn { width: 100%; }
  /* Ragged CTA pairs (209px next to 110px) read as a mistake at phone width. */
  .jts-hero__ctas,
  .jts-btn-row,
  .jts-services__cta { flex-direction: column; align-items: stretch; }
  .jts-hero__ctas .btn,
  .jts-btn-row .btn,
  .jts-services__cta .btn { width: 100%; }
}

/* The scrim is built for a wide hero; on a phone the copy is full width, so a
   flat vertical veil is the only way the right-hand end of each line clears AA. */
@media (max-width: 900px) {
  .jts-hero__veil {
    background: linear-gradient(180deg,
      rgba(20,34,46,.55) 0%,
      rgba(20,34,46,.82) 28%,
      rgba(20,34,46,.88) 100%);
  }
}

/* Landscape phone: the header was 31% of a 360px-tall viewport and the hero
   151% of it. */
@media (max-height: 480px) and (orientation: landscape) {
  .jts-hero, .jts-hero--inner { min-height: 0; }
  .jts-hero__copy { padding-block: var(--sp-8) var(--sp-6); }
}

/* 900-1100: the viewport says "wide" but .jts-contact__inner has halved the form
   slot, leaving 196px fields in a 2-column grid. */
@media (min-width: 900px) and (max-width: 1100px) {
  .jts-form-slot .form-grid { grid-template-columns: 1fr; }
}

.consent-banner button { min-height: 44px; }

/* The reveal uses a SCROLL-DRIVEN timeline, so base.css's reduced-motion guard
   (animation-duration: .01ms) does not disable it - duration is ignored on a
   progress timeline. Without this a reduced-motion visitor still gets the full
   opacity-0 entrance. */
@media (prefers-reduced-motion: reduce) {
  .jts-reveal { animation: none !important; opacity: 1 !important; transform: none !important; }
}

/* Print has no scroll timeline either, so every revealed section would print
   blank between the header and the footer. */
@media print {
  .jts-reveal { animation: none !important; opacity: 1 !important; transform: none !important; }
  .site-header { position: static; }
  .consent-banner { display: none !important; }
}

/* A block whose eyebrow is centred centres its heading too. The source
   fragments centred the eyebrow, the body copy and the button row but left the
   heading without a modifier, so the heading was the only thing in the block
   hanging off the left edge (the dark "Protect Your Investment" and "You've
   Been Burned Before" bands were the visible cases). */
:is(.jts-band__inner, .jts-contact__inner, .jts-container, .jts-split__copy)
  > .jts-eyebrow--center ~ :is(.jts-h2, .jts-h3, .jts-display) {
  text-align: center;
}

.jts-mobilebar { display: none; }
@media (max-width: 767px) {
  .jts-mobilebar {
    position: fixed;
    inset: auto 0 0 0;
    z-index: 50;
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: var(--sp-2);
    padding: var(--sp-2) var(--sp-3) calc(var(--sp-2) + env(safe-area-inset-bottom, 0px));
    background: var(--brand-neutral);
    box-shadow: 0 -6px 20px rgba(0, 0, 0, .2);
  }
  .jts-mobilebar a {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: var(--sp-2);
    min-height: 48px;
    border-radius: var(--radius-sm);
    font-family: var(--font-display);
    font-size: 1rem;
    letter-spacing: .03em;
    text-transform: uppercase;
    text-decoration: none;
  }
  .jts-mobilebar svg { width: 20px; height: 20px; flex: none; }
  .jts-mobilebar__call { background: var(--color-primary); color: #fff; }
  .jts-mobilebar__contact { background: #fff; color: var(--color-accent-text); }
  .site-footer { padding-bottom: calc(64px + env(safe-area-inset-bottom, 0px)); }
}

@media (max-width: 559px) {
  .site-footer { padding-top: var(--sp-10); }
  .site-footer__top {
    display: flex;
    align-items: center;
    gap: var(--sp-4);
    text-align: left;
    padding-bottom: var(--sp-8);
  }
  .site-footer__top .brand { flex: none; }
  .site-footer__top .brand__logo { height: 88px; }
  .site-footer__tagline { margin: 0; font-size: 1rem; }
  .site-footer__grid {
    grid-template-columns: 1fr 1fr;
    gap: var(--sp-8) var(--sp-5);
    padding-bottom: var(--sp-8);
  }
  .site-footer__contact,
  .site-footer__grid > div:last-child { grid-column: 1 / -1; }
  .site-footer__grid > div:last-child ul { grid-template-columns: 1fr 1fr; column-gap: var(--sp-5); }
  .site-footer__grid ul li > span { padding-block: var(--sp-1); }
  .site-footer__social { margin-top: var(--sp-3); }
  .site-footer__bottom { flex-direction: column; gap: var(--sp-2); }
  .site-footer__copy a { margin-left: 0; margin-right: var(--sp-4); }
}
