/* =============================================================================
   /locations content-area styles.
   =============================================================================

   WHY THIS FILE EXISTS
     Header and Footer now come from the shared semantic Site Chrome. The
     content between them previously used a palette and fonts that existed
     nowhere else in the product — a made-up navy (#141a42) and blue (#005ee9)
     next to the brand's #011932 / #1688CA, and system fonts against Poppins.
     Shared chrome around a differently-styled body reads as two sites stitched
     together.

     The CSS was also duplicated inline in both page templates, so any fix had
     to be made twice.

   TOKENS
     These readable names preserve the audited Trucker Path brand palette used
     by the shared Site Chrome. Keeping the values local to Locations makes a
     future palette mismatch visible and avoids coupling content styles to
     generated selectors.

     If the brand palette changes, update this block only.
   ========================================================================== */

:root {
  /* Brand */
  --tpl-blue: #1688ca;          /* primary brand blue */
  --tpl-blue-strong: #146fa3;   /* hover / pressed */
  --tpl-blue-bright: #18acf6;   /* accents, highlights */
  --tpl-blue-wash: #f0f9ff;     /* tinted surface */

  /* Ink */
  --tpl-ink: #011932;           /* headings, primary text */
  --tpl-ink-deep: #001728;      /* darkest surface */
  --tpl-ink-muted: #5f6980;     /* secondary text */
  --tpl-ink-soft: #868f98;      /* tertiary / captions */
  --tpl-ink-faint: #babfc4;     /* disabled, em-dashes */

  /* Surfaces & lines */
  --tpl-surface: #f2f5f8;
  --tpl-surface-alt: #f9fafb;
  --tpl-line: #e2e6e9;
  --tpl-line-soft: #f0f3f4;
  --tpl-white: #ffffff;

  /* Content and controls placed on dark surfaces */
  --tpl-on-dark-secondary: #ffffffb3;
  --tpl-on-dark-muted: #ffffff8f;
  --tpl-on-dark-subtle: #ffffff80;
  --tpl-on-dark-faint: #ffffff73;
  --tpl-on-dark-disabled: #ffffff40;
  --tpl-on-dark-surface: #ffffff14;
  --tpl-on-dark-surface-hover: #ffffff24;
  --tpl-on-dark-line: #ffffff1f;
  --tpl-on-dark-border: #ffffff33;
  --tpl-on-dark-border-hover: #ffffff59;

  /* Semantic — separate from the accent on purpose */
  --tpl-link: var(--tpl-blue); /* text links use the primary brand blue */
  --tpl-link-transition: 140ms ease; /* matches the shared site chrome */
  --tpl-go: #08b86c;
  --tpl-go-wash: #ecfcf2;
  --tpl-go-text: #056b40;
  --tpl-go-border: #b6ecce;
  --tpl-chip-go-text: #067a48;
  --tpl-chip-go-border: #b7ecd0;
  --tpl-caution-text: #9a4a05;
  --tpl-caution-wash: #fff6ec;
  --tpl-caution-border: #ffd9b0;
  --tpl-danger-text: #a3231b;
  --tpl-danger-wash: #fdeceb;
  --tpl-danger-border: #f6c9c5;
  --tpl-warn: #eb5200;
  --tpl-clearance-warn: #8a4b00;
  --tpl-rating: #ffc043;
  --tpl-placeholder: #dfe5ea;

  /* Type */
  --tpl-font-head: "Poppins", "Poppins Placeholder", sans-serif;
  --tpl-font-body: "Poppins", "Poppins Placeholder", sans-serif;

  /* Shape — matches the homepage's cards and dropdown panels */
  --tpl-radius: 8px;
  --tpl-radius-sm: 4px;
  --tpl-shadow:
    rgba(92, 92, 94, 0.02) 0 0.68px 2.57px -0.125px,
    rgba(92, 92, 94, 0.03) 0 2.05px 7.8px -0.25px,
    rgba(92, 92, 94, 0.05) 0 5.43px 20.6px -0.375px,
    rgba(92, 92, 94, 0.08) 0 17px 64.6px -0.5px;

  --tpl-maxw: 1200px;           /* same content width as the homepage sections */
  --tpl-content-gap: 48px;      /* vertical rhythm between primary content blocks */
}

/* --- layout ---------------------------------------------------------------- */

.tpl-wrap {
  max-width: var(--tpl-maxw);
  margin: 0 auto;
  padding: 0 24px;
}

/* The semantic shared chrome has no generated Framer flex root. Keep the page
   boundary explicit so full-bleed bands span the viewport and wide POI tables
   scroll inside their own wrapper instead of widening the document. */
#tp-main,
#tp-locations-main {
  width: 100%;
  min-width: 0;
  max-width: 100%;
  font-family: var(--tpl-font-body);
  color: var(--tpl-ink);
  background: var(--tpl-white);
}

/* Locations keeps its first dark section behind the fixed announcement/header.
   The extra top padding protects the breadcrumb while preserving one continuous
   dark surface instead of introducing a spacer band. */
.tp-site-chrome--dark-hero #tp-main > .tpl-hero:first-child {
  padding-top: calc(28px + var(--tp-site-announcement-height) + var(--tp-site-header-height));
}

.tpl-main { padding: 40px 0 16px; }

.tpl-main h2 {
  font-family: var(--tpl-font-head);
  font-size: 26px;
  font-weight: 600;
  line-height: 1.3;
  letter-spacing: -0.01em;
  margin: 48px 0 16px;
  color: var(--tpl-ink);
  text-wrap: balance;
}

/* BODY COPY ONLY — :not([class]) IS LOAD-BEARING.
   As `.tpl-main p` this rule is (0,0,1,1), which beats every single-class rule on a
   paragraph inside it. It was silently overriding four deliberate styles:

     .tpl-answer       wanted 17px / ink        got 16px / muted
     .tpl-empty-title  wanted 17px / ink        got 16px / muted
     .tpl-claim        wanted 13.5px / ink-soft got 16px / muted
     .tpl-inapp-title  wanted 24px / ink        got 16px / muted
     .tpl-inapp-eyebrow wanted 11px / blue      got 16px / muted

   So the topical answer block — the paragraph most likely to be quoted by an AI
   answer, sitting in its own tinted callout — was rendering in body grey at body
   size, and the "in the app" module had no heading hierarchy at all. Three
   redesigns of that module chased a problem that was this one line.

   A paragraph with a class has opted into its own styling by definition, so
   excluding classed paragraphs is both the fix and the rule. Verified: every
   classed <p> under .tpl-main (tpl-answer, tpl-empty-title, tpl-claim, tpl-cta-*,
   tpl-inapp-*) sets its own size and colour, so none of them lose anything. */
.tpl-main p:not([class]) { font-size: 16px; line-height: 1.65; color: var(--tpl-ink-muted); }

/* --- hero ----------------------------------------------------------------- */

.tpl-hero {
  background: linear-gradient(125deg, #0d2340 0%, #000000 100%);
  color: var(--tpl-white);
  padding: 28px 0 48px;
}

/* The Locations landing page carries one geographic cue, not a second hero.
   Keeping the state map as a background-only pseudo-element preserves the
   search and heading as the only interactive/semantic content. The source stays
   crisp; restraint comes from layout, opacity and a live edge mask so Retina
   screens do not expose a pre-faded raster edge. */
.tpl-root-hero,
.tpl-hub-hero,
.tpl-state-hero,
.tpl-detail-hero {
  position: relative;
}

.tpl-root-hero::after,
.tpl-hub-hero::after,
.tpl-state-hero::after,
.tpl-detail-hero::after {
  content: "";
  position: absolute;
  z-index: 0;
  top: 150px;
  /* Keep the artwork inside the viewport without clipping interactive layers
     such as the city/state autocomplete that intentionally leaves the hero. */
  right: max(0px, calc((100vw - var(--tpl-maxw)) / 2 - 60px));
  width: min(48vw, 660px);
  aspect-ratio: 1611 / 976;
  background: url("/assets/locations/us-map-states.png") center / contain no-repeat;
  opacity: 0.28;
  -webkit-mask-image: linear-gradient(
    to bottom,
    #000 0%,
    #000 52%,
    rgba(0, 0, 0, 0.78) 66%,
    rgba(0, 0, 0, 0.22) 86%,
    transparent 100%
  );
  mask-image: linear-gradient(
    to bottom,
    #000 0%,
    #000 52%,
    rgba(0, 0, 0, 0.78) 66%,
    rgba(0, 0, 0, 0.22) 86%,
    transparent 100%
  );
  pointer-events: none;
}

.tpl-state-hero::after,
.tpl-detail-hero::after {
  top: 118px;
  width: min(42vw, 580px);
  opacity: 0.2;
}

.tpl-hub-hero::after {
  top: 128px;
  width: min(45vw, 620px);
  opacity: 0.24;
}

.tpl-root-hero > .tpl-wrap,
.tpl-hub-hero > .tpl-wrap,
.tpl-state-hero > .tpl-wrap,
.tpl-detail-hero > .tpl-wrap {
  position: relative;
  z-index: 1;
}

.tpl-crumb {
  display: flex;
  align-items: center;
  gap: 6px;
  font-size: 13px;
  color: var(--tpl-on-dark-secondary);
  padding: 14px 0 24px;
}
.tpl-crumb a { color: var(--tpl-on-dark-secondary); text-decoration: none; }
.tpl-crumb a:hover { color: var(--tpl-white); text-decoration: underline; }
.tpl-crumb-parent { color: var(--tpl-on-dark-secondary); }
.tpl-crumb-separator { color: var(--tpl-on-dark-faint); }
.tpl-crumb-current { color: var(--tpl-white); }

.tpl-hero h1 {
  font-family: var(--tpl-font-head);
  font-size: 44px;
  font-weight: 600;
  line-height: 1.12;
  letter-spacing: -0.02em;
  margin: 0 0 14px;
  max-width: 24ch;
  text-wrap: balance;
  color: var(--tpl-white);
}

@supports ((-webkit-background-clip: text) or (background-clip: text)) {
  .tpl-hero h1 {
    background: linear-gradient(96deg, #ffffff 0%, rgba(255, 255, 255, 0.7) 100%);
    -webkit-background-clip: text;
    background-clip: text;
    -webkit-text-fill-color: transparent;
  }
}

@media (forced-colors: active) {
  .tpl-hero h1 {
    background: none;
    color: CanvasText;
    -webkit-text-fill-color: currentColor;
  }
}

.tpl-hero .sub {
  font-size: 18px;
  line-height: 1.55;
  color: var(--tpl-on-dark-secondary);
  max-width: 60ch;
  margin: 0;
}

.tpl-hero-meta {
  margin: 18px 0 0;
  color: var(--tpl-on-dark-secondary);
  font-size: 14px;
  line-height: 1.5;
}

/* Route shield in the corridor hero */
.tpl-shield {
  display: inline-block;
  background: var(--tpl-blue);
  color: var(--tpl-white);
  font-family: var(--tpl-font-head);
  font-weight: 600;
  font-size: 13px;
  letter-spacing: 0.04em;
  padding: 5px 13px;
  border-radius: var(--tpl-radius-sm);
  margin-bottom: 14px;
}

.tpl-stats { display: flex; gap: 16px; margin-top: 30px; flex-wrap: wrap; min-width: 0; }
.tpl-stat {
  background: var(--tpl-on-dark-surface);
  border: 0;
  border-radius: var(--tpl-radius);
  padding: 16px 22px;
  min-width: 150px;
}
.tpl-stat .n {
  font-family: var(--tpl-font-head);
  font-size: 28px;
  font-weight: 600;
  line-height: 1;
  color: var(--tpl-white);
  font-variant-numeric: tabular-nums;
}
.tpl-stat .l { font-size: 12.5px; color: var(--tpl-on-dark-secondary); margin-top: 8px; }

/* --- answer block (the topical summary above the list) -------------------- */

.tpl-main .tpl-answer {
  font-size: 14px;
  line-height: 1.7;
  text-wrap: pretty;
  background: var(--tpl-blue-wash);
  border-left: 4px solid var(--tpl-blue);
  padding: 18px 22px;
  border-radius: var(--tpl-radius);
  color: var(--tpl-ink);
  margin: 0;
}
.tpl-answer strong { font-weight: 600; }
.tpl-answer a { white-space: nowrap; }

/* TEXT LINK CONTRACT.
   Light-surface text links share one color, underline and motion treatment.
   Navigation, cards, buttons and dark-surface links keep their own interaction
   patterns because their containers already provide the affordance. */
.tpl-answer a,
.tpl-answer a:visited,
.tpl-claim a,
.tpl-claim a:visited,
.tpl-appswitch a,
.tpl-appswitch a:visited,
.tpl-facts dd a,
.tpl-facts dd a:visited,
a.tpl-phone,
a.tpl-phone:visited,
a.tpl-poiname,
a.tpl-poiname:visited {
  color: var(--tpl-link);
  text-decoration-line: underline;
  text-decoration-color: transparent;
  text-decoration-thickness: 1px;
  text-underline-offset: 3px;
  transition:
    color var(--tpl-link-transition),
    text-decoration-color var(--tpl-link-transition);
}
.tpl-answer a:hover,
.tpl-claim a:hover,
.tpl-appswitch a:hover,
.tpl-facts dd a:hover,
a.tpl-phone:hover,
a.tpl-poiname:hover {
  color: var(--tpl-blue-strong);
  text-decoration-color: currentColor;
}
.tpl-answer a:focus-visible,
.tpl-claim a:focus-visible,
.tpl-appswitch a:focus-visible,
.tpl-facts dd a:focus-visible,
a.tpl-phone:focus-visible,
a.tpl-poiname:focus-visible {
  color: var(--tpl-blue-strong);
  text-decoration-color: currentColor;
  outline: 2px solid var(--tpl-blue);
  outline-offset: 2px;
}

/* --- POI table ------------------------------------------------------------ */

/* overflow-x:auto alone does NOT stop the table's min-content width from
   propagating to the page — it only makes the overflow scrollable. Without
   min-width:0 the widest row (~550px) became a floor the whole page couldn't
   shrink below, so every phone width scrolled sideways. Measured: main was
   stuck at 599px from 320px through 414px viewports. */
.tpl-tablewrap { overflow-x: auto; min-width: 0; max-width: 100%; }


.tpl-table {
  width: 100%;
  border-collapse: collapse;
  background: var(--tpl-white);
  border: 1px solid var(--tpl-line);
  border-radius: var(--tpl-radius);
  overflow: hidden;
  font-size: 14.5px;
}
.tpl-table th,
.tpl-table td {
  text-align: left;
  padding: 13px 16px;
  border-bottom: 1px solid var(--tpl-line-soft);
  vertical-align: middle;
}
.tpl-table th {
  background: var(--tpl-surface);
  font-family: var(--tpl-font-head);
  font-size: 12.5px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--tpl-ink-muted);
  white-space: nowrap;
}
.tpl-table tbody tr:last-child td { border-bottom: none; }
.tpl-table tbody tr:hover { background: var(--tpl-surface-alt); }

.tpl-poiname {
  display: flex;
  min-height: 40px;
  align-items: center;
  color: var(--tpl-ink);
  font-weight: 600;
}
.tpl-phone {
  color: var(--tpl-link);
  font: inherit;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}
/* Route position — the field that decides whether a stop is usable at all */
.tpl-route { white-space: nowrap; }
.tpl-hwy {
  display: inline-block;
  background: var(--tpl-ink);
  color: var(--tpl-white);
  font-family: var(--tpl-font-head);
  font-weight: 600;
  font-size: 11.5px;
  letter-spacing: 0.03em;
  padding: 3px 8px;
  border-radius: var(--tpl-radius-sm);
}
.tpl-exit {
  display: inline-block;
  margin-left: 7px;
  font-variant-numeric: tabular-nums;
  font-weight: 600;
  font-size: 13.5px;
  color: var(--tpl-ink);
}
.tpl-muted { color: var(--tpl-ink-faint); }
.tpl-addr { display: block; color: var(--tpl-ink-soft); font-size: 12.5px; margin-top: 3px; }

.tpl-chip {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  background: var(--tpl-surface);
  border: 1px solid var(--tpl-line);
  border-radius: 6px;
  padding: 3px 9px;
  font-size: 12px;
  color: var(--tpl-ink-muted);
  margin: 2px 4px 0 0;
  white-space: nowrap;
}
.tpl-chip-list {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 4px;
}
.tpl-chip-list .tpl-chip { margin: 0; }
/* Bypass support saves real time, so it reads as a "go" signal, not a neutral
   chip. Semantic colour, deliberately not the brand accent. */
/* Icons are pre-recoloured to the brand token at build time, not masked: several
   are multi-colour (restrooms uses three fills) and masking would flatten them. */
.tpl-chip-ico { width: 16px; height: 16px; flex: 0 0 auto; display: block; }
/* Quantity for the count amenities (showers, parking spots, ATMs, bulk DEF).
   Tinted rather than bolded: the number is the useful part of "Showers 8", but
   a row can carry several chips and bolding them all just makes the cell loud. */
.tpl-chip-n {
  margin-left: 2px;
  padding-left: 0;
  color: var(--tpl-ink);
  font-variant-numeric: tabular-nums;
}
.tpl-chip-go {
  background: var(--tpl-go-wash);
  border-color: var(--tpl-chip-go-border);
  color: var(--tpl-chip-go-text);
  font-weight: 600;
}

/* --- empty state ---------------------------------------------------------- */

.tpl-empty {
  background: var(--tpl-surface);
  border: 1px solid var(--tpl-line);
  border-radius: var(--tpl-radius);
  padding: 40px 24px;
  text-align: center;
  color: var(--tpl-ink-muted);
}
.tpl-empty a { color: var(--tpl-blue); font-weight: 600; }
.tpl-empty-title { font-family: var(--tpl-font-head); font-weight: 600; font-size: 17px;
                   color: var(--tpl-ink); margin: 0 0 6px; }
.tpl-empty-alts { display: flex; flex-wrap: wrap; gap: 8px; justify-content: center;
                  margin: 18px 0 0; padding: 0; list-style: none; }
.tpl-empty-alts a {
  display: inline-block; background: var(--tpl-white); border: 1px solid var(--tpl-line);
  border-radius: 100px; padding: 8px 16px; font-size: 13.5px; color: var(--tpl-ink);
  font-weight: 500;
}
.tpl-empty-alts a:hover { border-color: var(--tpl-blue); color: var(--tpl-blue); }
.tpl-empty-error {
  border: 0;
  margin-top: var(--tpl-content-gap);
}
.tpl-empty-error p { margin: 0 auto 14px; max-width: 62ch; }
.tpl-empty-error .tpl-empty-title { margin-bottom: 6px; }

/* A brand-in-state empty result has two immediately useful alternatives: stay with
   the chain nationwide, or stay in the state and broaden the type. It should read
   as a quiet route choice, not the generic dead-end card used by a whole type with
   no coverage. The approved Figma chain icon anchors that decision without adding
   a second visual panel. */
.tpl-empty-brand {
  display: grid;
  grid-template-columns: 44px minmax(0, 1fr);
  gap: 16px;
  align-items: start;
  padding: 26px;
  text-align: left;
}
.tpl-empty-brand-icon {
  display: block;
  width: 40px;
  height: 40px;
  object-fit: contain;
}
.tpl-empty-brand-copy > p:not(.tpl-empty-title) { margin: 0; }
.tpl-empty-brand .tpl-empty-alts { justify-content: flex-start; }

/* The Figma assets are exported from a square component canvas. Brand touchpoints
   intentionally expose only the circular POI marker, never that rectangular canvas. */
.tpl-empty-brand-icon,
.tpl-brand-directory-entry-icons img,
.tpl-brand-card-icon,
.tpl-brand-links img {
  border-radius: 50%;
  clip-path: circle(50% at 50% 50%);
}

/* The Truck Stops hub has one early, compact decision point for chain browsing.
   It is a single real link to the directory, not a row of decorative logos that
   would compete with search or make the list start below the fold. */
.tpl-brand-directory-entry { margin: 28px 0 38px; }
.tpl-brand-directory-entry > a {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr) auto;
  align-items: center;
  gap: 18px;
  padding: 18px 20px;
  color: var(--tpl-ink);
  text-decoration: none;
  background: var(--tpl-white);
  border: 1px solid var(--tpl-line);
  border-radius: var(--tpl-radius);
  transition:
    color 180ms cubic-bezier(0.2, 0, 0, 1),
    border-color 180ms cubic-bezier(0.2, 0, 0, 1);
}
.tpl-brand-directory-entry > a:hover,
.tpl-brand-directory-entry > a:focus-visible {
  color: var(--tpl-blue);
  border-color: var(--tpl-blue);
}
.tpl-brand-directory-entry-icons {
  display: flex;
  align-items: center;
  min-width: 84px;
}
.tpl-brand-directory-entry-icons img {
  display: block;
  width: 36px;
  height: 36px;
  margin-right: -10px;
  object-fit: contain;
}
.tpl-brand-directory-entry-icons img:last-child { margin-right: 0; }
.tpl-brand-directory-entry-copy { display: block; min-width: 0; }
.tpl-brand-directory-entry-eyebrow,
.tpl-brand-directory-entry-title,
.tpl-brand-directory-entry-description { display: block; }
.tpl-brand-directory-entry-eyebrow {
  margin-bottom: 3px;
  color: var(--tpl-blue);
  font-family: var(--tpl-font-head);
  font-size: 11.5px;
  font-weight: 600;
  letter-spacing: 0.08em;
  line-height: 1.35;
  text-transform: uppercase;
}
.tpl-brand-directory-entry-title {
  font-family: var(--tpl-font-head);
  font-size: 17px;
  font-weight: 600;
  line-height: 1.35;
}
.tpl-brand-directory-entry-description {
  margin-top: 3px;
  color: var(--tpl-ink-muted);
  font-size: 13.5px;
  line-height: 1.5;
}
.tpl-brand-directory-entry-action {
  font-family: var(--tpl-font-head);
  font-size: 13.5px;
  font-weight: 600;
  white-space: nowrap;
}
.tpl-brand-directory-entry-action span { color: var(--tpl-blue); margin-left: 4px; }

/* The directory gives all chains equal visual weight: logo, name, one action.
   Counts remain on each live brand page, where the API can substantiate them. */
.tpl-brand-directory { margin-top: 44px; }
.tpl-brand-grid {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 12px;
}
.tpl-brand-card,
.tpl-brand-links a {
  display: grid;
  grid-template-columns: 40px minmax(0, 1fr) auto;
  align-items: center;
  gap: 14px;
  min-height: 88px;
  box-sizing: border-box;
  padding: 18px;
  color: var(--tpl-ink);
  text-decoration: none;
  background: var(--tpl-white);
  border: 1px solid var(--tpl-line);
  border-radius: var(--tpl-radius);
  transition:
    color 180ms cubic-bezier(0.2, 0, 0, 1),
    border-color 180ms cubic-bezier(0.2, 0, 0, 1);
}
.tpl-brand-card:hover,
.tpl-brand-card:focus-visible,
.tpl-brand-links a:hover,
.tpl-brand-links a:focus-visible {
  color: var(--tpl-blue);
  border-color: var(--tpl-blue);
}
.tpl-brand-card-icon,
.tpl-brand-links img {
  display: block;
  width: 40px;
  height: 40px;
  object-fit: contain;
}
.tpl-brand-card-copy { display: block; min-width: 0; }
.tpl-brand-card-title,
.tpl-brand-card-note { display: block; }
.tpl-brand-card-title {
  font-family: var(--tpl-font-head);
  font-size: 16px;
  font-weight: 600;
  line-height: 1.35;
}
.tpl-brand-card-note {
  margin-top: 3px;
  color: var(--tpl-ink-muted);
  font-size: 13px;
  line-height: 1.45;
}
.tpl-brand-card-arrow { color: var(--tpl-blue); font-size: 18px; }

/* Sibling brands are still secondary navigation, so they use the same approved
   icons at a shorter row height than the directory's primary cards. */
.tpl-brand-links {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(216px, 1fr));
  gap: 8px;
}
.tpl-brand-links a { min-height: 58px; padding: 10px 12px; }
.tpl-brand-links img { width: 32px; height: 32px; }
.tpl-brand-links span {
  min-width: 0;
  font-size: 13.5px;
  font-weight: 500;
  line-height: 1.35;
}
/* --- section hierarchy ---------------------------------------------------- */

/* Everything used to carry the same visual weight, so "browse other states" read
   as important as the list the visitor actually came for. The secondary
   navigation blocks now sit on a banded background, visually below the content. */
.tpl-browse {
  background: var(--tpl-surface);
  border-top: 0;
  margin-top: 56px;
  padding: 8px 0 40px;
}
.tpl-browse h2 { font-size: 19px; margin: 32px 0 12px; }
.tpl-browse p { font-size: 14px; margin: 0 0 14px; }
.tpl-browse .tpl-states a,
.tpl-browse .tpl-links a { background: var(--tpl-white); }

/* --- link grids ----------------------------------------------------------- */

.tpl-states { display: grid; grid-template-columns: repeat(auto-fill, minmax(158px, 1fr)); gap: 8px; }
/* State links and non-interactive route metrics share one compact card shape.
   The route metrics become links only after the backend can filter corridors;
   until then, matching their layout without a hover/focus affordance keeps the
   counts useful without promising a destination. */
.tpl-states a,
.tpl-states .tpl-state-flat,
.tpl-states .tpl-highway-metric {
  display: flex;
  min-height: 40px;
  box-sizing: border-box;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  background: var(--tpl-white);
  border: 1px solid var(--tpl-line);
  border-radius: var(--tpl-radius);
  padding: 10px 13px;
  font-size: 13.5px;
  color: var(--tpl-ink);
  text-decoration: none;
}
.tpl-states a,
.tpl-links a {
  transition:
    color 180ms cubic-bezier(0.2, 0, 0, 1),
    border-color 180ms cubic-bezier(0.2, 0, 0, 1);
}

.tpl-states a:hover,
.tpl-links a:hover {
  border-color: var(--tpl-blue);
  color: var(--tpl-blue);
}
.tpl-states .tpl-state-flat { color: var(--tpl-ink-muted); background: var(--tpl-surface-alt); cursor: default; }
/* INERT ONLY WHEN IT IS NOT A LINK — hence span, not the bare class.
   These metrics were all inert: corridor pages needed a filter the endpoint did not
   have, so `border: 0; cursor: default` deliberately made them read as text. Now the
   linkable ones are anchors to state-scoped corridor pages, and this rule was
   defeating that: at (0,0,2,0) it outranks `.tpl-states a` at (0,0,1,1), so the anchor
   lost its chip border and got an arrow cursor — a link that neither looked nor felt
   like one. State routes are still spans, because fromSlug() rejects them and a link
   would 404, so they keep exactly the treatment they had. */
.tpl-states span.tpl-highway-metric {
  color: var(--tpl-ink);
  border: 0;
  cursor: default;
}
.tpl-states .c { color: var(--tpl-ink-soft); font-variant-numeric: tabular-nums; }
.tpl-highways a,
.tpl-highways .tpl-state-flat,
.tpl-highways .tpl-highway-metric { font-weight: 500; }
.tpl-highways .c { font-weight: 400; }

.tpl-list-note {
  margin: 14px 0 0;
  color: var(--tpl-ink-muted);
  font-size: 13.5px;
  line-height: 1.6;
}

/* --- root Locations directory -------------------------------------------- */

.tpl-root-hero h1 { max-width: 19ch; }

.tpl-type-directory {
  background: var(--tpl-surface);
  padding: 56px 0 64px;
}
.tpl-section-intro { max-width: 62ch; margin-bottom: 28px; }
.tpl-section-eyebrow {
  margin: 0 0 8px;
  color: var(--tpl-blue);
  font-family: var(--tpl-font-head);
  font-size: 12.5px;
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
}
.tpl-section-intro h2 {
  margin: 0 0 8px;
  color: var(--tpl-ink);
  font-family: var(--tpl-font-head);
  font-size: 30px;
  font-weight: 600;
  letter-spacing: -0.01em;
}
.tpl-section-intro > p:last-child {
  margin: 0;
  color: var(--tpl-ink-muted);
  font-size: 15px;
  line-height: 1.6;
}
.tpl-type-grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 12px;
}
.tpl-type-card {
  display: grid;
  grid-template-columns: 40px minmax(0, 1fr) auto;
  gap: 16px;
  align-items: center;
  min-height: 112px;
  box-sizing: border-box;
  padding: 22px;
  color: var(--tpl-ink);
  text-decoration: none;
  background: var(--tpl-white);
  border: 1px solid var(--tpl-line);
  border-radius: var(--tpl-radius);
  transition:
    color 180ms cubic-bezier(0.2, 0, 0, 1),
    border-color 180ms cubic-bezier(0.2, 0, 0, 1);
}
.tpl-type-card:hover {
  color: var(--tpl-blue);
  border-color: var(--tpl-blue);
}
.tpl-type-card-icon { display: block; width: 40px; height: 40px; object-fit: contain; }
.tpl-type-card-copy { display: block; min-width: 0; }
.tpl-type-card-title {
  display: block;
  font-family: var(--tpl-font-head);
  font-size: 17px;
  font-weight: 600;
  line-height: 1.35;
}
.tpl-type-card-description {
  display: block;
  margin-top: 5px;
  color: var(--tpl-ink-muted);
  font-size: 13px;
  line-height: 1.5;
}
.tpl-type-card-arrow { color: var(--tpl-blue); font-size: 19px; }
.tpl-root-list { padding-top: 64px; }
.tpl-root-hero .tps-form:has(#tps-type option[value=""]:checked) {
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr) auto;
}
.tpl-root-hero .tps-form:has(#tps-type option[value=""]:checked) .tps-field-amenity {
  display: none;
}
.tpl-poitype {
  color: var(--tpl-ink-muted);
  font-size: 12.5px;
  font-weight: 500;
}

/* Server-side pagination stays deliberately simple: one row of status and
   Previous/Next controls, with no animated lift or decorative effects. */
.tpl-pagination {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  margin-top: 24px;
}
.tpl-pagination-summary {
  color: var(--tpl-ink-muted);
  font-size: 13.5px;
  font-variant-numeric: tabular-nums;
}
.tpl-pagination-actions { display: flex; gap: 8px; }
.tpl-page-link {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 7px;
  min-height: 40px;
  box-sizing: border-box;
  padding: 9px 14px;
  color: var(--tpl-ink);
  background: var(--tpl-white);
  border: 1px solid var(--tpl-line);
  border-radius: var(--tpl-radius-sm);
  font-size: 13.5px;
  font-weight: 600;
  text-decoration: none;
  transition:
    color 180ms cubic-bezier(0.2, 0, 0, 1),
    border-color 180ms cubic-bezier(0.2, 0, 0, 1);
}
.tpl-page-link:hover { color: var(--tpl-blue); border-color: var(--tpl-blue); }
.tpl-page-link.is-disabled { color: var(--tpl-ink-faint); cursor: default; }

.tpl-links { display: flex; flex-wrap: wrap; gap: 8px; }
.tpl-links a {
  display: inline-flex;
  min-height: 40px;
  box-sizing: border-box;
  align-items: center;
  gap: 8px;
  background: var(--tpl-white);
  border: 1px solid var(--tpl-line);
  border-radius: 100px;
  padding: 9px 15px 9px 10px;
  font-size: 13.5px;
  color: var(--tpl-ink);
  text-decoration: none;
}
.tpl-type-icon {
  display: block;
  width: 24px;
  height: 24px;
  flex: 0 0 24px;
  object-fit: contain;
}

/* The link out to the interactive app version. Quiet — it is a secondary route for
   the minority who want the map, not a competing call to action. */
.tpl-appswitch { margin: 20px 0 0; font-size: 14.5px; }
.tpl-appswitch a { font-weight: 600; }

/* --- CTA ------------------------------------------------------------------ */

.tpl-cta {
  display: grid;
  /* Was 1.15fr / 0.85fr with a one-line headline, which left most of the left
     column empty on a wide screen while the two cards crowded the right. The
     headline is now a real sentence, so the split is closer to even. */
  grid-template-columns: minmax(0, 1fr) minmax(0, 0.72fr);
  gap: 48px;
  align-items: center;
  /* The fleet image comes from the current Trucker Path homepage. The lighter
     masks keep both text columns readable while letting the trucks remain a
     recognisable part of the card instead of disappearing into the surface. */
  background:
    linear-gradient(90deg, rgba(0, 24, 42, 0.78) 0%, rgba(0, 24, 42, 0.64) 48%, rgba(0, 24, 42, 0.5) 100%),
    linear-gradient(180deg, rgba(0, 19, 34, 0.02) 0%, rgba(0, 19, 34, 0.18) 100%),
    url('/assets/locations/fleet-cta-trucks.jpg') center 58% / cover no-repeat;
  background-color: var(--tpl-ink-deep);
  border-radius: 14px;
  padding: 48px 52px;
  margin: var(--tpl-content-gap) 0;
  color: var(--tpl-white);
}
/* Was `.tpl-cta h2`. The CTA's title is now a <p role="heading"> so a promo
   label stays out of the document outline — see the note in _cta.blade.php. The
   h2 selector is kept so the block still looks right if any other page passes a
   real heading in. */
/* Eyebrow: names the product so the headline can be about the benefit. */
.tpl-cta-eyebrow {
  font-family: var(--tpl-font-head);
  font-size: 11.5px;
  font-weight: 600;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--tpl-blue-bright);
  margin: 0 0 12px !important;
}
.tpl-cta h2,
.tpl-cta .tpl-cta-title {
  font-family: var(--tpl-font-head);
  font-size: 30px;
  font-weight: 600;
  line-height: 1.25;
  color: var(--tpl-white);
  margin: 0 0 10px;
  text-wrap: balance;
}
/* Must not inherit the body-copy rule below, which is also `.tpl-cta p`. */
.tpl-cta p:not(.tpl-cta-title) { color: var(--tpl-on-dark-secondary); margin: 0 0 20px; max-width: 46ch; font-size: 15.5px; }
.tpl-cta .tpl-cta-button { font-family: var(--tpl-font-head); }
/* ROWS, NOT BOXES.
   The two secondary items were cards with their own fill and 1px border, sitting
   inside an already-dark panel. Dark-on-dark at that size reads as an empty
   placeholder rather than as content, which is most of why the block looked
   unfinished. Hairline separators carry the same grouping without inventing a
   container. */
.tpl-cta-side { min-width: 0; align-self: center; }
.tpl-cta-sidelabel {
  font-family: var(--tpl-font-head);
  font-size: 11.5px;
  font-weight: 600;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--tpl-on-dark-faint);
  margin: 0 0 10px !important;
}
.tpl-cta-rows { border-top: 1px solid var(--tpl-on-dark-line); }
.tpl-cta-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  border-bottom: 1px solid var(--tpl-on-dark-line);
  padding: 14px 0;
  text-decoration: none;
}
.tpl-cta-rowtitle {
  display: block;
  font-family: var(--tpl-font-head);
  font-size: 14.5px;
  font-weight: 600;
  line-height: 1.3;
  color: var(--tpl-white);
}
.tpl-cta-rownote {
  display: block;
  font-size: 13px;
  line-height: 1.45;
  color: var(--tpl-on-dark-muted);
  margin-top: 3px;
}
.tpl-cta-rowarrow {
  display: block;
  width: 12px;
  height: 12px;
  flex: 0 0 12px;
  object-fit: contain;
  opacity: 0.9;
  transition: transform 0.15s ease;
}
.tpl-cta-row:hover .tpl-cta-rowtitle,
.tpl-cta-row:focus-visible .tpl-cta-rowtitle { color: var(--tpl-blue-bright); }
.tpl-cta-row:hover .tpl-cta-rowarrow { transform: translateX(3px); }

/* --- business-owner claim ------------------------------------------------- */

/* A FOOTNOTE, NOT A BANNER.
   This was `background: var(--tpl-blue-wash)` with a border and 18px padding — the
   only tinted full-width band on the page, carrying more visual weight than the
   primary CTA, for the item that matters to the fewest visitors. `margin: 0 0 8px`
   also gave it no top margin, so it butted straight into the dark panel above and
   the two treatments collided.
   It is now a quiet text footnote. Same information and link, with weight
   proportional to its priority and no extra divider competing with the CTA. */
.tpl-claim {
  margin: 30px 0 0;
  padding: 0;
  border-top: 0;
  font-size: 13.5px;
  line-height: 1.6;
  color: var(--tpl-ink-soft);
}
.tpl-claim b { color: var(--tpl-ink); font-family: var(--tpl-font-head); font-weight: 600; }
.tpl-claim a { font-weight: 600; white-space: nowrap; }

/* --- FAQ ------------------------------------------------------------------ */

.tpl-faq details {
  background: var(--tpl-white);
  border: 1px solid var(--tpl-line);
  border-radius: var(--tpl-radius);
  margin-bottom: 8px;
  padding: 0 20px;
}
.tpl-faq details:last-of-type { margin-bottom: 0; }
.tpl-faq details[open] { box-shadow: 0 1px 4px rgba(16, 24, 40, 0.05); }
.tpl-faq summary {
  font-family: var(--tpl-font-head);
  font-weight: 600;
  font-size: 15.5px;
  color: var(--tpl-ink);
  cursor: pointer;
  padding: 16px 0;
  list-style: none;
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 16px;
}
.tpl-faq summary::-webkit-details-marker { display: none; }
.tpl-faq-icon {
  position: relative;
  width: 16px;
  height: 16px;
  flex: 0 0 16px;
}
.tpl-faq-icon::before,
.tpl-faq-icon::after {
  content: "";
  position: absolute;
  top: 7px;
  left: 2px;
  width: 12px;
  height: 2px;
  border-radius: 1px;
  background: var(--tpl-blue);
}
.tpl-faq-icon::after {
  transform: rotate(90deg) scale(1);
  opacity: 1;
  filter: blur(0);
  transition: transform 200ms cubic-bezier(0.2, 0, 0, 1),
              opacity 200ms cubic-bezier(0.2, 0, 0, 1),
              filter 200ms cubic-bezier(0.2, 0, 0, 1);
}
.tpl-faq details[open] .tpl-faq-icon::after {
  transform: rotate(90deg) scale(0.25);
  opacity: 0;
  filter: blur(4px);
}
.tpl-faq-answer { overflow: hidden; }
.tpl-faq p { margin: 0 0 18px; color: var(--tpl-ink-muted); font-size: 15px; line-height: 1.7; }

/* FAQ is its own closing section. The generic `.tpl-main` rhythm is weighted
   toward content that continues below it, so its 40/16 padding plus the h2's
   top margin left much more air above the accordion than below it. Keep the
   closing section optically centered before the footer instead. */
.tpl-main.tpl-faq-section { padding: 48px 0; }
.tpl-faq-section .tpl-faq h2 { margin: 0 0 16px; }

/* --- search --------------------------------------------------------------- */

.tps-form {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr)) auto;
  gap: 10px;
  align-items: end;
  background: var(--tpl-on-dark-surface);
  border: 0;
  border-radius: 12px;
  padding: 20px;
  margin-top: 26px;
}
.tps-form:has(.tps-field-brand:not([hidden])) {
  grid-template-columns: repeat(4, minmax(0, 1fr)) auto;
}
/* min-width:0 is load-bearing. Grid and flex items default to min-width:auto,
   which resolves to min-content — and a <select>'s min-content is the width of
   its longest option ("District of Columbia", "Walmart Stores"). That gave the
   whole page a ~490px floor that no media query could shrink, so it scrolled
   sideways on every phone. width:100% does not override min-width:auto. */
.tps-field { display: flex; flex-direction: column; gap: 6px; position: relative; min-width: 0; }
.tps-field[hidden] { display: none; }
.tps-field select, .tps-field input { min-width: 0; }
.tps-form { min-width: 0; }
.tps-field label {
  font-family: var(--tpl-font-head);
  font-size: 12.5px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--tpl-on-dark-secondary);
}
.tps-optional { text-transform: none; letter-spacing: 0; font-weight: 400; color: var(--tpl-on-dark-subtle); }
.tps-field select,
.tps-field input {
  width: 100%;
  box-sizing: border-box;
  height: 42px;
  margin: 0;
  border: 1px solid var(--tpl-line);
  border-radius: var(--tpl-radius-sm);
  padding: 0 12px;
  font-family: var(--tpl-font-body);
  font-size: 14.5px;
  font-weight: 400;
  line-height: 1.2;
  color: var(--tpl-ink);
  background-color: var(--tpl-white);
  box-shadow: none;
}
.tps-field select {
  padding-right: 40px;
  -webkit-appearance: none;
  appearance: none;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='18' height='18' viewBox='0 0 18 18'%3E%3Cpath d='m5 7 4 4 4-4' fill='none' stroke='%23868f98' stroke-width='1.5' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
  background-position: right 12px center;
  background-repeat: no-repeat;
  background-size: 18px 18px;
}
.tps-field-location input[role="combobox"] {
  padding-right: 40px;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='18' height='18' viewBox='0 0 18 18'%3E%3Cpath d='m5 7 4 4 4-4' fill='none' stroke='%23868f98' stroke-width='1.5' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
  background-position: right 12px center;
  background-repeat: no-repeat;
  background-size: 18px 18px;
}
.tps-field input::placeholder { color: var(--tpl-ink-faint); }
.tps-field select:focus,
.tps-field input:focus {
  border-color: var(--tpl-blue);
  outline: 1px solid var(--tpl-blue);
  outline-offset: 0;
}

.tp-site-chrome .tp-site-button.tp-site-button--form {
  height: 42px;
  padding: 0 28px;
}
.tps-suggest {
  position: absolute;
  top: 100%;
  left: 0;
  right: 0;
  z-index: 40;
  margin: 5px 0 0;
  padding: 5px;
  list-style: none;
  background: var(--tpl-white);
  border: 1px solid var(--tpl-line);
  border-radius: var(--tpl-radius);
  box-shadow: var(--tpl-shadow);
  max-height: 264px;
  overflow-y: auto;
}
.tps-suggest li {
  padding: 9px 11px;
  font-size: 13.5px;
  color: var(--tpl-ink);
  border-radius: 6px;
  cursor: pointer;
}
.tps-suggest li:hover,
.tps-suggest li[aria-selected="true"] { background: var(--tpl-blue-wash); color: var(--tpl-blue); }

/* --- responsive ----------------------------------------------------------- */

/* --- POI detail page ------------------------------------------------------
   /location-details/{type}/{state}/{city}/{name}?id=N

   Same hero, same bands, same tokens as the state pages — a detail page is one
   level down the same tree, not a different product. What it adds is the action
   row under the h1 and the two-column facts/panels split.

   .tpl-detail-hero joins the .tpl-root-hero / .tpl-hub-hero / .tpl-state-hero
   family, so it gets the same US-map background pseudo-element, on the state
   tier's tuning (top 118px, min(42vw,580px), opacity .2) rather than a fourth set
   of hand-picked numbers. An earlier version deliberately left it out, arguing
   that a map of the country behind a page about one specific place is decoration
   arguing with the content. That reasoning is not wrong in the abstract and it was
   the wrong call here: these pages are one visual system, and a detail page that
   drops the hero treatment reads as a different site rather than as one level down
   the same tree. Consistency wins. */

/* BREADCRUMB, FOUR LEVELS DEEP.
   The shared .tpl-crumb is a nowrap flex row, which is fine for the list pages'
   three fixed-length levels. This trail has four, and the last one is a POI name of
   arbitrary length — so on a phone flex squeezed every item until "Truck Stops"
   broke across two lines and "Top Fuel Bracey" across three. Observed, not
   predicted.

   Wrap BETWEEN items instead of inside them: the parents and separators stay on one
   line each, and only the leaf may wrap, because it is last and has nothing after it
   to strand. Scoped to the detail variant so the list pages keep the behaviour they
   already have. */
.tpl-crumb-detail { flex-wrap: wrap; row-gap: 2px; }
.tpl-crumb-detail > a,
.tpl-crumb-detail > .tpl-crumb-separator { white-space: nowrap; }

/* ACTION ROW.
   Both actions use the shared site-button geometry and typography. The secondary
   call action changes only its surface treatment so this row cannot drift from
   the Navigation and Locations CTA button contract. */
.tpl-actions {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
  margin-top: 26px;
}
.tpl-actions .tp-site-button { box-sizing: border-box; }

/* Call is a real link, so it gets a real affordance — but stays quieter than the
   shared primary button because the app is the conversion target. */
.tpl-actions .tpl-action {
  background-color: var(--tpl-on-dark-surface);
  border: 1px solid var(--tpl-on-dark-border);
}
.tpl-actions .tpl-action:hover,
.tpl-actions .tpl-action:focus-visible {
  background-color: var(--tpl-on-dark-surface-hover);
  border-color: var(--tpl-on-dark-border-hover);
  color: var(--tpl-white);
}

/* --- ROUTE MARKER --------------------------------------------------------
   The road sign for `highway` + `exit`, in the detail hero. Real data rendered in
   the visual language a North American driver already reads — it was six points of
   grey text at the tail of the subtitle before. See
   resources/views/poi/partials/_route-shield.blade.php.

   Sits on the dark hero, so the signs keep their real colours (they are legible on
   dark by design — that is what road signs are for) and the text beside them is
   white. */
.tpl-marker {
  display: inline-flex;
  align-items: center;
  gap: 12px;
  margin-top: 18px;
}
.tpl-marker-sign { display: block; flex: 0 0 auto; line-height: 0; }
/* Highway numerals are set in a condensed-ish weight on real signage; Poppins at
   700 with tight tracking is the closest thing already loaded, and loading a
   dedicated sign font for one glyph run would cost more than it buys. */
.tpl-marker-num {
  font-family: var(--tpl-font-head);
  font-size: 17px;
  font-weight: 700;
  letter-spacing: -0.5px;
}
/* Three- and four-digit routes (I-405, US-1187) overflow the shield at full size. */
.tpl-marker-n3 { font-size: 14px; letter-spacing: -0.8px; }
.tpl-marker-n4 { font-size: 11.5px; letter-spacing: -0.9px; }

.tpl-marker-text { display: flex; flex-direction: column; gap: 2px; }
.tpl-marker-route {
  font-family: var(--tpl-font-head);
  font-size: 16px;
  font-weight: 600;
  color: var(--tpl-white);
  line-height: 1.1;
}
.tpl-marker-exit {
  font-size: 14px;
  color: var(--tpl-on-dark-secondary);
  line-height: 1.1;
}

/* --- MANY / SOME / FEW LEGEND -------------------------------------------
   The app's own three words, shown TOGETHER so they read as a scale of what the app
   reports rather than as this location's current state. Nothing is highlighted and
   there is no timestamp — see the notes in _locked-band.blade.php and
   config/poi-detail.php for why one-of-three-highlighted would be both a real-time
   disclosure and wrong most of the time.

   Real semantic colours, not the accent: green/amber/red is what the app uses and
   what the words mean. The tones are the same tokens the bypass chip uses. */
.tpl-inapp-scale {
  display: flex;
  gap: 5px;
  margin: 10px 0 12px;
}
.tpl-scale-step {
  flex: 1 1 0;
  text-align: center;
  font-family: var(--tpl-font-head);
  font-size: 12px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  padding: 6px 4px;
  border-radius: var(--tpl-radius-sm);
  /* Deliberately not saturated. At full app-strength green these three read as a
     status readout; muted, with all three present, they read as a key. */
  border: 1px solid transparent;
}
.tpl-scale-go   { background: var(--tpl-go-wash); color: var(--tpl-go-text); border-color: var(--tpl-go-border); }
.tpl-scale-warn { background: var(--tpl-caution-wash); color: var(--tpl-caution-text); border-color: var(--tpl-caution-border); }
.tpl-scale-stop { background: var(--tpl-danger-wash); color: var(--tpl-danger-text); border-color: var(--tpl-danger-border); }

/* --- PUBLISHED REVIEW EXCERPTS -------------------------------------------
   Real driver words, open on the page — the gate's other side, not behind it. The
   only section that meaningfully answers the thin-content problem, because a
   driver's sentence exists nowhere else while an address exists everywhere.

   Quoted with a left rule rather than boxed: a card around a one-line quote gives
   it more furniture than content, which is what made the first CTA block read as
   filler. */
.tpl-detail-reviews { min-width: 0; }
.tpl-quote {
  margin: 0 0 16px;
  padding: 0 0 0 16px;
  border-left: 3px solid var(--tpl-blue-wash);
  max-width: 72ch;
}
.tpl-quote:last-child { margin-bottom: 0; }
.tpl-quote-stars { display: inline-flex; gap: 1px; font-size: 13px; line-height: 1; }
.tpl-qstar { color: var(--tpl-ink-faint); }
/* Amber, not the brand blue — a blue star does not read as a rating. Same token as
   the hero's aggregate row. */
.tpl-qstar-on { color: var(--tpl-rating); }
.tpl-quote-rating {
  font-size: 12px;
  color: var(--tpl-ink-soft);
  margin-left: 8px;
}
.tpl-detail-reviews .tpl-quote p {
  font-size: 15.5px;
  line-height: 1.6;
  color: var(--tpl-ink);
  margin: 6px 0 0;
}

/* --- THE QUESTIONS (reviews row) ----------------------------------------
   Third variant of the same device: parking gets the app's three-word scale, fuel
   gets the two-price comparison, this gets the questions a driver arrives with.
   Each shows the shape of what the app answers; none states an answer.

   Quoted rather than bulleted — these are things a driver says, and a left rule
   reads as speech where a bullet reads as a feature list. */
.tpl-inapp-qs {
  display: flex;
  flex-direction: column;
  gap: 6px;
  margin: 10px 0 12px;
  padding-left: 10px;
  border-left: 2px solid var(--tpl-blue-wash);
}
.tpl-inapp-qitem {
  font-size: 14px;
  line-height: 1.45;
  color: var(--tpl-ink);
  font-style: italic;
}

/* --- TWO-PRICE COMPARISON (fuel) ----------------------------------------
   The posted price and the discounted one, as two LABELLED EMPTY slots. Same device
   as the scale and the questions: the shape of what the app shows, never the values.
   See _locked-band.blade.php for why no number goes in here, ever.

   STACKED, and the horizontal version is why. It lived in `grid-template-columns:
   1fr auto 1fr` with the arrow as a ::before pinned to column 2 — but a ::before on
   a grid container becomes a grid ITEM, so it competed with the two children for
   auto-placement and landed off to one side while the boxes ended up in the wrong
   cells at unequal heights. On top of that the row sits in a ~240px column of a
   three-across grid, which has no room for two priced boxes side by side; the
   longer label wrapped and broke the alignment again.

   A real element for the arrow, flex column, done. And vertical is how a discount
   reads anyway: this price, down to that one. */
.tpl-inapp-compare {
  display: flex;
  flex-direction: column;
  gap: 4px;
  margin: 10px 0 12px;
}
.tpl-cmp {
  display: flex;
  flex-direction: column;
  gap: 2px;
  padding: 7px 10px;
  border-radius: var(--tpl-radius-sm);
  border: 1px solid var(--tpl-line);
  background: var(--tpl-surface);
  min-width: 0;
}
.tpl-cmp-arrow {
  align-self: center;
  font-size: 12px;
  line-height: 1;
  color: var(--tpl-ink-faint);
}
.tpl-cmp-label {
  font-size: 12px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  color: var(--tpl-ink-soft);
  line-height: 1.2;
}
/* The slot where the number would be. A bar plus the unit, on one line. */
.tpl-cmp-slot { display: flex; align-items: center; gap: 4px; }
.tpl-cmp-slot::before {
  content: "";
  display: block;
  width: 38px;
  height: 11px;
  border-radius: 3px;
  background: var(--tpl-placeholder);
}
.tpl-cmp-unit { font-size: 12px; color: var(--tpl-ink-soft); }
.tpl-cmp-hint { font-size: 12px; color: var(--tpl-ink-soft); line-height: 1.2; }

/* The discounted side reads as the better one — which is the product fact being
   stated. It carries no value, so it claims an ordering, not an amount. */
.tpl-cmp-save { background: var(--tpl-go-wash); border-color: var(--tpl-go-border); }
.tpl-cmp-save .tpl-cmp-label { color: var(--tpl-go-text); }
.tpl-cmp-save .tpl-cmp-slot::before { background: var(--tpl-go-border); }
.tpl-cmp-save .tpl-cmp-unit, .tpl-cmp-save .tpl-cmp-hint { color: var(--tpl-go-text); }

/* THE OPEN RATING, in the detail hero under the h1.
   Renders nothing today — the endpoint returns no aggregate, so ratingOf() is null
   and the reviews module stays locked instead. Styled now so the day the field
   lands it is a data change, not a design task.

   The number leads at display size because that is what a driver scans; the stars
   are a glyph row beside it, and the full sentence ("3.3 out of 5, from 9 drivers…")
   is the accessible text, since a row of ★ characters says nothing to a screen
   reader. */
.tpl-rating {
  display: flex;
  align-items: center;
  gap: 10px;
  flex-wrap: wrap;
  margin: 16px 0 0;
}
.tpl-rating-value {
  font-family: var(--tpl-font-head);
  font-size: 26px;
  font-weight: 600;
  line-height: 1;
  color: var(--tpl-white);
  font-variant-numeric: tabular-nums;
}
.tpl-rating-stars { display: inline-flex; gap: 1px; font-size: 17px; line-height: 1; }
.tpl-star { color: var(--tpl-on-dark-disabled); }
/* Amber, not the brand blue: a blue star does not read as a rating, and the app
   uses a warm fill for the same control. */
.tpl-star-on { color: var(--tpl-rating); }
.tpl-rating-count { font-size: 14.5px; color: var(--tpl-on-dark-secondary); }

/* OPEN FACTS — full width, no sidebar.
   These were the left half of a two-column split with the locked modules in a
   right rail. The rail was wrong twice: a right column reads as advertising and
   gets skipped, and it put the page's main interaction where nobody looks. The
   facts now take the full column and the locked band sits below them, in the
   centre, where a reader is already going. */
/* Facts, amenities and reviews as a single stack.

   This was a two-column grid: facts left, a Google Maps embed right, with the
   children placed explicitly so source order (address first, for crawlers) could
   differ from visual order. The map has since been dropped from the page — it added
   nothing a crawler reads, the local relevance already comes from the visible
   address plus PostalAddress/GeoCoordinates in the JSON-LD, and a fully interactive
   Google map sitting next to "Get directions with Trucker Path" competes with the
   one action this page exists to drive.

   With the right column gone there is nothing left for a grid to place, so this is
   plain flow: each block full width, in DOM order. The explicit grid-row/grid-column
   on the children went with it — leftover placement rules on a single-column layout
   are a trap for whoever edits this next. */
.tpl-detail-body { min-width: 0; }
.tpl-detail-facts { min-width: 0; }
.tpl-detail-facts h2:first-child { margin-top: 0; }

/* Amenities below the facts. They used to live inside the facts column, which cost
   twice: the chips wrapped inside 600px with 1152 available, and on a phone they sat
   between the address and the map. */
.tpl-detail-amenities { min-width: 0; }
.tpl-detail-amenities h2 { margin-top: 44px; }

/* Definition list as a two-column grid: label left, value right. dt/dd rather
   than a table because these are name/value pairs about one thing, not rows.
   Capped rather than full-bleed — a 1200px-wide row for "Phone" would put the
   value a screen away from its own label. */
.tpl-facts {
  display: grid;
  grid-template-columns: 132px minmax(0, 1fr);
  gap: 0;
  margin: 0;
  max-width: 640px;
  border-top: 1px solid var(--tpl-line);
}
.tpl-facts dt {
  font-family: var(--tpl-font-head);
  font-size: 14px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--tpl-ink-soft);
  padding: 15px 0;
  border-bottom: 1px solid var(--tpl-line);
}
.tpl-facts dd {
  margin: 0;
  padding: 15px 0;
  font-size: 15px;
  line-height: 1.5;
  color: var(--tpl-ink);
  border-bottom: 1px solid var(--tpl-line);
  min-width: 0;
  overflow-wrap: break-word;
}
.tpl-facts .tpl-addr { display: block; font-size: inherit; }

/* Clearance and capacity read as figures, not prose — a driver scans for the number.
   Tabular so a column of them lines up. */
.tpl-clearance, .tpl-capnum {
  font-family: var(--tpl-font-head);
  font-size: 17px;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
  color: var(--tpl-ink);
}
/* Clearance carries warning weight because getting it wrong hits the bridge. Amber
   rather than red: this is information to act on, not an error state. */
.tpl-clearance { color: var(--tpl-clearance-warn); }
.tpl-approx {
  display: block;
  font-size: 12px;
  color: var(--tpl-warn);
  margin-top: 2px;
}
/* City under a nearby POI's name, so the row says where without a second line. */
.tpl-nearby-where { color: var(--tpl-ink-soft); font-weight: 400; }

/* Amenities: chips, wrapping, ALL of them. Never partially hidden — they are
   static facility attributes already published on the state list pages and in
   their JSON-LD, and they are the page's only substantive content. See the note
   in locations-detail.blade.php. */
.tpl-amenities {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  list-style: none;
  margin: 0;
  padding: 0;
}
.tpl-amenity {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  background: var(--tpl-surface);
  border: 0;
  border-radius: var(--tpl-radius-sm);
  padding: 8px 12px;
  font-size: 14px;
  color: var(--tpl-ink);
}
.tpl-amenity img { display: block; flex: 0 0 auto; }
.tpl-amenity b { font-weight: 600; color: var(--tpl-ink-muted); }
/* Bypass support is the one amenity that saves a driver time rather than
   describing a facility, so it carries the semantic green, not the accent. */
.tpl-amenity-bypass {
  background: var(--tpl-go-wash);
  border-color: var(--tpl-go-border);
  color: var(--tpl-go-text);
  font-weight: 600;
}

/* --- "IN THE APP" MODULE -------------------------------------------------
   Third attempt. The first two failed for the same reason, recorded here so the
   fourth does not repeat it:

     v1  three cards, each an UNLOCK pill over a group of grey bars -> read as a
         paywall: repeated pills, tinted panel, no real content anywhere.
     v2  one set of bars off to the side -> worse. The bars floated in half a screen
         of empty space, far from the list and too faint to signify, so they read as
         a skeleton loader that never finished. A bug, not a lock.

   Common cause: nothing is behind the lock, so any visual implying hidden content
   is either dishonest (blurring a real value publishes it — filter: blur() is
   paint-time only) or broken (empty skeleton bars). There is no third version of
   fake concealment that works, so there is no placeholder here at all.

   AND IT NO LONGER LOOKS LIKE AN AD. v1/v2 were a tinted rounded box on a page
   whose every other section is white with hairline rules, and that difference was
   most of why the eye skipped it. This uses the page's own language: a rule above,
   a heading, a list, one filled button. The button is still the only filled element
   below the hero, which is where the emphasis belongs. */
.tpl-inapp {
  margin: 56px 0 0;
  padding-top: 28px;
  border-top: 1px solid var(--tpl-line);
}
/* These two are <p> and would have been clobbered by `.tpl-main p` before that rule
   gained :not([class]) — see the note on it. That is why this module looked
   hierarchy-less through three redesigns. */
.tpl-inapp-eyebrow {
  font-family: var(--tpl-font-head);
  font-size: 12px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.07em;
  color: var(--tpl-blue-strong);
  margin: 0 0 8px;
}
.tpl-inapp-title {
  font-family: var(--tpl-font-head);
  font-size: 24px;
  font-weight: 600;
  line-height: 1.25;
  letter-spacing: -0.01em;
  /* Full ink, matching the page's h2s. v2 rendered this in a muted grey, which put
     the section's own title at less contrast than the body text under it. */
  color: var(--tpl-ink);
  margin: 0 0 22px;
  max-width: 40ch;
  text-wrap: balance;
}

/* Three across, using the width the module actually has. Auto-fit rather than a
   fixed three, because the count is per type — a repair shop gets one. */
.tpl-inapp-list {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
  gap: 0;
  list-style: none;
  margin: 0;
  padding: 0;
  border-top: 1px solid var(--tpl-line);
}
.tpl-inapp-list > li { border-bottom: 1px solid var(--tpl-line); }
/* Vertical hairlines between columns, but only between — :not(:first-child) rather
   than a right border on every item, which would leave one hanging at the row end. */
.tpl-inapp-list > li + li { border-left: 1px solid var(--tpl-line); }

.tpl-inapp-item {
  display: block;
  padding: 18px 22px 18px 0;
  text-decoration: none;
  color: inherit;
  height: 100%;
  box-sizing: border-box;
  transition: background 120ms ease;
}
.tpl-inapp-list > li + li .tpl-inapp-item { padding-left: 22px; }
.tpl-inapp-item:hover { background: var(--tpl-blue-wash); }

/* The padlock sits ON the row. v2 moved it up into the eyebrow and the three rows
   immediately stopped reading as gated at all — they looked like ordinary links. */
.tpl-inapp-lock {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 22px;
  height: 22px;
  border-radius: 50%;
  background: var(--tpl-blue-wash);
  color: var(--tpl-blue);
  margin-bottom: 10px;
}
.tpl-inapp-item:hover .tpl-inapp-lock { background: var(--tpl-blue); color: var(--tpl-white); }

.tpl-inapp-q {
  display: block;
  font-family: var(--tpl-font-head);
  font-size: 15.5px;
  font-weight: 600;
  line-height: 1.3;
  color: var(--tpl-ink);
  margin-bottom: 6px;
}
.tpl-inapp-note {
  display: block;
  font-size: 14px;
  line-height: 1.55;
  color: var(--tpl-ink-muted);
  margin-bottom: 10px;
}
.tpl-inapp-go {
  display: block;
  font-family: var(--tpl-font-head);
  font-size: 14px;
  font-weight: 600;
  color: var(--tpl-blue);
}
.tpl-inapp-item:hover .tpl-inapp-go { color: var(--tpl-blue-strong); }

.tpl-inapp-foot {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 16px;
  margin-top: 24px;
}
.tpl-inapp-footnote { font-size: 14px; color: var(--tpl-ink-muted); max-width: 40ch; }

/* --- NAVPRO LIVE TOOLS ---------------------------------------------------
   Parking, fuel and truck-safe routing are three equal product capabilities,
   not an information block followed by an unrelated directions button. The
   previews deliberately show interface structure rather than POI-specific live
   values: this server-rendered page does not own those continuously changing
   data points. All three actions keep the existing NavPro destinations and
   campaign attribution. */
.tpl-live-tools {
  margin: 56px 0 0;
  padding-top: 32px;
  border-top: 1px solid var(--tpl-line);
}
.tpl-live-tools__intro {
  display: grid;
  grid-template-columns: minmax(0, 1.35fr) minmax(280px, 0.65fr);
  align-items: end;
  gap: 40px;
  margin-bottom: 24px;
}
.tpl-live-tools__eyebrow {
  margin: 0 0 8px;
  color: var(--tpl-blue);
  font-family: var(--tpl-font-head);
  font-size: 12px;
  font-weight: 700;
  letter-spacing: 0.07em;
  line-height: 1.4;
  text-transform: uppercase;
}
.tpl-live-tools__title {
  max-width: 34ch;
  margin: 0;
  color: var(--tpl-ink);
  font-family: var(--tpl-font-head);
  font-size: 28px;
  font-weight: 600;
  letter-spacing: -0.01em;
  line-height: 1.25;
  text-wrap: balance;
}
.tpl-live-tools__summary {
  max-width: 42ch;
  margin: 0 0 3px;
  color: var(--tpl-ink-muted);
  font-size: 14px;
  line-height: 1.6;
}
.tpl-live-tools__grid {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 16px;
}
.tpl-live-tool {
  display: flex;
  min-width: 0;
  padding: 22px;
  border: 1px solid var(--tpl-line);
  border-radius: var(--tpl-radius);
  background: var(--tpl-white);
  flex-direction: column;
}
.tpl-live-tool__header {
  display: flex;
  min-width: 0;
  align-items: center;
  gap: 12px;
}
.tpl-live-tool__icon {
  display: inline-flex;
  width: 42px;
  height: 42px;
  border-radius: var(--tpl-radius);
  align-items: center;
  justify-content: center;
  flex: 0 0 42px;
  background: var(--tpl-blue-wash);
}
.tpl-live-tool__icon img {
  display: block;
  width: 24px;
  height: 24px;
  object-fit: contain;
}
.tpl-live-tool__name {
  margin: 0;
  color: var(--tpl-ink);
  font-family: var(--tpl-font-head);
  font-size: 18px;
  font-weight: 600;
  line-height: 1.3;
}
.tpl-live-tool__note {
  color: var(--tpl-ink-muted);
  font-size: 14px;
  line-height: 1.55;
}
.tpl-live-tool__note { margin: 0 0 18px; }

.tpl-live-preview {
  position: relative;
  min-height: 190px;
  box-sizing: border-box;
  margin: 20px 0 16px;
  border: 0;
  border-radius: var(--tpl-radius);
  background: var(--tpl-placeholder);
  overflow: hidden;
}
.tpl-live-preview--image img {
  display: block;
  width: 100%;
  height: 190px;
  object-fit: contain;
  object-position: center;
}
.tpl-live-preview--parking img { padding: 8px; box-sizing: border-box; }
.tpl-live-preview--fuel img {
  padding: 0;
  box-sizing: border-box;
  transform: scale(1.08);
}
.tpl-live-preview--route img { object-fit: cover; }
.tpl-live-tool__button {
  width: 100%;
  margin-top: auto;
  box-sizing: border-box;
  font-size: 14px;
}

/* DETAIL TYPOGRAPHY FLOOR.
   The project body-copy contract is 14px. Keep navigational crumbs, field names,
   diagram labels and route-shield numerals compact, but do not shrink sentences,
   CTA supporting copy or browse links to manufacture density. The detail modifiers
   keep this correction local to the POI page instead of silently changing the
   established state-list hierarchy. */
.tpl-detail-main .tpl-cta-rownote,
.tpl-detail-main .tpl-claim,
.tpl-detail-browse .tpl-links a {
  font-size: 14px;
}
.tpl-detail-main .tpl-cta-eyebrow,
.tpl-detail-main .tpl-cta-sidelabel {
  font-size: 12px;
}

@media (max-width: 900px) {
  .tps-form,
  .tps-form:has(.tps-field-brand:not([hidden])) { grid-template-columns: 1fr; }
  .tpl-cta { grid-template-columns: 1fr; padding: 28px 24px; }
  .tpl-brand-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }

  .tpl-inapp { margin-top: 40px; padding-top: 24px; }
  .tpl-inapp-title { font-size: 20px; }
  /* Stacked: the vertical rules between columns become wrong once there is one
     column, and the first item needs the same left padding as the rest (none). */
  .tpl-inapp-list > li + li { border-left: 0; }
  .tpl-inapp-list > li + li .tpl-inapp-item { padding-left: 0; }
  .tpl-inapp-item { padding-right: 0; }
  .tpl-inapp-foot .tp-site-button { width: 100%; }

  .tpl-live-tools { margin-top: 40px; padding-top: 24px; }
  .tpl-live-tools__intro { grid-template-columns: 1fr; gap: 10px; }
  .tpl-live-tools__title { font-size: 24px; }
  .tpl-live-tools__grid { grid-template-columns: 1fr; }
}

@media (max-width: 1199px), (forced-colors: active) {
  .tpl-root-hero::after,
  .tpl-hub-hero::after,
  .tpl-state-hero::after,
  .tpl-detail-hero::after { display: none; }
}

/* Phone: each table row becomes a stacked card. Same markup — the table stays a
   table for screen readers and crawlers — but a horizontally scrolling table is
   a poor way to read a list on a phone, and phones are the primary device here.
   Cells surface their column name from data-label. */
@media (max-width: 720px) {
  .tpl-tablewrap { overflow-x: visible; }
  .tpl-table,
  .tpl-table tbody { display: block; width: 100%; }
  .tpl-table { border: 0; background: none; }
  .tpl-table thead { position: absolute; width: 1px; height: 1px; overflow: hidden;
                     clip: rect(0 0 0 0); white-space: nowrap; }
  .tpl-table tbody tr {
    display: block;
    width: 100%;
    box-sizing: border-box;
    background: var(--tpl-white);
    border: 1px solid var(--tpl-line);
    border-radius: var(--tpl-radius);
    padding: 14px 16px;
    margin-bottom: 10px;
  }
  .tpl-table tbody tr:hover { background: var(--tpl-white); }
  .tpl-table td {
    display: block;
    border: 0;
    padding: 0;
    margin-bottom: 8px;
  }
  .tpl-table td:last-child { margin-bottom: 0; }
  /* Field name for every cell except the name, which is the card's own heading,
     and route, which is self-evident from the shield. */
  .tpl-table td[data-label]:not(.tpl-cell-name):not(.tpl-route)::before {
    content: attr(data-label);
    display: block;
    font-family: var(--tpl-font-head);
    font-size: 12px;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.04em;
    color: var(--tpl-ink-soft);
    margin-bottom: 3px;
  }
  .tpl-table .tpl-cell-name { font-size: 16px; margin-bottom: 10px; }
  .tpl-table .tpl-route { margin-bottom: 10px; }
  /* A cell with no data is an em-dash holding a column open — there are no
     columns here, so it would render as a field name above nothing. */
  .tpl-table td.tpl-cell-blank { display: none; }
}

@media (max-width: 760px) {
  .tpl-hero { padding: 20px 0 36px; }
  .tpl-hero h1 { font-size: 30px; }
  .tpl-hero .sub { font-size: 16px; }
  .tpl-main h2 { font-size: 22px; margin: 36px 0 14px; }
  .tpl-stat { min-width: 0; flex: 1 1 140px; }
  .tpl-type-directory { padding: 40px 0 48px; }
  .tpl-section-intro h2 { font-size: 25px; }
  .tpl-type-grid { grid-template-columns: 1fr; }
  .tpl-type-card { min-height: 0; padding: 18px; }
  .tpl-brand-grid { grid-template-columns: 1fr; }
  .tpl-brand-directory { margin-top: 36px; }
  .tpl-empty-brand { grid-template-columns: 40px minmax(0, 1fr); gap: 12px; padding: 22px 18px; }
  .tpl-pagination { align-items: flex-start; flex-direction: column; }
  .tpl-root-hero .tps-form:has(#tps-type option[value=""]:checked) { grid-template-columns: 1fr; }

  /* Map under the facts, full width. The address is why someone opened the page, so
     it stays first; the map immediately after is the next thing they want. */
  .tpl-detail-amenities h2 { margin-top: 0; }

  /* Facts stack: a 132px label column against a phone's width leaves an address
     wrapping after three words. Label above value instead. */
  .tpl-facts { grid-template-columns: 1fr; }
  .tpl-facts dt { padding: 14px 0 0; border-bottom: 0; }
  .tpl-facts dd { padding: 4px 0 14px; }
  /* Full-width buttons read as buttons on a phone; a 3-wide row of pills does
     not. Primary keeps the top slot. */
  .tpl-actions { gap: 8px; }
  .tpl-actions > * { flex: 1 1 100%; text-align: center; }
}

/* --- wide screens ---------------------------------------------------------
   Everything above is tuned for a ~1200px window, which is also the content
   width — so at 1200px the page looks right and nothing opened up beyond it.
   On a 1680px display the same values read as cramped: the reference layout at
   truckerpath.com/navigation gives its sections 80-130px of vertical padding,
   against 28-40px here.

   Only rhythm and scale change. The content stays at 1200px (--tpl-maxw), which
   already matches the homepage sections — widening the text column instead would
   push line length past comfortable reading. */
@media (min-width: 1200px) {
  :root { --tpl-content-gap: 56px; }
  .tp-site-chrome--dark-hero #tp-main > .tpl-hero:first-child {
    padding-top: calc(36px + var(--tp-site-announcement-height) + var(--tp-site-header-height));
  }
  .tpl-hero { padding: 52px 0 100px; }
  .tpl-hero h1 { font-size: 52px; }
  .tpl-hero .sub { font-size: 19px; }
  .tps-form { margin-top: 46px; }
  .tpl-main { padding: 72px 0 24px; }
  .tpl-browse { padding: 32px 0 72px; }
  .tpl-main h2 { margin: 52px 0 20px; }
  .tpl-browse h2 { margin: 40px 0 16px; }
  .tpl-stats { gap: 20px; margin-top: 36px; }
  .tpl-stat { min-width: 190px; }
  .tpl-cta { margin: var(--tpl-content-gap) 0 0; }
  .tpl-main.tpl-faq-section { padding: 64px 0; }
  .tpl-faq-section .tpl-faq h2 { margin: 0 0 20px; }

  /* Auto table layout spreads spare width across every column in proportion, so
     at 1200px "Route" was given 241px to hold "I-10 Exit 141" and Bypass 182px
     for a single chip, while Location and Amenities — the columns whose content
     actually varies in length — got no more than the short ones. Pinning the
     predictable columns hands the slack to the two that can use it.
     Sized by data-col, not position: Route, Bypass and Phone are conditional. */
  .tpl-table th[data-col="Route"] { width: 132px; }
  .tpl-table th[data-col="Bypass"] { width: 116px; }
  .tpl-table th[data-col="Phone"] { width: 148px; }
  .tpl-table th[data-col="Name"] { width: 22%; }
  .tpl-table th[data-col="Type"] { width: 132px; }

  /* Detail page gets the same opened-up rhythm. */
  .tpl-actions { margin-top: 34px; }
  .tpl-inapp,
  .tpl-live-tools { margin-top: 72px; padding-top: 34px; }
  .tpl-inapp-title { font-size: 27px; }
}

@media (max-width: 560px) {
  .tpl-brand-directory-entry > a { grid-template-columns: auto minmax(0, 1fr); gap: 14px; padding: 16px; }
  .tpl-brand-directory-entry-action { grid-column: 1 / -1; }
  .tpl-brand-card { min-height: 76px; padding: 15px; }
  .tpl-brand-links { grid-template-columns: 1fr; }
  .tpl-live-tool { padding: 18px; }
  .tpl-live-preview { min-height: 0; }
  .tpl-live-preview--image img { height: auto; min-height: 168px; }
}

/* --- client transition shells --------------------------------------------
   These are structural placeholders, not a separate visual language: dark hero
   values use the existing on-dark tokens and list values use the same subdued
   surface as empty/table support UI. There is deliberately no looping shimmer;
   the shell exists only while an SSR response is unknown. */
.tpl-transition-hero { min-height: 248px; }
.tpl-transition-status {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}
.tpl-transition-line,
.tpl-transition-disc {
  display: block;
  position: relative;
  isolation: isolate;
  overflow: hidden;
  border-radius: 999px;
  background: var(--tpl-placeholder);
}
.tpl-transition-hero .tpl-transition-line,
.tpl-transition-hero .tpl-transition-disc {
  background: rgba(255, 255, 255, 0.16);
}
/* A clear travelling highlight tells the driver that data is still arriving
   without turning the placeholder into a flashing progress indicator. The
   highlighted layer is shared by every neutral block, so its colour continues
   to come from the existing token beneath it. */
.tpl-transition-line::after,
.tpl-transition-disc::after,
.tpl-transition-card--map::after {
  content: "";
  position: absolute;
  z-index: 1;
  top: 0;
  bottom: 0;
  left: 0;
  width: 100%;
  transform: translateX(-105%);
  background: linear-gradient(90deg, transparent 0%, rgba(255, 255, 255, 0.16) 22%, rgba(255, 255, 255, 0.78) 50%, rgba(255, 255, 255, 0.16) 78%, transparent 100%);
  animation: tpl-skeleton-sweep 1.12s cubic-bezier(0.4, 0, 0.2, 1) infinite;
  pointer-events: none;
}
@keyframes tpl-skeleton-sweep {
  0% { transform: translateX(-105%); }
  100% { transform: translateX(105%); }
}
/* `min-height` is content-box sizing. On the wide detail Hero the fixed chrome
   paddings total 250px; 342px here therefore produces the same 592px footprint
   as a typical final detail page with a one-line title, without double-counting
   that height as the earlier implementation did. */
.tpl-transition-detail-hero-shell { min-height: 342px; }
.tpl-transition-detail-hero-hints {
  display: grid;
  gap: 22px;
  max-width: 500px;
  margin-top: 34px;
}
.tpl-transition-detail-route { width: 132px; height: 22px; border-radius: 6px; }
.tpl-transition-detail-actions { display: flex; flex-wrap: wrap; gap: 10px; }
.tpl-transition-detail-action { width: 218px; height: 42px; border-radius: 6px; }
.tpl-transition-detail-action--short { width: 168px; }
.tpl-transition-results,
.tpl-transition-detail { min-height: 490px; }
.tpl-transition-results { position: relative; }
.tpl-transition-answer {
  max-width: 760px;
  margin-bottom: 36px;
  padding: 17px 18px;
  border-left: 3px solid var(--tpl-blue);
  border-radius: var(--tpl-radius-sm);
  background: var(--tpl-blue-wash);
}
.tpl-transition-line--answer { width: 100%; height: 11px; margin-bottom: 9px; background: rgba(12, 35, 64, 0.18); }
.tpl-transition-line--answer-short { width: 63%; height: 11px; background: rgba(12, 35, 64, 0.18); }
.tpl-transition-table {
  overflow: hidden;
  border: 1px solid var(--tpl-line);
  border-radius: var(--tpl-radius);
  background: var(--tpl-white);
}
.tpl-transition-table-head,
.tpl-transition-table-row {
  display: grid;
  grid-template-columns: minmax(94px, 0.7fr) minmax(170px, 1.2fr) minmax(168px, 1.15fr) minmax(220px, 1.7fr);
  gap: 18px;
  align-items: center;
  padding: 0 18px;
}
.tpl-transition-table-head {
  height: 38px;
  background: var(--tpl-surface);
}
.tpl-transition-table-head span {
  width: 42px;
  height: 8px;
  border-radius: 999px;
  background: rgba(12, 35, 64, 0.18);
}
.tpl-transition-table-row {
  min-height: 64px;
  border-top: 1px solid var(--tpl-line);
}
.tpl-transition-line--route { width: 58px; height: 19px; background: var(--tpl-ink); }
.tpl-transition-line--name { width: 78%; height: 12px; }
.tpl-transition-line--location { width: 68%; height: 12px; }
.tpl-transition-line--chips { width: 92%; height: 28px; }
.tpl-transition-type-grid {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 16px;
}
.tpl-transition-type-card,
.tpl-transition-brand-card {
  display: flex;
  min-height: 102px;
  box-sizing: border-box;
  align-items: center;
  gap: 14px;
  padding: 20px;
  border: 1px solid var(--tpl-line);
  border-radius: var(--tpl-radius);
  background: var(--tpl-white);
}
.tpl-transition-disc { width: 38px; height: 38px; flex: 0 0 38px; }
.tpl-transition-line--card-title { width: 48%; height: 13px; }
.tpl-transition-line--card-copy { width: 30%; height: 10px; margin-left: -5%; margin-top: 31px; }
.tpl-transition-brand-grid {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: 14px;
}
.tpl-transition-brand-card { min-height: 82px; padding: 16px; }
.tpl-transition-brand-card .tpl-transition-disc { width: 34px; height: 34px; flex-basis: 34px; }
.tpl-transition-brand-card .tpl-transition-line { width: 54%; height: 12px; }
.tpl-transition-detail { position: relative; }
.tpl-transition-detail-grid {
  display: grid;
  grid-template-columns: minmax(0, 0.9fr) minmax(360px, 1.1fr);
  gap: 24px;
}
.tpl-transition-card {
  min-height: 300px;
  padding: 26px;
  border: 1px solid var(--tpl-line);
  border-radius: var(--tpl-radius);
  background: var(--tpl-white);
}
.tpl-transition-card .tpl-transition-line { margin-bottom: 14px; }
.tpl-transition-line--label { width: 72px; height: 9px; margin-top: 4px; }
.tpl-transition-line--body { width: 92%; height: 15px; }
.tpl-transition-line--body-short { width: 58%; height: 15px; margin-bottom: 34px !important; }
.tpl-transition-card--map {
  position: relative;
  isolation: isolate;
  overflow: hidden;
  min-height: 300px;
  background: var(--tpl-placeholder);
}
.tpl-transition-error {
  max-width: 540px;
  margin: 0 auto;
  padding: 28px;
  border: 1px solid var(--tpl-line);
  border-radius: var(--tpl-radius);
  background: var(--tpl-white);
  text-align: center;
}
.tpl-transition-error p { margin: 0 0 10px; }
.tpl-transition-error .tpl-empty-title { margin-bottom: 8px; }
.tpl-transition-retry { margin-top: 12px; }

@media (max-width: 900px) {
  .tpl-transition-type-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .tpl-transition-brand-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .tpl-transition-detail-grid { grid-template-columns: 1fr; }
  .tpl-transition-card--map { min-height: 220px; }
}

@media (max-width: 720px) {
  .tpl-transition-hero { min-height: 204px; }
  /* Mobile detail actions stack and rating copy wraps, adding about 83px to the
     one-line-title Hero. Reserve that real footprint so the completed POI does
     not push the results band down after loading. */
  .tpl-transition-detail-hero-shell { min-height: 425px; }
  .tpl-transition-results,
  .tpl-transition-detail { min-height: 420px; }
  .tpl-transition-table-head { display: none; }
  .tpl-transition-table { border: 0; background: transparent; overflow: visible; }
  .tpl-transition-table-row {
    grid-template-columns: 1fr;
    gap: 11px;
    min-height: 148px;
    margin-bottom: 10px;
    padding: 16px;
    border: 1px solid var(--tpl-line);
    border-radius: var(--tpl-radius);
    background: var(--tpl-white);
  }
  .tpl-transition-line--chips { width: 72%; }
  .tpl-transition-type-grid,
  .tpl-transition-brand-grid { grid-template-columns: 1fr; }
  .tpl-transition-type-card { min-height: 82px; }
}

@media (prefers-reduced-motion: reduce) {
  .tpl-transition-line::after,
  .tpl-transition-disc::after,
  .tpl-transition-card--map::after { display: none; animation: none; }
  .tpl-answer a,
  .tpl-claim a,
  .tpl-appswitch a,
  .tpl-facts dd a,
  a.tpl-phone,
  a.tpl-poiname,
  .tpl-states a,
  .tpl-links a,
  .tpl-type-card,
  .tpl-page-link { transition: none; }
  .tpl-faq-icon::after { transition: none; }
}
