/* Texas Fuego Trailer Rentals: the Night Haul ride (home page only) and the price card it hands off to.
   js/ride.js reads: #ride, .ride-stage, .ride-canvas, .step, .ride-dots (and its <i>), .ride-ui, and toggles
   .is-list / .is-pinned on #ride, .is-on on .step and dots, .is-done on dots, .is-end on .ride-ui, .step-still canvases
   (Reduce Motion), .no-cap on #ride while no caption shows, and .is-pinned on #ride + .ride-pinned on <html> while the
   stage is pinned. It reads the CSS variable --ride-red (base.css) for the red bloom around the taillight at the end.
   The pinned mode is keyed on html.ride-on (set in the page head, removed if js/ride.js never runs) and on the media
   query "no Reduce Motion, at least 340 px tall, and not a short (<= 500 px), narrow (< 480 px) landscape window"
   (written out as three comma-joined queries): the exact opposite of LIST_QUERY in js/ride.js. Keep the two in step.
   Scroll layout (pinned): #ride is 11.3 screens tall = 0.5 lead-in (the opening screen lifts away) + 9 story + 0.8 tail
   + 1 stage; #price has a top margin of -1 stage, so it slides up OVER the still-pinned last frame (the taillight
   close-up) during the tail, and the page never sits on a plain red screen (Gavin, 2026-11-11). #how follows it and
   covers the rest of the stage (home.css), so #price keeps its natural height (no dead gap under the card).
   The stage is 100svh (the screen with the browser's toolbars showing): on iPhone Safari the scene is then framed for
   what is actually visible, the same box the opening screen's text is laid out in; when the toolbar collapses, the
   thin strip under the stage is the ride's night background behind the bottom bar. */

/* ---------- the ride ----------
   Without JS (or if the ride can't start) it's a plain, readable list. With JS and motion allowed it becomes a tall
   section with a sticky, viewport-sized stage; js/ride.js draws on the canvas from the scroll position. */
.ride { position: relative; background: var(--night); }
.ride-stage { position: relative; }
.ride-canvas, .ride-call { display: none; }
.ride-ui { max-width: 760px; margin: 0 auto; padding: clamp(40px, 8vw, 80px) var(--gut); }
.ride-h {
  font-weight: 900; text-transform: uppercase; font-size: clamp(2.2rem, 7vw, 3.4rem); margin-bottom: 28px;
  text-shadow: 0 0 24px rgba(225, 20, 28, 0.4);
}
.ride-steps { list-style: none; margin: 0; padding: 0; display: grid; gap: 28px; }
.step { display: grid; grid-template-columns: auto minmax(0, 1fr); gap: 6px 18px; align-items: start; }
.step h3, .step p { overflow-wrap: break-word; } /* 200% text at 320 px: a long word can't push the list sideways */
.step-n {
  font-family: var(--head); font-weight: 900; font-size: clamp(3rem, 9vw, 4.4rem); line-height: 0.85;
  color: var(--fire); text-shadow: 0 0 22px rgba(225, 20, 28, 0.55);
  font-variant-numeric: tabular-nums;
}
.step h3 { font-weight: 850; text-transform: uppercase; font-size: clamp(1.6rem, 4.6vw, 2.2rem); margin: 2px 0 8px; }
.step p { color: var(--steel); max-width: 40ch; }
.step[tabindex="-1"]:focus { outline: none; } /* the scroll cue's landing point (js/site.js), not a control */
.ride h2, .ride h3, .price h2 { text-wrap: wrap; line-height: 0.98; } /* base.css balances headings; the ride's captions keep their own breaks */
.step-still { grid-column: 1 / -1; width: 100%; height: auto; border-radius: 12px; margin-bottom: 6px;
  background: linear-gradient(180deg, #060608 0%, #2c0507 45%, #c8141e 72%, #0b0a0e 78%, #060608 100%);
  box-shadow: 0 0 0 1px rgba(244, 244, 246, 0.08), 0 20px 50px -24px rgba(225, 20, 28, 0.6); }
.ride-dots { display: none; }

/* the pinned ride: only with JS, when motion is OK and the screen is tall enough for a caption (= not LIST_QUERY) */
@media (prefers-reduced-motion: no-preference) and (min-height: 340px) and (min-width: 480px),
  (prefers-reduced-motion: no-preference) and (min-height: 500.02px),
  (prefers-reduced-motion: no-preference) and (min-height: 340px) and (orientation: portrait) {
  .ride-on .ride:not(.is-list) { height: 1100vh; height: 1100lvh; }
  .ride-on .ride:not(.is-list) .ride-stage {
    position: sticky; top: 0; height: 100vh; height: 100svh; overflow: hidden;
    /* shows until the first frame is drawn (same night sky the canvas paints) */
    background: linear-gradient(180deg, #060608 0%, #1a0406 38%, #5a0a0e 64%, #b8261a 74%, #0b0a0e 78%, #060608 100%);
  }
  .ride-on .ride:not(.is-list) .ride-canvas {
    display: block; position: absolute; inset: 0; width: 100%; height: 100%;
  }
  .ride-on .ride:not(.is-list) .ride-ui {
    position: absolute; z-index: 2; left: 0; top: 0; margin: 0; max-width: none;
    padding: calc(14px + env(safe-area-inset-top)) var(--gut) 0;
    width: 100%; pointer-events: none;
  }
  .ride-on .ride:not(.is-list) .ride-h {
    position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); clip-path: inset(50%);
    white-space: nowrap; margin: -1px; padding: 0;
  }
  /* only the caption showing takes up room (the others sit on top of it, out of the flow, while they fade), so the
     progress dots always sit right under the caption you are reading */
  .ride-on .ride:not(.is-list) .ride-steps { display: grid; gap: 0; position: relative; }
  .ride-on .ride:not(.is-list) .step:not(.is-on) { position: absolute; left: 0; right: 0; top: 0; }
  .ride-on .ride:not(.is-list) .step {
    grid-area: 1 / 1; align-self: start;
    grid-template-columns: auto minmax(0, 1fr); /* big text sizes (200%) wrap inside the screen */
    padding: 14px 16px 16px;
    border-radius: 14px;
    /* strong enough to read over the landfill floodlights (step 04) */
    background: linear-gradient(180deg, rgba(6, 6, 8, 0.8), rgba(6, 6, 8, 0.64));
    box-shadow: 0 0 0 1px rgba(244, 244, 246, 0.07), 0 18px 40px -20px rgba(0, 0, 0, 0.9);
    opacity: 0; transform: translate3d(0, 14px, 0);
    transition: opacity 0.15s ease, transform 0.15s ease;
  }
  .ride-on .ride:not(.is-list) .step.is-on {
    opacity: 1; transform: none;
    transition: opacity 0.35s ease 0.15s, transform 0.45s cubic-bezier(0.2, 0.7, 0.2, 1) 0.15s;
  }
  .ride-on .ride:not(.is-list) .step-n {
    font-size: 3.1rem; width: 1.06em; /* the same width for 01..05, so the text never shifts between captions */
    color: var(--flare); -webkit-text-stroke: 1.5px rgba(0, 0, 0, 0.75); paint-order: stroke fill;
    text-shadow: 0 2px 0 #000, 0 0 18px rgba(225, 20, 28, 0.6);
  }
  .ride-on .ride:not(.is-list) .step h3 {
    font-size: min(1.65rem, 7.4vw); margin: 0 0 6px; text-shadow: 0 2px 8px #000;
    text-wrap: balance; /* no lone word on its own line */
    overflow-wrap: anywhere;
  }
  .ride-on .ride:not(.is-list) .step p { font-size: min(0.98rem, 4.6vw); line-height: 1.42; color: #e6e6ea; text-shadow: 0 1px 6px #000; }
  .ride-on .ride:not(.is-list) .ride-dots {
    display: flex; gap: 8px; width: max-content; margin: 10px 0 0 8px; padding: 6px 10px;
    border-radius: 999px; background: rgba(6, 6, 8, 0.85); box-shadow: 0 0 0 1px rgba(244, 244, 246, 0.06);
  }
  .ride-on .ride:not(.is-list) .ride-dots { transition: opacity 0.3s ease; }
  /* the dots fade while no caption shows (the drives between stops, and the end) */
  .ride-on .ride.no-cap:not(.is-list) .ride-dots, .ride-on .ride:not(.is-list) .is-end .ride-dots { opacity: 0; }
  /* once #price covers the stage (not pinned any more) no caption shows through its see-through top, whatever state a
     jump past the ride left the captions in (js/ride.js also keeps them in step) */
  .ride-on .ride:not(.is-list):not(.is-pinned) .ride-ui { opacity: 0; }
  .ride-dots i {
    width: 8px; height: 8px; border-radius: 50%; background: rgba(244, 244, 246, 0.28);
    transition: background-color 0.3s ease, transform 0.3s ease, box-shadow 0.3s ease;
  }
  .ride-dots i.is-on { background: var(--fire); transform: scale(1.35); box-shadow: 0 0 10px rgba(255, 42, 42, 0.8); }
  .ride-dots i.is-done { background: rgba(244, 244, 246, 0.7); }

  @media (min-width: 768px) {
    .ride-on .ride:not(.is-list) .ride-ui { padding: clamp(28px, 6vh, 64px) clamp(24px, 4.5vw, 72px) 0; width: auto; }
    .ride-on .ride:not(.is-list) .ride-steps { width: min(30rem, 58vw); }
    .ride-on .ride:not(.is-list) .step { padding: 18px 22px 20px; gap: 6px 20px; }
    .ride-on .ride:not(.is-list) .step-n { font-size: 4.3rem; }
    .ride-on .ride:not(.is-list) .step h3 { font-size: min(2.15rem, 5.4vw); }
    .ride-on .ride:not(.is-list) .step p { font-size: 1.05rem; }
    .ride-on .ride:not(.is-list) .ride-dots { margin-left: 12px; }
  }

  /* Call stays on screen through the whole ride (desktop; phones have the bottom bar) */
  .ride-on .ride:not(.is-list) .ride-call {
    display: inline-flex; position: absolute; z-index: 3;
    top: clamp(28px, 6vh, 64px); right: clamp(24px, 4.5vw, 72px);
    background: rgba(6, 6, 8, 0.78); color: var(--chrome);
    border-color: rgba(244, 244, 246, 0.35);
    box-shadow: 0 10px 30px -12px rgba(0, 0, 0, 0.9);
    opacity: 0; visibility: hidden; transition: opacity 0.25s ease, visibility 0s linear 0.25s;
  }
  .ride-on .ride.is-pinned:not(.is-list) .ride-call { opacity: 1; visibility: visible; transition: opacity 0.25s ease; }
  .ride-on .ride:not(.is-list) .ride-call .ico { color: var(--flare); }
  .ride-on .ride:not(.is-list) .ride-call:hover { border-color: var(--chrome); background: rgba(6, 6, 8, 0.92); }

  /* phones on their side (short screens): compact captions so the scene still shows */
  @media (max-height: 500px) and (orientation: landscape) {
    .ride-on .ride:not(.is-list) .ride-ui { padding: calc(10px + env(safe-area-inset-top)) var(--gut) 0; }
    .ride-on .ride:not(.is-list) .ride-steps { width: min(22rem, 42vw); }
    .ride-on .ride:not(.is-list) .step { padding: 10px 14px 12px; gap: 4px 12px; }
    .ride-on .ride:not(.is-list) .step-n { font-size: 2.2rem; }
    .ride-on .ride:not(.is-list) .step h3 { font-size: 1.25rem; margin-bottom: 4px; }
    .ride-on .ride:not(.is-list) .step p { font-size: 0.88rem; line-height: 1.35; }
    .ride-on .ride:not(.is-list) .ride-dots { margin-top: 6px; }
  }
  /* narrow screens: captions use the full width */
  @media (max-width: 559.98px) {
    .ride-on .ride:not(.is-list) .ride-steps { width: auto; }
  }

  /* phones on their side: the bottom bar would eat a third of the scene, so it steps aside while the ride is pinned
     and a compact Call pill takes the top right corner (clear of the notch / home indicator) */
  @media (max-height: 500px) and (pointer: coarse) {
    .ride-pinned .mbar { display: none; }
    .ride-on .ride:not(.is-list) .ride-call {
      top: calc(8px + env(safe-area-inset-top)); right: calc(10px + env(safe-area-inset-right));
      min-height: 44px; padding: 0.4em 0.9em; font-size: 0.95rem;
    }
  }
}
/* portrait phones and narrow windows: the bottom bar carries Call, so the ride's own Call pill stays hidden */
@media (max-width: 767.98px) and (min-height: 501px), (max-width: 767.98px) and (pointer: fine) {
  .ride-on .ride:not(.is-list) .ride-call { display: none; }
}

/* ---------- price card ----------
   List mode / no JS / Reduce Motion: a plain night section with a soft red glow (no red band).
   Pinned ride: #price slides up over the ride's last frame (the taillight close-up, dark at the edges with the red
   bloom around the lamp). Its top is see-through and darkens into night, and the red light catches the card's top
   edge, so the hand-off has no seam and never a flat red screen (Gavin, 2026-11-11: "make it quicker or shorter"). */
.price {
  position: relative;
  background:
    radial-gradient(60% 45% at 50% 42%, rgba(225, 20, 28, 0.22), transparent 70%),
    radial-gradient(70% 220px at 50% 0, rgba(122, 10, 14, 0.35), transparent 75%),
    var(--night);
  padding: clamp(56px, 9vw, 96px) var(--gut) clamp(60px, 10vw, 110px);
}
@media (prefers-reduced-motion: no-preference) and (min-height: 340px) and (min-width: 480px),
  (prefers-reduced-motion: no-preference) and (min-height: 500.02px),
  (prefers-reduced-motion: no-preference) and (min-height: 340px) and (orientation: portrait) {
  .ride-on .ride:not(.is-list) + .price {
    margin-top: -100vh; margin-top: -100svh; z-index: 4; /* (the stage's height) */
    /* natural height: #how follows with the same z-index and an opaque background (home.css), so together they cover
       the stage when it stops being pinned, without a screen-tall dead gap under the card on big screens */
    padding-bottom: clamp(48px, 7vw, 80px);
    background:
      radial-gradient(60% 45% at 50% 42%, rgba(225, 20, 28, 0.22), transparent 70%),
      linear-gradient(180deg, rgba(6, 6, 8, 0) 0, rgba(6, 6, 8, 0.55) 8vh, rgba(6, 6, 8, 0.9) 18vh, var(--night) 30vh);
  }
  /* the red light the taillight throws on the card: it fades in from nothing at the section's top edge (a radial at full
     strength right at the edge drew a hard, ruled line across the lamp's bloom as #price slid up) */
  .ride-on .ride:not(.is-list) + .price::before {
    content: ""; position: absolute; left: 0; right: 0; top: 0; height: 34vh; z-index: 0; pointer-events: none;
    background: radial-gradient(80% 30vh at 50% 0, rgba(225, 20, 28, 0.28), transparent 72%);
    -webkit-mask-image: linear-gradient(180deg, transparent 0, rgba(0, 0, 0, 0.35) 4vh, #000 12vh);
    mask-image: linear-gradient(180deg, transparent 0, rgba(0, 0, 0, 0.35) 4vh, #000 12vh);
  }
  .ride-on .ride:not(.is-list) + .price .price-card {
    border-top-color: rgba(255, 90, 70, 0.55);
    box-shadow: 0 40px 90px -40px rgba(0, 0, 0, 0.9), 0 -14px 60px -18px rgba(255, 42, 42, 0.7), 0 0 60px -20px rgba(255, 42, 42, 0.45);
  }
}
.price-card {
  position: relative;
  max-width: 640px; margin: 0 auto; text-align: center;
  background: linear-gradient(180deg, rgba(6, 6, 8, 0.86), rgba(11, 10, 14, 0.95));
  border: 1px solid rgba(244, 244, 246, 0.12);
  border-radius: 20px;
  padding: clamp(28px, 5vw, 48px) clamp(20px, 5vw, 48px);
  box-shadow: 0 40px 90px -40px rgba(0, 0, 0, 0.9), 0 0 60px -20px rgba(255, 42, 42, 0.45);
}
.price-big {
  font-weight: 900; text-transform: uppercase; font-size: clamp(2.2rem, 7vw, 3.2rem); color: var(--steel);
}
.price-big .num {
  display: block; font-size: clamp(5rem, 22vw, 8.5rem); line-height: 0.9; color: var(--chrome);
  text-shadow: 0 0 34px rgba(225, 20, 28, 0.6);
}
.deal {
  display: inline-flex; flex-wrap: wrap; justify-content: center; gap: 0.35em;
  margin: 18px 0 20px; padding: 10px 18px; border-radius: 999px;
  background: rgba(225, 20, 28, 0.16); border: 1px solid rgba(255, 42, 42, 0.55);
  font-weight: 650;
}
.deal strong { color: #fff; }
.facts { list-style: none; padding: 0; margin: 0 0 26px; color: var(--steel); display: grid; gap: 6px; }
.facts li::before { content: "\2605"; color: var(--fire); margin-right: 0.5em; }
