/* Learn with me (/courses): the route page, its own look among the site's pages
   (tymaxey-llc D319 phone, D321 desktop, D322 the quiet accent). Tokens from /style.css. */


/* One frame: the header, the hero, the route, and the foot share the site's column (tymaxey-llc D327). */
body.route-page { max-width: none; padding: 0; }
.route-page .site-header, .route-page .site-footer { width: min(66ch, 100% - 2 * var(--s3)); max-width: none; margin-left: auto; margin-right: auto; }
.route-page .site-header { margin-top: var(--s4); margin-bottom: 0; }
.route-page .site-footer { margin-top: 0; margin-bottom: var(--s5); }

.r-inner { position: relative; z-index: 1; width: min(66ch, 100% - 2 * var(--s3)); margin: 0 auto; box-sizing: border-box; }

/* The hero */
/* The hero starts s5 under the nav's rule, as every page's h1 does; the lockup is the page's h1 (D327 as amended) */
.r-hero { position: relative; padding: var(--s5) 0 160px; box-sizing: border-box; }
.r-hero .r-inner { display: flex; flex-direction: column; gap: 40px; }
.r-lockup { display: flex; align-items: center; gap: 16px; margin: 0; font-weight: 600; font-size: 1.75rem; line-height: 1; color: var(--ink-5); letter-spacing: -0.01em; }
.r-mark { width: 56px; height: 56px; flex: none; }
.r-mark-chevron { fill: none; stroke: var(--ink-5); stroke-width: 14; stroke-linecap: square; }
.r-mark-bar { fill: var(--accent); }
.r-headline { margin: 0; font-weight: 600; font-size: clamp(2.5rem, 6vw, 5rem); line-height: 1.05; color: var(--ink-5); }
.r-sentence { margin: 0; font-size: 1.25rem; max-width: 46ch; }
/* Orientation's first step: under the headline, in the page's own type, not a strip or a box (tymaxey-llc D396) */
.r-first { display: flex; flex-wrap: wrap; align-items: baseline; gap: var(--s2) var(--s3); }
/* "free" in the green token, as the Free badge (Ty 2026-10-15) */
.r-first .free { color: var(--green); }

/* The offer element: top and foot only (D319 item 2) */
.offer { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--s3); }
.offer-box { display: flex; flex-direction: column; align-items: flex-start; gap: var(--s2); padding: var(--s3); border: 1px solid var(--ink-2); border-radius: var(--radius); }
.offer-box p { margin: 0; }
.offer-label, .r-kicker, .r-facts, .r-label { font-family: var(--mono); font-size: 0.75rem; letter-spacing: 0.05em; text-transform: uppercase; color: var(--ink-3); }
.offer-price { font-size: 1.5rem; font-weight: 600; line-height: 1.25; color: var(--ink-5); }
.offer-text { flex: 1; }
.offer-box .button { margin-top: var(--s2); }
/* At the top the offers' calls are links, so Orientation's step is the one button above the route; the foot keeps buttons (tymaxey-llc D398) */
.offer-box .offer-link { display: inline-block; min-height: 24px; padding-block: 2px; margin-top: var(--s2); }
.offer-link:hover .cta-arrow, .offer-link:focus-visible .cta-arrow { transform: translateX(0.2em); }

/* The route: one dashed path in the patch's column, in the quiet accent (D321, D322) */
.r-stop { position: relative; max-width: 66ch; margin: 0 auto; box-sizing: border-box; display: grid; grid-template-rows: 96px auto; align-items: start; }
.r-stop.r-switch { grid-template-rows: 320px auto; }
/* the patch's column is the patch's own width; the copy takes the rest, s5 off it (D327 as amended) */
.r-stop.left { grid-template-columns: 200px minmax(0, 1fr); }
.r-stop.right { grid-template-columns: minmax(0, 1fr) 200px; }
.r-band { grid-column: 1 / -1; grid-row: 1; display: block; width: 100%; height: 100%; }
.r-band path { fill: none; stroke: var(--accent-quiet); stroke-width: 7px; stroke-dasharray: 18 12; }
.r-vline { position: absolute; z-index: 0; width: 7px; transform: translateX(-50%); background: repeating-linear-gradient(to bottom, var(--accent-quiet) 0 18px, transparent 18px 30px); pointer-events: none; }
.r-x22 { left: 100px; }
.r-x78 { left: calc(100% - 100px); }
.r-stop .r-vline { top: 96px; bottom: 0; }
.r-stop.r-switch .r-vline { top: 320px; }
/* the hero's line sits on the column's path, 100px into the column, not of the window (D327) */
.r-hero-line { bottom: 0; height: 120px; left: calc((100% - min(66ch, 100% - 2 * var(--s3))) / 2 + 100px); }
.r-stop.left .r-patchcell { grid-column: 1; grid-row: 2; }
.r-stop.left .r-text { grid-column: 2; grid-row: 2; padding: 0 0 var(--s4) var(--s5); }
.r-stop.right .r-text { grid-column: 1; grid-row: 2; padding: 0 var(--s5) var(--s4) 0; }
.r-stop.right .r-patchcell { grid-column: 2; grid-row: 2; }
.r-patchcell { position: relative; z-index: 1; align-self: stretch; display: flex; justify-content: center; align-items: flex-start; padding-bottom: var(--s4); }
.r-sticky { position: sticky; top: 12vh; }
.r-patch { display: block; width: min(28vh, 200px); height: auto; aspect-ratio: 1 / 1; }
.r-patch.cover-light, [data-mode="light"] .r-patch.cover-dark { display: none; }
[data-mode="light"] .r-patch.cover-light { display: block; }
.r-leg { display: none; }

.r-text { position: relative; z-index: 1; }
.r-kicker { margin: 0; }
.r-name { margin: var(--s2) 0 var(--s3); font-size: clamp(2.5rem, 4.5vw, 4rem); line-height: 1; letter-spacing: -0.01em; }
.r-line { margin: 0 0 var(--s3); font-size: 1.3rem; line-height: 1.4; color: var(--ink-5); max-width: 30ch; }
.r-facts { margin: 0 0 var(--s3); }
.r-more { max-width: 52ch; margin-top: var(--s3); padding-top: var(--s3); border-top: 1px solid var(--ink-2); }
.r-more p { margin: 0 0 20px; }
.r-more p.r-label { margin: 0 0 var(--s1); }
.r-more ul, .r-more ol { margin: 0 0 20px; }


/* The landing: Landing's patch touches down on the closing cards (D321 item 3) */
/* the route is Landing's runway: it ends inside the patch's tip, which rests at its end */
.r-stop.r-last .r-vline { bottom: calc(0.1501 * min(28vh, 200px) + 6px); }
.r-stop.r-last .r-patchcell { padding-bottom: 0; }
/* the patch's artwork ends 15% of its height above its box; the closing cards sit 24px below the tip, the
   patch at rest at the route's end (Ty: "Ending on the runway (the dashed line). It's probably 20-30px from
   the card."), and Landing's copy keeps clear of them */
.r-stop.r-last .r-text { padding-bottom: calc(0.1501 * min(28vh, 200px) - 24px + var(--s4)); }
/* the landing's scroll room, less what the site footer below it already gives (about 160px) */
.r-close { position: relative; z-index: 2; margin-top: calc(24px - 0.1501 * min(28vh, 200px)); min-height: calc(88vh - min(28vh, 200px) - 104px); padding-bottom: var(--s4); box-sizing: border-box; }
/* the close's question, in the hero's sentence style, above the offer element */
.r-close-q { margin-bottom: var(--s3); }
.r-close .free { color: var(--green); }
.r-foot { list-style: none; display: flex; flex-wrap: wrap; align-items: center; gap: var(--s2) var(--s4); margin: var(--s3) 0 0; padding: var(--s3) 0 0; border-top: 1px solid var(--ink-2); }
.r-foot li { margin: 0; }
.r-top { margin-left: auto !important; }
/* Back to top takes the Tools cards' arrow link: the body face, whose Pi file draws the arrow; the arrow rises on hover */
.r-top a { display: inline-block; padding: var(--s2) var(--s1); margin: calc(-1 * var(--s2)) calc(-1 * var(--s1)); }
.r-top a.cta:hover .cta-arrow, .r-top a.cta:focus-visible .cta-arrow { transform: translateY(-0.2em); }

/* The phone (D319): one column, a dashed leg into each centred patch */
@media (max-width: 720px) {
  .r-hero { padding: var(--s5) 0 var(--s4); }
  .offer, .r-close .offer { grid-template-columns: 1fr; }
  .r-stop, .r-stop.left, .r-stop.right, .r-stop.r-switch { min-height: 0; grid-template-columns: 1fr; grid-template-rows: none; }
  .r-stop.left .r-patchcell, .r-stop.right .r-patchcell, .r-stop.left .r-text, .r-stop.right .r-text { grid-column: 1; grid-row: auto; }
  .r-band, .r-vline { display: none; }
  .r-patchcell { flex-direction: column; align-items: center; align-self: start; padding: 0 var(--s3); }
  .r-sticky { position: static; }
  .r-leg { display: block; width: 5px; height: 96px; margin-bottom: var(--s3); background: repeating-linear-gradient(to bottom, var(--accent-quiet) 0 18px, transparent 18px 30px); }
  .r-close-leg { margin: 0 auto var(--s3); }
  .r-patch { width: 224px; }
  .r-stop.left .r-text, .r-stop.right .r-text, .r-stop.r-last .r-text { padding: var(--s3) var(--s3) 64px; }
  .r-close { margin-top: 0; min-height: 0; padding-bottom: var(--s4); }
}

/* The patches that move are inline so their parts can: the colours from the theme, one copy for both modes (D340) */
svg.r-patch .p-field { fill: var(--ink-0); }
svg.r-patch .p-details { fill: var(--ink-3); }
svg.r-patch .p-ink { fill: var(--ink-5); }
svg.r-patch .p-accent { fill: var(--accent); }
/* imagery only, one value in every mode: the blues and Runway's runway (tymaxey-llc D376, D377) */
svg.r-patch .p-mass { fill: var(--patch-blue); }
svg.r-patch .p-mass-lit { fill: var(--patch-blue-lit); }
svg.r-patch .p-mass-shade { fill: var(--patch-blue-shade); }
svg.r-patch .p-surface { fill: var(--patch-asphalt); }
svg.r-patch .p-markings { fill: var(--patch-marking); }
.p7-leg { transform-box: fill-box; transform-origin: 50% 0; }
/* the landmark sits where the patch touches down; its trip up the window is the patch's timeline */
.r-landmark { position: absolute; left: 0; bottom: 0; width: 1px; height: 0; }
/* and the top of the patch's column: its trip from the window's foot to where the patch sticks is the sun's */
.r-landmark-top { position: absolute; left: 0; top: 0; width: 1px; height: 0; }

/* On a desktop, three stages: the sun rising as the patch comes into view; then, over the last half window
   before touchdown, the gear up, half down, down, and the centreline stripes a third of a stripe nearer each stage. Stills without support or with reduced motion. */
@supports (animation-timeline: view()) {
  @media (min-width: 640px) and (prefers-reduced-motion: no-preference) {
    .r-last { timeline-scope: --p7, --p7sun; }
    .r-landmark { view-timeline: --p7 block; }
    .r-last .r-landmark-top { view-timeline: --p7sun block; }
    .p7-sun { animation: p7-sun linear both; animation-timeline: --p7sun; animation-range: cover 0% cover 88%; transform-box: view-box; }
    .p7-leg, .p7-dashes { animation: linear both; animation-timeline: --p7; animation-range: cover calc(38% - min(28vh, 200px)) cover calc(88% - min(28vh, 200px)); }
    .p7-leg { animation-name: p7-gear; }
    .p7-dashes { animation-name: p7-stripes; }
  }
}
/* the sun climbs r · sin 15° (76 of its 295) as the patch comes into view: the plane is descending */
@keyframes p7-sun {
  0%, 33.3% { transform: translateY(76px); }
  33.4%, 66.6% { transform: translateY(38px); }
  66.7%, 100% { transform: translateY(0); }
}
@keyframes p7-gear {
  0%, 33.3% { transform: scaleY(0); }
  33.4%, 66.6% { transform: scaleY(0.55); }
  66.7%, 100% { transform: scaleY(1); }
}
@keyframes p7-stripes {
  0%, 33.3% { transform: translateY(0); }
  33.4%, 66.6% { transform: translateY(17.33px); }
  66.7%, 100% { transform: translateY(34.67px); }
}
.r-patch-7 .p7-halo { stroke: var(--ink-0); }

/* Patches 1 to 6 change in place, as Landing's gear does: stage 1 as the patch arrives, then stages 2 and 3 over the
   half window after it sticks (Ty: "yes that what I was picturing"). The landmark sits half a window down the patch's
   column, so it is at 62% of the window when the patch sticks and at 12% half a window later. */
.r-landmark-stuck { position: absolute; left: 0; top: 50vh; width: 1px; height: 0; }

/* Runway's stars rise from behind the mountains: the centre star just above the peak, then the upper pair clear of
   the ridge, then all five as drawn (Ty: "they rise up!"). Each star climbs its own distance; the runway is untouched. */
@supports (animation-timeline: view()) {
  @media (min-width: 640px) and (prefers-reduced-motion: no-preference) {
    .r-stop:not(.r-last) { timeline-scope: --stuck; }
    .r-landmark-stuck { view-timeline: --stuck block; }
    .p1-star { animation: linear both; animation-timeline: --stuck; animation-range: cover 38% cover 88%; }
    .p1-star-1 { animation-name: p1-star-1; }
    .p1-star-2 { animation-name: p1-star-2; }
    .p1-star-3 { animation-name: p1-star-3; }
    .p1-star-4 { animation-name: p1-star-4; }
    .p1-star-5 { animation-name: p1-star-5; }
  }
}
@keyframes p1-star-1 { 0%, 33.3% { transform: translateY(150px); } 33.4%, 66.6% { transform: translateY(75px); } 66.7%, 100% { transform: translateY(0); } }
@keyframes p1-star-2 { 0%, 33.3% { transform: translateY(222px); } 33.4%, 66.6% { transform: translateY(153px); } 66.7%, 100% { transform: translateY(0); } }
@keyframes p1-star-3 { 0%, 33.3% { transform: translateY(218px); } 33.4%, 66.6% { transform: translateY(150px); } 66.7%, 100% { transform: translateY(0); } }
@keyframes p1-star-4 { 0%, 66.6% { transform: translateY(130px); } 66.7%, 100% { transform: translateY(0); } }
@keyframes p1-star-5 { 0%, 66.6% { transform: translateY(116px); } 66.7%, 100% { transform: translateY(0); } }

/* Takeoff's burn: no flame and no plumes as the patch arrives, then half the flame and the foreground plume, then the
   full flame and both plumes as drawn (Ty: "50% flame. foreground plume only"). The fighter and the runway untouched. */
.p2-flame { transform-box: fill-box; transform-origin: 50% 0; }
@supports (animation-timeline: view()) {
  @media (min-width: 640px) and (prefers-reduced-motion: no-preference) {
    .p2-flame, .p2-front, .p2-back { animation: linear both; animation-timeline: --stuck; animation-range: cover 38% cover 88%; }
    .p2-flame { animation-name: p2-flame; }
    .p2-front { animation-name: p2-front; }
    .p2-back { animation-name: p2-back; }
  }
}
@keyframes p2-flame { 0%, 33.3% { transform: scaleY(0); } 33.4%, 66.6% { transform: scaleY(0.5); } 66.7%, 100% { transform: scaleY(1); } }
@keyframes p2-front { 0%, 33.3% { opacity: 0; } 33.4%, 100% { opacity: 1; } }
@keyframes p2-back { 0%, 66.6% { opacity: 0; } 66.7%, 100% { opacity: 1; } }

/* Autopilot's flight: no plane and no path as the patch arrives, then the plane seen from above at 10 o'clock,
   climbing along the path with the whole path below it, then the plane seen from the side, level at the path's end,
   and the whole path as drawn (Ty, 2026-10-15: "the plane at scene 3 ought to appear level, cruising orientation, and
   the plane at scene 2 will need to appear in takeoff orientation"; scene 2 at 10 o'clock, "this is the one"). Two
   planes: .p3-climb (patch-3-climb-v5.svg) shown in scene 2 only, turned on its centre along the path; .p3-plane
   the drawn file's, shown in scene 3 and at rest. */
.p3-climb { opacity: 0; transform-box: view-box; transform-origin: 1059px 511px; transform: translate(-562px, 102px) rotate(-29deg); }
@supports (animation-timeline: view()) {
  @media (min-width: 640px) and (prefers-reduced-motion: no-preference) {
    .p3-plane, .p3-climb, .p3-path, .p3-trail { animation: linear both; animation-timeline: --stuck; animation-range: cover 38% cover 88%; }
    .p3-plane { animation-name: p3-plane; }
    .p3-climb { animation-name: p3-climb; }
    .p3-path { animation-name: p3-path; }
    .p3-trail { animation-name: p3-trail; }
  }
}
@keyframes p3-plane { 0%, 66.6% { opacity: 0; } 66.7%, 100% { opacity: 1; } }
@keyframes p3-climb { 0%, 33.3% { opacity: 0; } 33.4%, 66.6% { opacity: 1; } 66.7%, 100% { opacity: 0; } }
@keyframes p3-path { 0%, 33.3% { opacity: 0; } 33.4%, 100% { opacity: 1; } }
/* the path behind the plane: the arc below the climbing plane's centre (y 613) */
@keyframes p3-trail { 0%, 66.6% { transform: translateY(613px); } 66.7%, 100% { transform: none; } }

/* Autopilot's patch rides the runway into the S-curve and rests at its midpoint, halfway across (Ty, 2026-10-17: "can it
   continue along the runway until it's mid-way through the curve?"; D321's slide, its stretch run on), at the pace of
   the scroll, as every patch slides (Ty: "the autopilot patch animation speed doesn't match the rest, now it's too
   fast"): each pixel scrolled is a pixel along the path, so the half curve, 290.3px long, takes 290.3px of scroll and the
   patch rises in the window as the path turns across. The patch's column reaches into Command's band so the patch
   stays stuck for the ride; the band's trip up the window times it, from where the curve leaves the straight (the
   band's top). The keyframes are the band's cubic (15.77 to 84.23 of 100, 66ch wide, 633.6px) read every 1/24 of its
   length: across in 66ch, and up by what the scroll gave and the path did not. Stills without support or with reduced
   motion keep the stop at the straight. */
@supports (animation-timeline: view()) {
  @media (min-width: 721px) and (prefers-reduced-motion: no-preference) {
    #main { timeline-scope: --curve; }
    .r-switch .r-band { view-timeline: --curve block; }
    .r-stop:has(+ .r-switch) .r-patchcell { padding-bottom: 0; margin-bottom: calc(-290.3px - min(14vh, 100px)); }
    .r-stop:has(+ .r-switch) .r-sticky { animation: r-curve linear both; animation-timeline: --curve; animation-range: cover calc(88vh - min(14vh, 100px)) cover calc(88vh - min(14vh, 100px) + 290.3px); }
  }
}
@keyframes r-curve {
  0% { transform: translate(calc(66ch * 0.0000), 0.0px); }
  4.167% { transform: translate(calc(66ch * 0.0009), 0.0px); }
  8.333% { transform: translate(calc(66ch * 0.0039), -0.2px); }
  12.5% { transform: translate(calc(66ch * 0.0090), -0.6px); }
  16.67% { transform: translate(calc(66ch * 0.0163), -1.5px); }
  20.83% { transform: translate(calc(66ch * 0.0256), -3.1px); }
  25% { transform: translate(calc(66ch * 0.0368), -5.4px); }
  29.17% { transform: translate(calc(66ch * 0.0495), -8.4px); }
  33.33% { transform: translate(calc(66ch * 0.0634), -12.3px); }
  37.5% { transform: translate(calc(66ch * 0.0783), -16.8px); }
  41.67% { transform: translate(calc(66ch * 0.0940), -22.0px); }
  45.83% { transform: translate(calc(66ch * 0.1103), -27.8px); }
  50% { transform: translate(calc(66ch * 0.1270), -34.1px); }
  54.17% { transform: translate(calc(66ch * 0.1441), -40.8px); }
  58.33% { transform: translate(calc(66ch * 0.1615), -47.9px); }
  62.5% { transform: translate(calc(66ch * 0.1791), -55.4px); }
  66.67% { transform: translate(calc(66ch * 0.1969), -63.1px); }
  70.83% { transform: translate(calc(66ch * 0.2149), -71.0px); }
  75% { transform: translate(calc(66ch * 0.2329), -79.1px); }
  79.17% { transform: translate(calc(66ch * 0.2510), -87.4px); }
  83.33% { transform: translate(calc(66ch * 0.2692), -95.9px); }
  87.5% { transform: translate(calc(66ch * 0.2874), -104.4px); }
  91.67% { transform: translate(calc(66ch * 0.3057), -113.0px); }
  95.83% { transform: translate(calc(66ch * 0.3240), -121.6px); }
  100% { transform: translate(calc(66ch * 0.3423), -130.3px); }
}

/* Command's orbit: the ring drawn clockwise from the moon's right edge to 3 o'clock as the patch arrives, then on to
   7, then whole (Ty: "ring visible starting right side of moon and extending to the 3 oclock position"). Three
   wedges from the ring's centre uncover it; at rest all three, the drawn patch. The tower and the moon untouched. */
@supports (animation-timeline: view()) {
  @media (min-width: 640px) and (prefers-reduced-motion: no-preference) {
    .p4-arc-2, .p4-arc-3 { animation: linear both; animation-timeline: --stuck; animation-range: cover 38% cover 88%; }
    .p4-arc-2 { animation-name: p4-arc-2; }
    .p4-arc-3 { animation-name: p4-arc-3; }
  }
}
@keyframes p4-arc-2 { 0%, 33.3% { visibility: hidden; } 33.4%, 100% { visibility: visible; } }
@keyframes p4-arc-3 { 0%, 66.6% { visibility: hidden; } 66.7%, 100% { visibility: visible; } }

/* Testing's needle: at 8 as the patch arrives, then 11, then where it is drawn, about half past one (Ty: "dial at 8 oclock",
   "needle at 11", "needle at final poition"). It turns on the hub; the gauge and the sky untouched. */
.p5-needle { transform-box: view-box; transform-origin: 757px 878px; }
@supports (animation-timeline: view()) {
  @media (min-width: 640px) and (prefers-reduced-motion: no-preference) {
    .p5-needle { animation: p5-needle linear both; animation-timeline: --stuck; animation-range: cover 38% cover 88%; }
  }
}
@keyframes p5-needle { 0%, 33.3% { transform: rotate(-162.4deg); } 33.4%, 66.6% { transform: rotate(-72.4deg); } 66.7%, 100% { transform: none; } }

/* Recon's lookout: the birds cross the sky left to right, and each lens's shine draws on clockwise, from 12 o'clock
   to 1, then to 2, then to 3 as drawn (Ty: "birds shifting across the sky left to right"; "Rule A, the shine draws on
   clockwise; the birds as today"). The binoculars and the mountains untouched. */
@supports (animation-timeline: view()) {
  @media (min-width: 640px) and (prefers-reduced-motion: no-preference) {
    .p6-birds, .p6-arc-2, .p6-arc-3 { animation: linear both; animation-timeline: --stuck; animation-range: cover 38% cover 88%; }
    .p6-birds { animation-name: p6-birds; }
    .p6-arc-2 { animation-name: p4-arc-2; }
    .p6-arc-3 { animation-name: p4-arc-3; }
  }
}
@keyframes p6-birds { 0%, 33.3% { transform: translateX(-140px); } 33.4%, 66.6% { transform: translateX(-70px); } 66.7%, 100% { transform: none; } }
