/* Northern Hills Taxi — design system.

   The palette is sampled from the logo (assets/img/logo.png), not chosen
   around it. Three colors do all the work:

     #FBE108  taxi yellow  — the "TAXI" wordmark and the cab outline
     #4CC8EE  sky blue     — the halo around the script
     #040606  black        — the script itself

   Two rules keep them honest:

   1. The logo is a DARK-ground mark. Its yellow has no keyline — a pixel scan
      through "TAXI" finds yellow sitting straight on transparency — so on white
      it washes out at 1.32:1, and the cyan halo that separates the script from
      its background drops to 1.94:1 with it. On near-black the yellow is 14:1
      and the halo 9.5:1. The black script never touches the ground at all: it
      reads against its own halo, at 10.5:1. So the header is --night.
      (The old pine header's problem was never that it was dark. It was a muddy
      green ground plus an antique gold that clashed with the logo's own yellow.)
   2. Yellow is never text on a light ground (1.3:1 on white). On light it is
      only ever a FILL — buttons, the sticky call bar, the callout rule. On the
      dark grounds it is 14:1 and can be type. The one exception is --cab-ink,
      the same hue pulled dark enough to read, used for the rating stars.

   Blue carries what yellow can't: kickers, links and labels on light grounds.
   Everything else is a cool neutral, because warm cream fights the logo's cyan.
*/
:root{
  /* brand, sampled from the logo */
  --cab:#FBE108;
  --cab-lift:#FFEB4F;      /* hover */
  --cab-ink:#8A7300;       /* same hue, darkened for the stars (4.6:1 on white) */
  --sky:#4CC8EE;
  --sky-lift:#8ADEF7;
  --sky-ink:#0A6E92;       /* text-safe blue on light (5.7:1 on white) */

  /* grounds */
  --night:#0E1418;         /* hero, routes, footer */
  --night-2:#151E24;       /* raised dark surface / hover */
  --night-3:#1D272E;       /* ridgeline, dark hairlines */
  --paper:#FFFFFF;
  --haze:#F1F4F6;          /* alternating light band */

  /* type */
  --ink:#0C1013;
  --slate:#57636D;         /* muted on light (6.2:1) */
  --mist:#C6D0D8;          /* body on dark (11.9:1) */
  --mist-2:#9FAAB4;        /* muted on dark (7.9:1) */
  --line:#DBE2E7;

  --maxw:1080px;
  --space:clamp(3.5rem,7vw,6rem);
}
*{box-sizing:border-box}
html{scroll-behavior:smooth}
@media (prefers-reduced-motion:reduce){html{scroll-behavior:auto}}
body{
  margin:0;
  background:var(--paper);
  color:var(--ink);
  font-family:"Public Sans",system-ui,sans-serif;
  font-size:1.05rem;
  line-height:1.6;
  -webkit-font-smoothing:antialiased;
}
h1,h2,h3{font-family:"Archivo",system-ui,sans-serif;line-height:1.04;margin:0;letter-spacing:-0.01em}
a{color:inherit}
img{max-width:100%;display:block}
.wrap{max-width:var(--maxw);margin:0 auto;padding:0 1.5rem}

/* skip link */
.skip{position:absolute;left:-9999px;top:0;background:var(--cab);color:var(--ink);padding:.6rem 1rem;font-weight:700;z-index:200}
.skip:focus{left:1rem;top:1rem}

/* Focus ring: blue on light grounds, yellow on the dark ones. A single color
   can't do both — yellow vanishes on white, blue vanishes on near-black. */
a:focus-visible,button:focus-visible{outline:3px solid var(--sky-ink);outline-offset:2px}
header a:focus-visible,.hero a:focus-visible,.routes a:focus-visible,
footer a:focus-visible,.sticky-call a:focus-visible,
.btn-primary:focus-visible{outline-color:var(--cab)}

/* eyebrow / mono dispatch readout */
.eyebrow{font-family:"IBM Plex Mono",monospace;font-size:.78rem;letter-spacing:.12em;text-transform:uppercase;color:var(--sky-ink)}
.meta{font-family:"IBM Plex Mono",monospace;font-size:.82rem;letter-spacing:.04em;color:var(--slate)}
/* on the dark grounds the kicker takes the logo's own blue */
.hero .eyebrow,.routes .eyebrow{color:var(--sky)}

/* buttons */
.btn{display:inline-flex;align-items:center;gap:.5rem;font-family:"Archivo",sans-serif;font-weight:700;
  font-size:1.05rem;padding:.95rem 1.5rem;border-radius:2px;text-decoration:none;border:2px solid transparent;
  transition:transform .12s ease,background .15s ease,color .15s ease;white-space:nowrap}
.btn:active{transform:translateY(1px)}
/* yellow body, black lettering — the cab's own color pairing, and the highest
   contrast this palette can make (14.4:1) on the button that matters most */
.btn-primary{background:var(--cab);color:var(--ink);border-color:var(--cab)}
.btn-primary:hover{background:var(--cab-lift);border-color:var(--cab-lift)}
.btn-ghost{background:transparent;color:var(--paper);border-color:rgba(255,255,255,.45)}
.btn-ghost:hover{border-color:var(--paper);background:rgba(255,255,255,.08)}
.btn-dark{background:var(--night);color:var(--paper);border-color:var(--night)}
.btn-dark:hover{background:var(--night-2);border-color:var(--night-2)}

/* header — near-black, the ground this logo was drawn for (see the note up top).
   Starts tall, shrinks on scroll via .scrolled (set by site.js). The yellow rule
   is the cab stripe: it holds the edge against the dark hero below, and gives the
   sticky bar a hard boundary once it is floating over the light sections. */
header{background:var(--night);color:var(--paper);position:sticky;top:0;z-index:100;
  border-bottom:3px solid var(--cab)}
.bar{display:flex;align-items:center;justify-content:space-between;gap:1rem;
  padding:1.1rem 1.5rem;max-width:var(--maxw);margin:0 auto;
  transition:padding .3s ease}
.brand{display:inline-flex;align-items:center;text-decoration:none;color:var(--paper);
  font-family:"Archivo",sans-serif;font-weight:800;letter-spacing:.02em}
.brand .logo{height:72px;width:auto;display:block;transition:height .3s ease}
header.scrolled .bar{padding:.55rem 1.5rem}
header.scrolled .logo{height:38px}
/* the phone number is the primary conversion, so on desktop it is a button,
   not a text link. On mobile the sticky bar already carries it in yellow. */
.head-call{font-family:"Archivo",sans-serif;font-weight:800;font-size:1.05rem;letter-spacing:.01em;
  text-decoration:none;background:var(--cab);color:var(--ink);
  padding:.6rem 1.1rem;border-radius:2px;transition:background .15s ease}
.head-call:hover{background:var(--cab-lift)}

/* hero */
.hero{position:relative;background:var(--night);color:var(--paper);overflow:hidden;padding:0}
.hero .ridges{position:absolute;left:0;right:0;bottom:0;height:65%;width:100%;pointer-events:none}
.hero .wrap{position:relative;padding:var(--space) 1.5rem calc(var(--space) - 1rem)}
.hero h1{font-size:clamp(2.4rem,6.5vw,4.4rem);font-weight:800;max-width:14ch;margin:.9rem 0}
.hero p.sub{font-size:clamp(1.05rem,2.4vw,1.3rem);color:var(--mist);max-width:42ch;margin:0 0 2rem}
.hero-cta{display:flex;flex-wrap:wrap;gap:.8rem;margin-bottom:1.6rem}
.trust{font-family:"IBM Plex Mono",monospace;font-size:.8rem;letter-spacing:.06em;color:var(--mist-2)}
.trust span{color:var(--cab)}

/* Print-ad message match (.hero-ad — Black Hills I Do, Oct 2026).
   The ad headline is what a QR scanner must see first, so it gets the display
   size and the <h1> is demoted to a deck. Structure is unchanged: the <h1> is
   still the keyword phrase, it just stops being the biggest thing on screen.
   Scoped to .hero-ad so no other page's h1 moves. */
.hero .promise{font-family:"Archivo",sans-serif;font-weight:800;color:var(--paper);
  font-size:clamp(2.7rem,7.4vw,5rem);line-height:1.02;letter-spacing:-0.02em;
  margin:.7rem 0 .55rem;max-width:16ch}
.hero-ad h1{font-size:clamp(1.2rem,2.5vw,1.55rem);font-weight:600;color:var(--mist);
  letter-spacing:.01em;max-width:none;margin:0 0 1.1rem}

/* generic section */
section{padding:var(--space) 0}

/* article prose (route, landing, and legal pages) */
.wrap.prose{max-width:760px}
.prose h1{font-size:clamp(2rem,5vw,3rem);margin:.5rem 0 1rem}
.prose h2{font-size:clamp(1.5rem,3vw,2rem);margin:2.2rem 0 .6rem}
.prose > h2:first-child{margin-top:0}
.prose ul{line-height:1.8}
/* :not(.btn) matters — .prose a is (0,1,1) and out-specifies .btn-primary
   (0,1,0), so without it every in-prose CTA renders blue-on-yellow at
   3.2:1 instead of black-on-yellow at 14.4:1. */
.prose a:not(.btn){color:var(--sky-ink);font-weight:600}
.cta-row{margin-top:1.5rem}
/* yellow as a fill, never as type on light */
.callout{margin-top:2rem;background:var(--haze);border:1px solid var(--line);border-left:4px solid var(--cab);
  border-radius:2px;padding:1rem 1.25rem;font-weight:600;color:var(--ink)}

.lead-in{max-width:46ch}
.lead-in h2{font-size:clamp(1.9rem,4vw,2.7rem);font-weight:700;margin:.6rem 0 1rem}
.lead-in p{color:var(--slate);font-size:1.1rem}

/* service strip */
.svc{display:grid;grid-template-columns:repeat(3,1fr);gap:1.2rem;margin-top:2.5rem}
.svc a{background:var(--paper);border:1px solid var(--line);border-radius:3px;padding:1.5rem;text-decoration:none;
  display:block;transition:border-color .15s ease,box-shadow .15s ease,transform .15s ease}
.svc a:hover{border-color:var(--sky-ink);box-shadow:0 6px 20px rgba(12,16,19,.07);transform:translateY(-2px)}
.svc h3{font-size:1.2rem;font-weight:700;margin:.4rem 0 .4rem}
.svc p{margin:0;color:var(--slate);font-size:.98rem}

/* routes — dark band. Blue labels the detail, yellow marks the action. */
.routes{background:var(--night);color:var(--paper)}
.routes .lead-in p{color:var(--mist)}
/* Hairlines come from each cell's own ring, not from a lighter container
   showing through the gaps — an odd number of routes would otherwise leave a
   lit phantom cell in the last slot. box-shadow, not outline, so the focus
   ring still has somewhere to go. */
.route-grid{display:grid;grid-template-columns:repeat(2,1fr);gap:1px;background:var(--night);
  border:1px solid var(--night-3);margin-top:2.5rem;border-radius:3px;overflow:hidden}
.route-grid a{background:var(--night);box-shadow:0 0 0 1px var(--night-3);padding:1.4rem 1.5rem;text-decoration:none;display:flex;
  align-items:baseline;justify-content:space-between;gap:1rem;transition:background .15s ease}
.route-grid a:hover{background:var(--night-2)}
.route-grid .name{font-family:"Archivo",sans-serif;font-weight:600;font-size:1.12rem;color:var(--paper)}
.route-grid .name span{display:block;color:var(--sky);font-size:.78rem;font-family:"IBM Plex Mono",monospace;
  letter-spacing:.04em;font-weight:400;margin-top:.3rem}
.route-grid .go{color:var(--cab);font-size:1.3rem;line-height:1;transition:transform .15s ease}
.route-grid a:hover .go{transform:translateX(3px)}

/* booking form */
.book{background:var(--haze);border-top:1px solid var(--line)}
/* Booking: single centered column so the Jotform gets a proper desktop width
   (a 2-column split squeezed it into its narrow mobile layout). */
.book-inner{display:grid;gap:1.75rem;max-width:760px;margin-inline:auto}
.book-copy h2{font-size:clamp(1.9rem,4vw,2.7rem);font-weight:700;margin-bottom:1rem}
.book-copy p{color:var(--slate)}
.book-copy .or-call{margin-top:1.5rem;font-family:"IBM Plex Mono",monospace;font-size:.9rem;color:var(--slate)}
.book-copy .or-call a{color:var(--sky-ink);font-weight:700}

/* jotform embed wrapper */
.jf-embed{background:var(--paper);border:1px solid var(--line);border-radius:4px;padding:.4rem}
.jf-embed iframe{width:1px;min-width:100%;border:none;display:block}

/* social proof (Google rating + testimonials) */
.proof{background:var(--paper);border-top:1px solid var(--line);border-bottom:1px solid var(--line)}
.proof .wrap{display:grid;grid-template-columns:auto 1fr;gap:clamp(1.5rem,4vw,3rem);align-items:center;
  padding-top:2.5rem;padding-bottom:2.5rem}
.proof-rating{text-align:center;border-right:1px solid var(--line);padding-right:clamp(1.5rem,4vw,3rem)}
/* the one place yellow appears as a glyph on white: the brand hue, darkened
   until it reads (4.6:1). Stars have to look like stars. */
.proof .stars{color:var(--cab-ink);font-size:1.25rem;letter-spacing:.1em;margin:0}
.proof .star-dim{color:var(--line)}
.proof .score{font-family:"Archivo",sans-serif;font-weight:800;font-size:2.4rem;color:var(--ink);margin:.2rem 0 0;line-height:1}
.proof .count{font-family:"IBM Plex Mono",monospace;font-size:.78rem;color:var(--slate);margin:.35rem 0 0}
.proof .count a{color:var(--sky-ink);font-weight:700}
.proof-quotes{display:grid;gap:1.1rem}
.proof blockquote{margin:0;color:var(--ink);font-size:1.02rem;line-height:1.55}
.proof blockquote cite{display:block;font-family:"IBM Plex Mono",monospace;font-size:.76rem;
  letter-spacing:.04em;color:var(--slate);font-style:normal;margin-top:.35rem}
@media (max-width:760px){
  .proof .wrap{grid-template-columns:1fr;gap:1.5rem}
  .proof-rating{border-right:none;border-bottom:1px solid var(--line);padding-right:0;padding-bottom:1.5rem}
}

/* charge / trust */
.how{background:var(--haze);border-top:1px solid var(--line)}
.how-grid{display:grid;grid-template-columns:repeat(3,1fr);gap:2rem;margin-top:2rem}
.how-grid h3{font-size:1.1rem;font-weight:700;margin-bottom:.5rem}
.how-grid .num{font-family:"IBM Plex Mono",monospace;color:var(--sky-ink);font-size:.8rem;letter-spacing:.1em}
.how-grid p{margin:.3rem 0 0;color:var(--slate);font-size:.98rem}

/* footer */
footer{background:var(--night);color:var(--mist);padding:var(--space) 0 6rem;border-top:3px solid var(--cab)}
/* four columns since the vacation-rental communities got their own group;
   drops to two before the route names start breaking mid-word */
footer .cols{display:grid;grid-template-columns:1.3fr 1.1fr 1fr 1.1fr;gap:2rem}
@media (max-width:980px){footer .cols{grid-template-columns:1fr 1fr}}
footer h4{font-family:"Archivo",sans-serif;color:var(--paper);font-size:1rem;margin:0 0 .8rem;letter-spacing:.02em}
footer .meta{color:var(--mist-2);line-height:1.9}
footer a{color:var(--mist);text-decoration:none}
footer a:hover{color:var(--sky)}
footer .big-call{font-family:"Archivo",sans-serif;font-weight:800;font-size:1.6rem}
footer .big-call a{color:var(--cab)}
footer .big-call a:hover{color:var(--cab-lift)}
footer .fine{margin-top:2.5rem;padding-top:1.5rem;border-top:1px solid var(--night-3);font-size:.82rem;color:var(--mist-2)}
footer .chambers{display:flex;gap:1rem;align-items:center;margin-top:.5rem}
footer .chambers img{height:34px;opacity:.85}

/* sticky mobile contact bar — the cab's exact yellow, so it reads as the same
   object as the "TAXI" in the logo eight inches up the screen.
   Split two ways since texting became the lead channel (master plan §7): text
   takes the width and the number, call keeps a full-height segment of its own so
   it is still one tap. Both stay ≥48px tall for the thumb. */
.sticky-call{position:fixed;left:0;right:0;bottom:0;z-index:150;background:var(--cab);
  display:none;box-shadow:0 -4px 14px rgba(12,16,19,.28)}
.sticky-call a{display:flex;align-items:center;justify-content:center;gap:.5rem;color:var(--ink);
  font-family:"Archivo",sans-serif;font-weight:800;text-decoration:none;letter-spacing:.01em;
  padding:.85rem .75rem;min-height:48px}
.sticky-call .sc-text{flex:1 1 auto;font-size:1.15rem}
.sticky-call .sc-call{flex:0 0 30%;font-size:1.05rem;border-left:2px solid rgba(12,16,19,.30)}

@media (max-width:760px){
  .svc{grid-template-columns:1fr}
  .route-grid{grid-template-columns:1fr}
  .how-grid{grid-template-columns:1fr;gap:1.5rem}
  footer .cols{grid-template-columns:1fr;gap:2rem}
  /* no yellow pill in the header on mobile — the sticky bar owns that role */
  .head-call{background:none;color:var(--paper);padding:0;font-size:1rem}
  .head-call:hover{background:none;color:var(--sky)}
  .brand .logo{height:52px}
  header.scrolled .logo{height:34px}
  .sticky-call{display:flex}
  footer{padding-bottom:5.5rem}
}
