/**
 * Popular Hikes page — ranked hike cards with NPS permit panels.
 *
 * Visual language deliberately matches the discover page's .park-card family
 * (same surface, border, radius, hover lift) so the two pages read as one
 * product. Kept in its own file rather than appended to discover.css because
 * neither page loads the other's stylesheet.
 */

/* ------------------------------------------------------------------ */
/* Page width                                                           */
/* ------------------------------------------------------------------ */

/* This page mixes prose with a card grid, which want different measures. The
   other legal-style pages wrap everything in .legal-container (max-width
   46rem) — correct for a paragraph, but it squeezed three cards into ~213px
   each, which is where the skinny-column look came from.

   So the container runs at the site's full 1200px and the PROSE is what gets
   constrained, via .hikes-prose.

   That prose is centred on the page rather than pinned to the container's
   left edge. It used to be left-pinned, on the reasoning that sharing a left
   edge with the card grid stopped it reading as indented — but once the page
   gained a full-bleed photo band with a centred title above it, a left-hung
   column of text underneath read as though it had slipped off the page's
   axis. Symmetry with the title wins over alignment with the cards here; the
   cards still span the full 1200px and now simply sit wider than the prose,
   which reads as a deliberate measure rather than a misalignment. */
.hikes-container {
  /* Inherits max-width from .container (1200px). */
  display: block;
}

.hikes-prose {
  max-width: 46rem;
  margin-inline: auto;
  text-align: center;
}

/* ------------------------------------------------------------------ */
/* Intro band — Yellowstone photograph behind the page title            */
/*                                                                      */
/* Carries the shared photo-band primitives from components.css. That    */
/* band's contract is that the section owning it sets position:relative  */
/* and overflow:hidden, and lifts its inner wrapper above the frame —    */
/* the frame is absolutely positioned to fill this section and would     */
/* otherwise escape it.                                                  */
/* ------------------------------------------------------------------ */

.hikes-intro {
  position: relative;
  overflow: hidden;
  padding-block: clamp(var(--space-16), 10vw, var(--space-24));
  background-color: var(--color-bg);
  border-bottom: 1px solid var(--color-border-muted);
}

/* Matches the same step-down .discover-intro takes. Without it this band
   keeps its full-height padding at every width and reads noticeably taller
   than the Discover one — two bands built from the same primitives, one nav
   click apart, should not disagree about their own height. */
@media (min-width: 768px) {
  .hikes-intro {
    padding-block: clamp(var(--space-10), 6vw, var(--space-16));
  }
}

/* z-index lifts the title clear of .hero-photo-frame, which sits at 0. */
.hikes-intro-inner {
  position: relative;
  z-index: 1;
}

/* Centred, where index.html and discover.html hang their panels left. Those
   two pages set copy beside the panel; this one has none, so a left-hung
   panel under a full-bleed photograph reads as unbalanced rather than
   deliberate. Centring the panel is also what puts the page title on the
   page's own axis — it previously sat centred inside a left-aligned 46rem
   box, which is why it looked off to one side of everything below it. */
.hikes-intro-panel {
  max-width: 42rem;
  margin-inline: auto;
  text-align: center;
}

/* Contrast note, since Grand Prismatic is a bright photograph: the panel does
   this work, not the scrim. Measured against a pure-white worst case behind
   it, the title reads 10.61:1 and the --color-text-muted subtitle 5.61:1. */



/* ------------------------------------------------------------------ */
/* Ranked card grid                                                     */
/* ------------------------------------------------------------------ */

/* Stays an <ol> so the 1-10 ranking survives for screen readers and with CSS
   disabled; the list marker is suppressed because each card renders its own
   rank badge.

   Breakpoints are deliberately NOT the 768/1024 pair .parks-grid uses on the
   discover page. Going to three columns at 1024px would leave each card about
   304px wide, which is the cramped look this page was widened to fix. Holding
   two columns until 1100px keeps every card at 329px or wider (measured: 348px
   at 768px, 329px at the 1100px crossover, 363px at 1200px and above) — the
   third column only appears once there is room for it. */
.hike-grid {
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--space-6);
  margin: var(--space-8) 0 0;
  padding: 0;
  list-style: none;
  /* Cards size to their own content instead of stretching to the tallest in
     the row. Content length varies a lot here — a card with a written-out
     lottery is several times taller than one with just a description — and
     stretching left a large dead gap inside the short cards. Ragged bottoms
     read better than voids, and the image headers keep the tops aligned. */
  align-items: start;
}

@media (min-width: 700px) {
  .hike-grid {
    grid-template-columns: repeat(2, 1fr);
  }
}

@media (min-width: 1100px) {
  .hike-grid {
    grid-template-columns: repeat(3, 1fr);
    gap: var(--space-8);
  }
}

.hike-grid > li {
  display: flex;
  margin: 0;
}

/* ------------------------------------------------------------------ */
/* Card                                                                 */
/* ------------------------------------------------------------------ */

.hike-card {
  position: relative;
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
  width: 100%;
  padding: var(--space-6);
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-sm);
  transition:
    transform var(--duration-normal) var(--ease-out),
    border-color var(--duration-normal) var(--ease-out),
    box-shadow var(--duration-normal) var(--ease-out);
}

.hike-card:hover,
.hike-card:focus-within {
  transform: translateY(-3px);
  border-color: var(--color-accent-gold);
  box-shadow: var(--shadow-md);
}

/* Rank badge. Sits ON the image rather than hanging off the card's top edge —
   with a photograph up there, a badge floating outside the card read as a
   detached dot. z-index keeps it above the media. */
.hike-card-rank {
  position: absolute;
  z-index: 1;
  top: var(--space-4);
  left: var(--space-4);
  display: grid;
  place-items: center;
  width: 2rem;
  height: 2rem;
  font-family: var(--font-heading);
  font-size: var(--text-sm);
  font-weight: 700;
  color: var(--color-text-inverse);
  background: var(--color-accent-gold);
  border-radius: var(--radius-pill);
  box-shadow: var(--shadow-md);
}

/* ------------------------------------------------------------------ */
/* Card media header                                                    */
/* ------------------------------------------------------------------ */

/* Full-bleed image header. Negative margins pull it out to the card edges
   without needing an extra body wrapper around everything else, and the top
   corners are rounded to match the card so the crop looks intentional. */
.hike-card-media {
  position: relative;
  /* No bottom margin: the card is a flex column with its own gap, which is
     what should set the distance to the park label. */
  margin: calc(-1 * var(--space-6)) calc(-1 * var(--space-6)) 0;
  overflow: hidden;
  aspect-ratio: 16 / 10;
  background: var(--color-elevated);
  border-radius: var(--radius-lg) var(--radius-lg) 0 0;
}

.hike-card-img {
  display: block;
  width: 100%;
  height: 100%;
  /* Photographs range from portrait to panorama; cover crops them all to the
     same 16:10 box so a row of cards lines up. */
  object-fit: cover;
  /* Slight lift on hover, matched to the card's own transition. */
  transition: transform var(--duration-normal) var(--ease-out);
}

.hike-card:hover .hike-card-img,
.hike-card:focus-within .hike-card-img {
  transform: scale(1.04);
}

/* Gradient scrim along the top so the gold rank badge keeps its contrast over
   a bright sky, which several of these photographs have.
   Scoped away from the placeholder, which uses ::after for its far ridge: the
   two selectors would otherwise carry equal specificity and be decided by
   source order alone, so a rule reshuffle would silently swap them. */
.hike-card-media:not(.hike-card-media--placeholder)::after {
  content: '';
  position: absolute;
  inset: 0 0 auto 0;
  height: 40%;
  background: linear-gradient(to bottom, rgba(10, 26, 13, 0.55), transparent);
  pointer-events: none;
}

/* Used where NPS has no photograph of the route — Mount Washington and the
   Long Trail sit outside the NPS entirely. A designed placeholder keeps the
   grid rhythm rather than leaving a ragged gap, and is preferred over
   borrowing a photograph of somewhere the card is not about. */
.hike-card-media--placeholder {
  background:
    radial-gradient(120% 80% at 50% 100%, rgba(201, 168, 76, 0.18), transparent 70%),
    linear-gradient(160deg, var(--color-elevated), var(--color-bg));
}

/* Ridgeline silhouette, drawn with clip-path so it costs no request. Two
   layers at different opacities read as a near and a far ridge. An earlier
   attempt used crossed linear-gradients, which rendered as a literal X rather
   than anything mountain-shaped. */
.hike-card-media--placeholder::before,
.hike-card-media--placeholder::after {
  content: '';
  position: absolute;
  inset: 0;
  pointer-events: none;
}

.hike-card-media--placeholder::before {
  background: rgba(245, 240, 232, 0.05);
  clip-path: polygon(0% 100%, 14% 58%, 33% 80%, 55% 40%, 76% 68%, 100% 46%, 100% 100%);
}

.hike-card-media--placeholder::after {
  background: rgba(10, 26, 13, 0.55);
  clip-path: polygon(0% 100%, 26% 72%, 48% 88%, 70% 62%, 100% 84%, 100% 100%);
}

.hike-card-park {
  margin: var(--space-2) 0 0;
  font-size: var(--text-xs);
  font-weight: 600;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--color-accent-gold);
}

.hike-card-name {
  margin: 0;
  font-family: var(--font-heading);
  font-size: var(--text-lg);
  line-height: var(--leading-snug);
  color: var(--color-text-primary);
}

.hike-card-desc {
  margin: 0;
  font-size: var(--text-sm);
  line-height: var(--leading-normal);
  color: var(--color-text-muted);
}

/* ------------------------------------------------------------------ */
/* Curated permit block                                                 */
/* ------------------------------------------------------------------ */

/* Hand-written, source-checked permit guidance that ships in the markup. Sits
   above the live NPS panel and is visually weightier than it, because a
   verified lottery explanation is worth more to a hiker than a generic API
   field — the inset surface and gold rule are what signal that difference. */
.hike-card-curated {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
  padding: var(--space-4);
  background: rgba(0, 0, 0, 0.18);
  border-left: 3px solid var(--color-accent-gold);
  border-radius: var(--radius-sm);
}

.hike-curated-title {
  margin: 0;
  font-family: var(--font-heading);
  font-size: var(--text-sm);
  font-weight: 600;
  color: var(--color-text-primary);
}

.hike-curated-body {
  margin: 0;
  font-size: var(--text-xs);
  line-height: var(--leading-normal);
  color: var(--color-text-muted);
}

.hike-curated-links {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-3);
  margin: 0;
  padding: 0;
  list-style: none;
}

.hike-curated-links > li {
  margin: 0;
}


/* ------------------------------------------------------------------ */
/* Permit panel                                                         */
/* ------------------------------------------------------------------ */













.hike-permit-link {
  font-size: var(--text-xs);
  font-weight: 600;
  color: var(--color-accent-gold);
  text-decoration: underline;
  text-underline-offset: 2px;
}

.hike-permit-link:hover {
  color: var(--color-accent-gold-hover);
}


/* ------------------------------------------------------------------ */
/* Reduced motion                                                       */
/* ------------------------------------------------------------------ */

@media (prefers-reduced-motion: reduce) {
  .hike-card,
  .hike-card-img {
    transition: none;
  }

  .hike-card:hover,
  .hike-card:focus-within {
    transform: none;
  }

  .hike-card:hover .hike-card-img,
  .hike-card:focus-within .hike-card-img {
    transform: none;
  }
}


/* ------------------------------------------------------------------ */
/* Park cards — day hikes grouped by the park they belong to            */
/*                                                                      */
/* The day hikes used to be ten flat cards in a ranked grid. Two of the */
/* ten are in Zion and two in Yosemite, and nothing on the page said so */
/* — a visitor planning a trip to one park had to read all ten to find  */
/* out. These group them, so the page answers "what should I hike in    */
/* Zion" as directly as "what is the most popular hike in America".     */
/*                                                                      */
/* The ranking is not lost: each card keeps its number, and the cards   */
/* are ordered by their best-ranked hike, so Zion still leads.          */
/*                                                                      */
/* Same visual language as .hike-card deliberately — surface fill,      */
/* muted border, gold on hover — because this is the same kind of       */
/* object one level up, and the page should not read as two designs.    */
/* ------------------------------------------------------------------ */

.park-card-grid {
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--space-6);
  margin: var(--space-8) 0 0;
  padding: 0;
  list-style: none;
  /* Same reasoning as .hike-grid: a Zion card holding two written-out
     lotteries is far taller than a single-hike card, and stretching the
     short ones to match leaves voids inside them. */
  align-items: start;
}

@media (min-width: 700px) {
  .park-card-grid {
    grid-template-columns: repeat(2, 1fr);
  }
}

@media (min-width: 1100px) {
  .park-card-grid {
    grid-template-columns: repeat(3, 1fr);
    gap: var(--space-8);
  }
}

.park-card-grid > li {
  display: flex;
  margin: 0;
}

.park-card-hikes {
  display: flex;
  flex-direction: column;
  gap: var(--space-4);
  width: 100%;
  padding: var(--space-6);
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-sm);
  transition:
    border-color var(--duration-normal) var(--ease-out),
    box-shadow var(--duration-normal) var(--ease-out);
}

/* No translate on hover, unlike .hike-card. These cards expand in place
   when a hike is opened, and a card that lifts under the cursor while it
   is also growing downward reads as unstable. Border and shadow carry the
   affordance instead. */
.park-card-hikes:hover,
.park-card-hikes:focus-within {
  border-color: var(--color-accent-gold);
  box-shadow: var(--shadow-md);
}

.park-card-hikes-header {
  display: flex;
  flex-direction: column;
  gap: var(--space-1);
  padding-bottom: var(--space-4);
  border-bottom: 1px solid var(--color-border-muted);
}

.park-card-hikes-name {
  margin: 0;
  font-family: var(--font-heading);
  font-size: var(--text-lg);
  font-weight: 600;
  line-height: var(--leading-tight);
  color: var(--color-text-primary);
}

.park-card-hikes-meta {
  margin: 0;
  font-size: var(--text-sm);
  color: var(--color-text-muted);
}

.park-card-hikes-list {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
  margin: 0;
  padding: 0;
  list-style: none;
}

.park-card-hikes-list > li {
  margin: 0;
}


/* ------------------------------------------------------------------ */
/* Hike disclosure — one row per hike, opening to the full card         */
/*                                                                      */
/* A native <details>, for the same reasons the mobile nav is one: it    */
/* gets keyboard operation and the expanded/collapsed state exposed to   */
/* assistive tech for free, where a scripted toggle has to build both by */
/* hand. The page's own JS stays for what only JS can do — the live NPS  */
/* permit lookup — rather than for opening and closing a box.            */
/* ------------------------------------------------------------------ */

.hike-disclosure {
  border: 1px solid var(--color-border-muted);
  border-radius: var(--radius-md);
  background: var(--color-elevated);
}

.hike-disclosure[open] {
  border-color: var(--color-accent-green);
}

.hike-disclosure-summary {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  /* Comfortably past the 24px WCAG 2.5.8 minimum, and past 44px on a
     phone, which matters because this is the page's primary control. */
  min-height: 44px;
  padding: var(--space-2) var(--space-3);
  cursor: pointer;
  border-radius: var(--radius-md);
  transition: background-color var(--duration-fast) var(--ease-out);
  /* Suppress the default triangle in both engine families — the chevron
     below replaces it. Same two-property dance as .nav-mobile-toggle. */
  list-style: none;
}

.hike-disclosure-summary::-webkit-details-marker {
  display: none;
}

.hike-disclosure-summary::marker {
  content: "";
}

.hike-disclosure-summary:hover {
  background-color: rgba(201, 168, 76, 0.08);
}

.hike-disclosure-summary:focus-visible {
  outline: 2px solid var(--color-focus-ring);
  outline-offset: 2px;
}

.hike-disclosure-name {
  flex: 1;
  font-weight: 500;
  line-height: var(--leading-normal);
  color: var(--color-text-primary);
}

/* Chevron. A CSS triangle rather than an SVG or a glyph: one element, no
   request, and it rotates rather than swapping shapes. */
.hike-disclosure-summary::after {
  content: "";
  flex-shrink: 0;
  width: 0.5rem;
  height: 0.5rem;
  margin-right: var(--space-1);
  border-right: 2px solid var(--color-text-muted);
  border-bottom: 2px solid var(--color-text-muted);
  transform: rotate(45deg) translate(-2px, -2px);
  transition: transform var(--duration-fast) var(--ease-out);
}

.hike-disclosure[open] .hike-disclosure-summary::after {
  transform: rotate(-135deg) translate(-2px, -2px);
}

/* The card inside the disclosure. It was a standalone card in a grid and
   is now the body of a row, so it drops the frame it no longer needs —
   the disclosure supplies that — and keeps only its own spacing. */
.hike-disclosure .hike-card {
  gap: var(--space-3);
  padding: 0 var(--space-3) var(--space-3);
  background: transparent;
  border: 0;
  border-radius: 0;
  box-shadow: none;
}

/* .hike-card-media bleeds to the card edge with a negative margin sized to
   cancel .hike-card's own var(--space-6) padding exactly. That arithmetic
   stops being true here, where the padding above is 0 at the top and
   var(--space-3) at the sides — left alone, the photo pulled 24px UP over
   the summary row, hiding the rank badge and the hike's name, and hung 12px
   past the disclosure's rounded border on each side. Nothing clips it: the
   overflow:hidden on the media crops the <img> to its own box, not the box
   to its parent.

   So the bleed is re-cut to the padding that actually applies here: no top
   pull, sides matched to var(--space-3). */
.hike-disclosure .hike-card-media {
  margin: 0 calc(-1 * var(--space-3)) 0;
  /* The disclosure supplies the rounded frame now, and this sits inside it
     rather than forming its top edge, so it rounds on all four corners. */
  border-radius: var(--radius-sm);
}

.hike-disclosure .hike-card:hover,
.hike-disclosure .hike-card:focus-within {
  transform: none;
  border: 0;
  box-shadow: none;
}

@media (prefers-reduced-motion: reduce) {
  .hike-disclosure-summary,
  .hike-disclosure-summary::after {
    transition: none;
  }
}

/* Deep-link landing offset. The site header is sticky at 68px, and nothing
   sets scroll-padding globally, so an in-page anchor lands underneath it.
   That matters more here than elsewhere: the page's JSON-LD publishes a deep
   link per hike, so those URLs are what search results hand people, and
   hikes.js scrolls to the target after opening its disclosure.

   Scoped to these targets rather than fixed globally with
   `html { scroll-padding-top }` — the header overlap is a pre-existing,
   site-wide behaviour and correcting it everywhere belongs in its own
   change, not smuggled into this one. */
.hike-card[id],
.park-card-hikes[id] {
  scroll-margin-top: calc(68px + var(--space-4));
}

/* Print. A closed <details> prints closed, which on this page would put eight
   park headers and ten one-line summaries on paper and none of the permit
   detail — worse than what the flat grid printed, and printing a hike's
   lottery rules to carry offline is a plausible reason to print this page at
   all. Force every hike open on paper, and drop the chevron, which is an
   affordance for something you cannot click on a sheet of paper. */
@media print {
  .hike-disclosure:not([open]) > *:not(summary) {
    display: block;
  }

  .hike-disclosure-summary::after {
    display: none;
  }
}

/* Distance line on the leaner hikes. Sits above the description as a small
   factual label rather than reading as prose — it is the one number the
   source document gives for these routes, so it earns its own line. */
.hike-card-meta {
  margin: 0;
  font-family: var(--font-heading);
  font-size: var(--text-xs);
  letter-spacing: 0.02em;
  /* The lighter gold, not --color-accent-gold. Measured on the disclosure's
     --color-elevated fill, the base gold is 4.45:1 — under the 4.5:1 WCAG
     1.4.3 asks of 12px text, and this label now appears on ~141 cards, so a
     borderline value would be wrong at scale. The hover tone is 5.61:1. */
  color: var(--color-accent-gold-hover);
}


/* Link to the park's profile on Discover. Sits at the foot of every park
   card, after the hike list.

   This replaced a per-hike API layer that fetched entrance fees, hours and
   permit portals from NPS and injected them into each card. Discover already
   fetches exactly that, once per park, and presents it in one place — a
   second copy on this page meant two things to keep in step and about forty
   API requests per page view. margin-top:auto pins it to the bottom edge so
   the link sits in the same place on every card regardless of how many hikes
   the card holds. */
.park-card-hikes-link {
  margin: auto 0 0;
  padding-top: var(--space-3);
  border-top: 1px solid var(--color-border-muted);
  font-size: var(--text-sm);
}

.park-card-hikes-link a {
  /* The lighter gold: measured 5.61:1 on the card's surface fill, where the
     base gold is 4.45:1 and misses the 4.5:1 WCAG 1.4.3 asks of body text. */
  color: var(--color-accent-gold-hover);
  font-weight: 500;
  text-decoration: none;
  /* A bare inline link rendered 17px tall here. It stands alone in its own
     paragraph rather than sitting inside a sentence, so the "inline in a
     block of text" exception to WCAG 2.5.8 does not cover it, and it is the
     card's only outbound action. inline-block plus padding takes it past the
     24px minimum, in line with the 44px targets used elsewhere on the page. */
  display: inline-block;
  min-height: 24px;
  padding: var(--space-2) 0;
}

.park-card-hikes-link a:hover {
  text-decoration: underline;
  text-underline-offset: 3px;
}
