/* ============================================================
   KESEY  |  practice pages only  |  components layer
   Loaded by the pages the practice sells with, never by Pre-Trip, so the
   product's payload is unchanged. Sits on css/kesey.css and invents no
   tokens. House rule: no em dashes and no en dashes anywhere.

   The grammar here is deliberate: rules, hanging numerals and the road,
   rather than a grid of rounded cards. See CLAUDE.md, "The practice pages
   read as a printed page".
   ============================================================ */

/* ---- the vans ---- */
@keyframes roll{ to{ stroke-dashoffset:-15; } }
@keyframes spin{ to{ transform:rotate(360deg); } }
@keyframes bob{ 0%,100%{ transform:translateY(0); } 50%{ transform:translateY(-1.4px); } }
.road-dash{animation:roll 1.6s linear infinite;}
.hub{transform-box:fill-box; transform-origin:center; animation:spin 1.5s linear infinite;}

/* hero van: drives across its own strip of road */
.vanstage{position:relative; margin-top:38px; overflow:hidden;}
.vanroad{position:relative; height:2px; background:var(--line); border-radius:2px;}
.vanroad::after{content:""; position:absolute; inset:0;
  background:repeating-linear-gradient(90deg, rgba(169,163,184,.8) 0 14px, transparent 14px 30px);
  animation:vanroad 1s linear infinite;}
@keyframes vanroad{ to{ transform:translateX(-30px); } }
/* The van drives the length of the hero and comes round again. The drive lives
   on the WRAPPER and the bob on the van itself, because two animations on one
   element both writing transform means the second silently wins. .vanstage
   clips, so it leaves at the right edge and re-enters from the left. */
.vandrive{display:block; width:max-content; animation:drive 34s linear infinite;}
@keyframes drive{
  from{ transform:translateX(calc(-100% - 24px)); }
  to  { transform:translateX(100vw); }
}
.hero-van{position:relative; width:min(280px,58vw); height:auto; display:block;
  margin-bottom:-6px; animation:bob 2.4s ease-in-out infinite;
  filter:drop-shadow(0 0 22px rgba(255,122,47,.35));}
.beam{transform-box:fill-box; transform-origin:left center; animation:beam 3.4s ease-in-out infinite;}
@keyframes beam{ 0%,100%{opacity:.16;} 50%{opacity:.42;} }

/* footer van */
.foot-bus{width:56px; height:auto; display:block; opacity:.9; margin:0 0 8px auto;}

/* the scroll rail: a van driving the length of the page */
.rail{position:fixed; left:22px; top:0; bottom:0; width:34px; z-index:40; pointer-events:none; display:none;}
.rail-track{position:absolute; left:16px; top:120px; bottom:80px; width:2px; background:var(--line); border-radius:2px; overflow:hidden;}
.rail-track::after{content:""; position:absolute; inset:0;
  background:repeating-linear-gradient(180deg, rgba(169,163,184,.85) 0 10px, transparent 10px 22px);
  animation:railroad 1.1s linear infinite;}
@keyframes railroad{ to{ transform:translateY(22px); } }
.rail-fill{position:absolute; left:16px; top:120px; width:2px; border-radius:2px; height:var(--prog,0%);
  background:linear-gradient(180deg,var(--pink-mark),var(--orange-mark),var(--lime-mark),var(--cyan-mark));
  box-shadow:0 0 14px rgba(255,122,47,.7);}
.rail-van{position:absolute; left:0; width:34px; height:auto;
  top:calc(120px + var(--prog,0%) - 13px); filter:drop-shadow(0 0 10px rgba(200,245,66,.55));}
.rail-stops{position:absolute; left:16px; top:120px; bottom:80px; width:2px;}
.stop{position:absolute; left:-4px; width:10px; height:10px; border-radius:50%;
  background:var(--ink); border:1.5px solid var(--line); transform:translateY(-50%);
  transition:border-color .35s ease, background .35s ease, box-shadow .35s ease, scale .35s ease;}
.stop.on{border-color:var(--lime-mark); background:var(--lime-mark); box-shadow:0 0 10px rgba(200,245,66,.8); scale:1.15;}
@media (min-width:1200px){ .rail{display:block;} }

/* ticker */
.tick-band{border-top:1px solid var(--line); border-bottom:1px solid var(--line);
  background:linear-gradient(90deg, rgba(124,92,255,.10), rgba(255,77,157,.07), rgba(200,245,66,.08));
  overflow:hidden; padding:13px 0;
  -webkit-mask-image:linear-gradient(90deg,transparent,#000 7%,#000 93%,transparent);
  mask-image:linear-gradient(90deg,transparent,#000 7%,#000 93%,transparent);}
.tick-track{display:flex; width:max-content; animation:tickr 44s linear infinite;}
.tick-band:hover .tick-track{animation-play-state:paused;}
@keyframes tickr{ to{ transform:translateX(-50%); } }
.tick-item{font-size:14.5px; white-space:nowrap; color:var(--bone); opacity:.8;}
.tick-item b{color:var(--lime-ink); font-weight:400;}
.tick-item::after{content:"\273B"; margin:0 22px; color:var(--lime-ink); opacity:.7;}


header.hero{position:relative; padding:74px 0 58px; overflow:hidden;}
.blob{position:absolute; border-radius:50%; filter:blur(94px); pointer-events:none;}
.b1{width:520px; height:520px; background:var(--violet); opacity:.34; top:-230px; right:-140px;}
.b2{width:400px; height:400px; background:var(--pink); opacity:.28; bottom:-230px; left:-150px;}
.hero-in{position:relative; z-index:2;}
.kick{color:var(--lime-ink); margin-bottom:20px;}
.lede{font-size:19.5px; color:var(--dim); max-width:60ch; margin-top:22px;}
.lede b{color:var(--bone); font-weight:600;}
.ctas{display:flex; gap:13px; flex-wrap:wrap; margin-top:32px;}
/* .band centres its own text, so a left-aligned button row under a centred
   heading reads as a mistake. Five closing CTAs, one per practice page. */
.band .ctas{justify-content:center;}

section{padding:72px 0; border-top:1px solid var(--line);}
.sec-head{margin-bottom:34px;}
.sec-head h2{max-width:20ch;}
.sec-head p{color:var(--dim); font-size:18px; margin-top:13px; max-width:56ch;}

.symp{display:grid; grid-template-columns:repeat(auto-fit,minmax(min(260px,100%),1fr)); gap:12px;}
.symp{gap:0 44px;}
.symp div{border-top:1px solid var(--line); padding:20px 0;
  font-size:16.5px; line-height:1.45; color:var(--bone);}
.symp div span{display:block; font-family:var(--label); font-weight:600; font-size:10.5px; letter-spacing:.14em;
  text-transform:uppercase; color:var(--pink-ink); margin-bottom:9px;}
@media (min-width:900px){ .symp.four{grid-template-columns:repeat(2,1fr);} }

.doors{display:grid; grid-template-columns:repeat(auto-fit,minmax(min(300px,100%),1fr)); gap:16px;}
.door{background:var(--ink2); border:1px solid var(--line); border-radius:18px; padding:28px 26px;
  display:flex; flex-direction:column; gap:13px; transition:border-color .2s ease, transform .2s ease;}
.door:hover{border-color:var(--c,var(--violet)); transform:translateY(-3px);}
.door .lbl{font-family:var(--display); font-weight:900; font-size:15px; letter-spacing:-.01em;
  font-variation-settings:'WONK' 1,'opsz' 24; color:var(--ci,var(--c,var(--violet-ink)));}
.door .prob{font-size:16px; color:var(--bone); font-weight:600; line-height:1.35; font-family:var(--display); letter-spacing:-.01em;}
.door p{color:var(--dim); font-size:15px;}
.door .go{margin-top:auto; padding-top:15px; border-top:1px solid var(--line);
  font-size:14px; color:var(--dim);}

.refuse{display:grid; grid-template-columns:repeat(auto-fit,minmax(min(280px,100%),1fr)); gap:0 44px;}
.ref{border-top:1px solid var(--line); padding:22px 0;}
.ref h4{margin-bottom:7px; font-size:18px; font-variation-settings:'WONK' 1,'opsz' 28;}
.ref p{color:var(--dim); font-size:15.5px; line-height:1.5;}

.phases{display:grid; grid-template-columns:repeat(auto-fit,minmax(min(230px,100%),1fr)); gap:0 36px; counter-reset:ph;}
.phase{border-top:2px solid var(--line); padding:20px 0 24px;}
.phase::before{counter-increment:ph; content:counter(ph); font-family:var(--display); font-weight:900;
  font-size:26px; letter-spacing:-.02em; color:var(--lime-ink); display:block; margin-bottom:8px; line-height:1;}
.phase p{color:var(--dim); font-size:15px; margin-top:8px; line-height:1.5;}
.phase h4{font-size:18px; font-variation-settings:'WONK' 1,'opsz' 28;}

.tick{list-style:none; display:grid; gap:12px; max-width:66ch;}
.tick li{display:block; position:relative; padding-left:27px; color:var(--dim); font-size:16px;}
.tick li i{position:absolute; left:0; top:0; color:var(--lime-ink); font-style:normal; font-family:var(--label); font-weight:600; font-size:13px;}
.tick li b{color:var(--bone); font-weight:600;}
.tick.no li i{color:var(--pink-ink);}

.pull{border-left:3px solid; border-image:linear-gradient(180deg,var(--pink),var(--orange)) 1;
  padding:4px 0 4px 24px; margin:28px 0; font-family:var(--display); font-weight:800;
  font-size:clamp(19px,2.3vw,25px); line-height:1.34; color:var(--bone); letter-spacing:-.015em;}

.map{display:grid; grid-template-columns:1fr 1fr; gap:0 48px;}
.mapcol{border-top:2px solid var(--line); padding:22px 0 8px;}
.mapcol h4{margin-bottom:16px; font-size:19px; font-variation-settings:'WONK' 1,'opsz' 30;}

.dec{display:grid; gap:14px;}
.decision{background:var(--ink2); border:1px solid var(--line); border-radius:16px; padding:24px 26px;}
.decision .q{font-family:var(--display); font-weight:800; font-size:18px; letter-spacing:-.015em; margin-bottom:10px;}
.decision .rec{color:var(--dim); font-size:15.5px;}
.decision .rec b{color:var(--lime-ink); font-weight:600;}
.decision .why{color:var(--dim); font-size:14.5px; margin-top:9px; padding-top:9px; border-top:1px solid var(--line);}


/* ============================================================
   Layout grammar, second pass.
   The tell is not the font, it is the skeleton: every block a
   rounded card in an auto-fit grid. So the page stops using
   boxes as its default container and uses RULES, HANGING
   NUMERALS and the brand's own road as structure instead.
   ============================================================ */

/* a print column: hairline rules, hanging numerals, no boxes */
.ledger{border-top:1px solid var(--line);}
.led{display:grid; grid-template-columns:auto 1fr; gap:26px; align-items:start;
  padding:26px 0; border-bottom:1px solid var(--line);}
.led .no{font-family:var(--display); font-weight:900; font-size:46px; line-height:.9;
  letter-spacing:-.04em; color:#3B3547; font-variation-settings:'WONK' 1,'opsz' 60;
  transition:color .3s ease;}
.led:hover .no{color:var(--pink-ink);}
.led .t{font-family:var(--display); font-weight:900; font-size:21px; letter-spacing:-.015em;
  font-variation-settings:'WONK' 1,'opsz' 32; color:var(--bone); margin-bottom:6px;}
.led p{color:var(--dim); font-size:16.5px; line-height:1.5; max-width:58ch;}
@media (max-width:620px){ .led{grid-template-columns:auto 1fr; gap:16px;} .led .no{font-size:28px;} }

/* the route: the brand's own road, used as a list. stops, not cards. */
.route{position:relative; padding-left:54px; padding-top:34px;}
.route::before{content:""; position:absolute; left:15px; top:34px; bottom:12px; width:3px;
  background:#332E42; border-radius:3px;}
.route::after{content:""; position:absolute; left:16px; top:34px; bottom:12px; width:1px;
  background:repeating-linear-gradient(180deg, rgba(169,163,184,.5) 0 11px, transparent 11px 24px);
  animation:railroad 1.5s linear infinite;}
/* how far the van has driven. Set in px by the scroll handler, because the road
   starts 34px down and a percentage of the section would never line up with it. */
.route-fill{position:absolute; left:15px; top:34px; width:3px; border-radius:3px;
  height:max(0px, calc(var(--rp,34px) - 34px));
  background:linear-gradient(180deg,var(--pink-mark),var(--orange-mark),var(--lime-mark));
  box-shadow:0 0 14px rgba(255,122,47,.6); transition:height .35s cubic-bezier(.2,.8,.3,1);}
.route-van{position:absolute; left:-21px; top:var(--rp,34px); width:74px; height:auto;
  transform:translateY(-52%); filter:drop-shadow(0 0 12px rgba(200,245,66,.65)); z-index:3;
  transition:top .35s cubic-bezier(.2,.8,.3,1);}
@media (max-width:620px){ .route-van{left:-25px; width:64px;} .route-fill{left:8px;} }
.rstop{position:relative; padding:24px 0; border-bottom:1px solid var(--line); display:block;}
.rstop:first-child{padding-top:6px;}
.rstop:last-child{border-bottom:none;}
.rstop::before{content:""; position:absolute; left:-45px; top:30px; width:15px; height:15px;
  border-radius:50%; background:var(--ink); border:2px solid #4A4360;
  transition:border-color .25s ease, background .25s ease, box-shadow .25s ease;}
.rstop:first-child::before{top:12px;}
a.rstop:hover::before,.rstop.lit::before{border-color:var(--lime-mark); background:var(--lime-mark);
  box-shadow:0 0 12px rgba(200,245,66,.8);}
.rstop.lit .t{color:var(--bone);}
.rstop .t{font-family:var(--display); font-weight:900; font-size:clamp(19px,2.2vw,25px);
  letter-spacing:-.018em; font-variation-settings:'WONK' 1,'opsz' 36; color:var(--bone); line-height:1.14;}
a.rstop:hover .t{color:var(--lime-ink);}
.rstop p{color:var(--dim); font-size:16px; line-height:1.5; margin-top:8px; max-width:62ch;}
.rstop .tag{margin-top:9px; font-size:13.5px; color:var(--dim);}
.rstop .tag b{color:var(--lime-ink); font-weight:600;}
@media (max-width:620px){ .route{padding-left:38px;} .route::before{left:8px;} .route::after{left:9px;}
  .rstop::before{left:-36px; width:12px; height:12px;} }

/* masthead numbers: hairline rules, no boxes */
.mast{display:grid; grid-template-columns:repeat(auto-fit,minmax(min(190px,100%),1fr));
  border-top:1px solid var(--line);}
.mst{padding:26px 26px 26px 0; border-bottom:1px solid var(--line); min-width:0;}
.mst .n{font-family:var(--display); font-weight:900; font-size:clamp(34px,4.6vw,54px); line-height:.92;
  letter-spacing:-.045em; font-variation-settings:'WONK' 1,'opsz' 90;
  background:linear-gradient(92deg,var(--pink-mark),var(--orange-mark)); -webkit-background-clip:text;
  background-clip:text; color:transparent;}
.mst .l{color:var(--dim); font-size:14px; line-height:1.45; margin-top:12px; max-width:26ch;}

/* two plain columns of statements, rules only */
.stated{display:grid; grid-template-columns:1fr 1fr; gap:0 48px;}
.stt{padding:22px 0; border-top:1px solid var(--line);}
.stt h4{font-family:var(--display); font-weight:900; font-size:18px; letter-spacing:-.015em;
  font-variation-settings:'WONK' 1,'opsz' 28; margin-bottom:7px;}
.stt p{color:var(--dim); font-size:15.5px; line-height:1.5;}
@media (max-width:760px){ .stated{grid-template-columns:1fr; gap:0;} }

/* an editorial opener: the lede gets a rule and room, not a card */
.opener{border-left:2px solid var(--orange); padding-left:26px; margin:34px 0 0; max-width:64ch;}
.opener p{font-size:19px; color:var(--dim); line-height:1.55;}
.opener p b{color:var(--bone); font-weight:600;}

/* section heads sit on a rule rather than floating above a grid */
.head2{display:grid; grid-template-columns:1fr; gap:14px; margin-bottom:8px; padding-bottom:26px;}
.head2 h2{max-width:18ch;}
.head2 p{color:var(--dim); font-size:18px; max-width:56ch;}
@media (min-width:900px){
  .head2{grid-template-columns:minmax(0,1.1fr) minmax(0,1fr); gap:40px; align-items:end;}
  .head2 p{padding-bottom:5px;}
}

/* rules my first slice of this file dropped */
/* The mobile menu button. Absent until 2026-08-22, so on a phone the links
   hid at 900px and nothing opened them: no menu at all. The button lives LAST
   in .nav-in, and Book a call takes margin-left:auto so the two group at the
   right rather than the button landing centred by space-between. */
@media (max-width:900px){
  .site-nav .nav-in{gap:10px;}
  .site-nav .nav-in > .btn{margin-left:auto;}
}
nav.site-nav{position:sticky; top:0; z-index:60; background:rgba(14,13,18,.9);
  backdrop-filter:blur(12px); border-bottom:1px solid var(--line);}
.btn-sm{font-size:13.5px; padding:9px 18px;}

/* ============================================================
   Every seat at the table, drawn as the coach floorplan.
   Rows are eras, so the years run down the left gutter the way
   row numbers run down an aircraft seat map, and the taken seat
   crosses the aisle each row because he did keep moving seats.
   The janitor has the wheel: that is the seat this practice is
   in now, and everyone he used to be is riding behind him.
   Degrades to a readable list with no JS, which is why every
   detail block is in the DOM and .js is what collapses them.
   ============================================================ */
/* NOT .seatmap: css/kesey.css has owned that name since Pre-Trip's coverage
   table, and both sheets load here. Squatting on it inherited a 1px border,
   an 18px radius and overflow:hidden, which clipped the selected seat's
   drop shadow, plus an overflow-x:auto scroll container under 900px. */
.busmap{display:grid; gap:38px; align-items:start;}
/* the plan is taller than any one detail, so the text is centred against it
   rather than left hanging off the top of a 600px drawing */
@media (min-width:900px){ .busmap{grid-template-columns:minmax(230px,286px) minmax(0,1fr);
  gap:60px; align-items:center;} }

.busplan{position:relative;}
.busplan svg{width:100%; height:auto; display:block; overflow:visible;}
/* the plan is a tall narrow drawing, so on a phone it is capped rather than
   run to the full column, where it would be most of a screen on its own */
@media (max-width:899px){ .busplan{max-width:248px; margin:0 auto;} }

/* an empty seat is drawn and never labelled, because a seat map that shows
   only the taken seats is a diagram of six boxes again */
.eseat rect{fill:#1D1A29; stroke:#312C42; stroke-width:1.5;}
.doorwell .panel{fill:#100E19; stroke:#312C42; stroke-width:1.4; stroke-dasharray:5 5;}
.doorwell .step{fill:#2A2639;}
.doorwell .lbl{font-family:var(--mono); font-size:8.5px; letter-spacing:.22em;
  fill:#6B6484; text-anchor:middle;}

/* the aisle runs the length of the bus, which is the one problem every seat
   is looking at from a different row */
.aisle{stroke:url(#spine); stroke-width:3; stroke-linecap:round; opacity:.78;}

.bseat{cursor:pointer;}
.bseat rect,.bseat circle,.bseat line,.bseat text{
  transition:fill .22s ease, stroke .22s ease, r .22s ease;}
.bseat .back,.bseat .arm{fill:#2C2740; stroke:#453E5C; stroke-width:1.7;}
.bseat .cushion{fill:#221E31; stroke:#453E5C; stroke-width:2;}
.bseat .who{font-family:var(--display); font-weight:700; font-size:15px;
  letter-spacing:-.012em; font-variation-settings:'WONK' 1;
  fill:#8E87A6; text-anchor:middle; pointer-events:none;}
.bseat .yr{font-family:var(--display); font-weight:900; font-size:20.5px;
  font-variant-numeric:tabular-nums; letter-spacing:-.035em;
  font-variation-settings:'WONK' 1,'opsz' 40; fill:#6B6484; text-anchor:end;}
.bseat .tick{stroke:#3A3450; stroke-width:2; stroke-linecap:round;}
.bseat .node{fill:#3A3450;}
.bseat .wheel{fill:none; stroke:#4A4364; stroke-width:2.4;}
.bseat .hub{fill:#4A4364;}

.bseat:hover .cushion,.bseat:focus-visible .cushion{stroke:var(--sc,var(--violet));}
.bseat:hover .yr,.bseat:focus-visible .yr,
.bseat:hover .who,.bseat:focus-visible .who{fill:var(--dim);}

.bseat.on{filter:drop-shadow(0 0 15px color-mix(in srgb, var(--sc,var(--violet)) 42%, transparent));}
.bseat.on .cushion{fill:color-mix(in srgb, var(--sc,var(--violet)) 26%, #221E31);
  stroke:var(--sc,var(--violet));}
.bseat.on .back,.bseat.on .arm{fill:color-mix(in srgb, var(--sc,var(--violet)) 42%, #2C2740);
  stroke:var(--sc,var(--violet));}
.bseat.on .who{fill:var(--bone);}
.bseat.on .yr,.bseat.on .tick{fill:var(--sc,var(--violet)); stroke:var(--sc,var(--violet));}
.bseat.on .node{fill:var(--sc,var(--violet)); r:6;}
.bseat.on .wheel{stroke:var(--sc,var(--violet));}
.bseat.on .hub{fill:var(--sc,var(--violet));}
.bseat:focus{outline:none;}
.bseat:focus-visible .cushion{stroke-width:3.2;}

/* the detail, one at a time once JS is running */
.sdetail{border-top:1px solid var(--line); padding:26px 0 6px;}
.busmap.js .sdetail{display:none; border-top:none; padding:0;}
.busmap.js .sdetail.on{display:block; animation:seatin .34s cubic-bezier(.2,.8,.3,1) both;}
@keyframes seatin{from{opacity:0; transform:translateY(10px);} to{opacity:1; transform:none;}}
@media (prefers-reduced-motion:reduce){ .busmap.js .sdetail.on{animation:none;} }
.sd-head{display:flex; align-items:baseline; gap:15px; flex-wrap:wrap; margin-bottom:14px;}
.sd-yr{font-family:var(--display); font-weight:900; font-size:clamp(42px,6.4vw,66px);
  line-height:.88; letter-spacing:-.045em; font-variant-numeric:tabular-nums;
  font-variation-settings:'WONK' 1,'opsz' 90; color:var(--sc,var(--violet));}
.sd-meta{font-family:var(--mono); font-size:11px; letter-spacing:.15em;
  text-transform:uppercase; color:var(--dim); padding:5px 12px; border-radius:999px;
  border:1px solid var(--line); white-space:nowrap;}
.sdetail .sd-role{font-family:var(--display); font-weight:900; font-size:clamp(28px,4vw,44px);
  line-height:1.02; letter-spacing:-.025em; font-variation-settings:'WONK' 1,'opsz' 60;
  color:var(--bone); margin-bottom:18px;}
.sdetail .sd-lead{font-family:var(--display); font-weight:800; font-size:clamp(19px,2.2vw,24px);
  line-height:1.24; letter-spacing:-.015em; color:var(--bone); margin-bottom:16px;
  padding-left:17px; border-left:3px solid var(--sc,var(--violet));}
.sdetail p{color:var(--dim); font-size:16.5px; line-height:1.55; max-width:56ch;}
.janlink{color:var(--dim); border-bottom:1px solid var(--line); padding-bottom:2px;
  transition:color .2s ease, border-color .2s ease;}
.janlink:hover,.janlink:focus-visible{color:var(--bone); border-color:var(--dim);}
.sd-hint{display:none;}
.busmap.js .sd-hint{display:block; color:var(--dim); font-size:13.5px; margin-top:26px;
  padding-top:15px; border-top:1px solid var(--line);}

/* ---- the compose board ---- */
/* The stack as a parts list, never a logo wall. Every row is a ROLE the
   business already needs filled; the tools inside a row are interchangeable
   and the wiring BETWEEN rows is the thing being sold. Deliberately a spine
   and hairlines rather than a card grid, per the practice grammar: a grid of
   rounded logo tiles is the one shape this site does not use.
   One row is Pre-Trip, which is the whole point of showing the board: an
   agency can only ever list other people's tools. */
.compose{position:relative; margin-top:34px; padding-left:32px;}
.compose::before{content:""; position:absolute; left:9px; top:20px; bottom:20px; width:2px;
  border-radius:2px; opacity:.6;
  background:linear-gradient(180deg,var(--pink-mark),var(--orange-mark),var(--lime-mark),var(--cyan-mark));}
.cslot{position:relative; display:grid; gap:5px 26px; padding:15px 0;
  border-top:1px solid var(--line);}
.cslot:first-child{border-top:0;}
/* the node sits on the spine, which lives 32px left of the row box */
.cslot::before{content:""; position:absolute; left:-28px; top:21px; width:11px; height:11px;
  border-radius:50%; background:var(--ink); border:2px solid var(--line);
  transition:border-color .3s ease, box-shadow .3s ease;}
.cslot:hover::before{border-color:var(--sc,var(--violet));
  box-shadow:0 0 12px color-mix(in srgb, var(--sc,var(--violet)) 65%, transparent);}
@media (min-width:780px){
  .cslot{grid-template-columns:minmax(0,224px) minmax(0,1fr); align-items:baseline;}
}
.cslot .role{font-family:var(--mono); font-size:12px; letter-spacing:.08em;
  text-transform:uppercase; color:var(--dim);}
.cslot .fill{font-size:16.5px; line-height:1.55; color:var(--bone);}
.cslot .fill span{color:var(--dim);}
/* A link inside prose has to LOOK like one. Both the compose board and the
   section intros inherit the paragraph colour and carry no underline, so a link
   dropped into a sentence there renders identically to the sentence: present,
   visible, and invisible AS a link. Symptom: "I'm not seeing the linkage" about
   a link that was live, in the markup, and on screen the whole time. */
.cslot .fill a, .head2 p a, .lede a, .ref p a{color:var(--bone); text-decoration:underline;
  text-decoration-color:var(--lime-ink); text-decoration-thickness:1.5px;
  text-underline-offset:3px;}
.cslot .fill a:hover, .head2 p a:hover, .lede a:hover, .ref p a:hover{color:var(--lime-ink);}

/* the row we own */
.cslot.mine::before{border-color:var(--lime-mark); background:var(--lime-mark);
  box-shadow:0 0 12px rgba(200,245,66,.75);}
.cslot.mine .role{color:var(--lime-ink);}
.cslot .tag{display:inline-block; margin-left:9px; padding:2px 7px; border-radius:3px;
  font-family:var(--mono); font-size:10px; letter-spacing:.09em; text-transform:uppercase;
  color:var(--on-accent); background:var(--lime); vertical-align:2px;}

/* ---- the marks band ---- */
/* Colour, at the operator's call. Thirty five real marks inlined as webp data
   URIs at 64px for a 26px box, so the page makes no external request and
   nothing is hotlinked from a vendor CDN. webp rather than png halved it,
   50KB against 110KB.
   Every tile sits on a faint chip, which is doing real work rather than
   decoration: a mark with a transparent background and dark artwork
   (ConnectWise is the one that proved it) vanishes completely against this
   ink. Icons that ship their own background simply cover the chip.
   Gmail, GA4 and Search Console are inline SVG rather than fetched: the
   favicon endpoint answers the SAME generic Google G for all three, so
   fetching them would have put three identical tiles on one page.
   Slightly held back at rest and full on hover, or thirty five vendor
   palettes shout over every accent the page owns. */
.marks{list-style:none; margin:24px 0 0; padding:0; display:grid;
  gap:15px 18px; grid-template-columns:repeat(auto-fill, minmax(min(150px,100%), 1fr));}
.tmark{display:flex; align-items:center; gap:10px; min-width:0;}
.tico{width:26px; height:26px; flex:0 0 26px; border-radius:6px; overflow:hidden;
  display:grid; place-items:center; background:rgba(255,255,255,.08);
  opacity:.84; filter:saturate(.92); transition:opacity .25s ease, filter .25s ease;}
.tico.glyph{background:#fff;}
.tico img{width:100%; height:100%; object-fit:contain; display:block;}
.tico svg{width:17px; height:17px; display:block;}
.tmark span{font-size:13.5px; color:var(--dim); min-width:0;
  transition:color .25s ease;}
.tmark:hover .tico{opacity:1; filter:none;}
.tmark:hover span{color:var(--bone);}
.marks-note{margin:18px 0 0; color:var(--dim); font-size:13px; line-height:1.6;}

/* Phones get the marks WITHOUT the labels. Thirty five labelled rows is
   eighteen rows of scrolling on a 390px screen, which buries the sections
   that actually make the argument. Marks only, six across, is six rows.
   Recognition carries it, and every tool is named in text further down.
   The label is visually hidden rather than display:none, so the band still
   reads correctly to a screen reader and the li keeps an accessible name. */
@media (max-width:639px){
  .marks{display:flex; flex-wrap:wrap; gap:12px;}
  .tmark{gap:0;}
  /* :not(.tico) is load bearing. The icon wrapper is ALSO a span and a direct
     child, so a bare `.tmark > span` hides the marks along with the labels and
     the whole band renders as a 12px empty strip. */
  .tmark > span:not(.tico){position:absolute; width:1px; height:1px; padding:0;
    margin:-1px; overflow:hidden; clip-path:inset(50%); white-space:nowrap; border:0;}
  .tico{width:34px; height:34px; flex-basis:34px; border-radius:8px; opacity:1; filter:none;}
  .tico svg{width:22px; height:22px;}
  .marks-note{margin-top:14px;}
}

/* ---- the delivery: van drives the band, tiles settle in its wake ---- */
/* Every start state here is scoped to html.js, because the hidden state is
   applied by script and a script that fails to load would otherwise leave the
   whole marks band invisible with all 34 tiles present in the DOM. That is the
   exact failure `.reveal` already shipped on three live pages.
   Reduced motion never gets the .wake class at all, so it renders static. */
.vanlane{position:relative; height:44px; margin-top:26px; overflow:hidden;}
/* No script, no van, so no empty road. The lane is furniture that only means
   anything once something drives on it; left up it reads as a stray rule. */
html:not(.js) .vanlane{display:none;}
.vantrack{position:absolute; left:0; right:0; bottom:0; height:1px; background:var(--line);}
.vantrack::after{content:""; position:absolute; inset:0;
  background:repeating-linear-gradient(90deg, rgba(169,163,184,.7) 0 12px, transparent 12px 26px);}
.vanrun{position:absolute; bottom:1px; left:0; width:max-content;
  transform:translateX(calc(-100% - 40px));}
.wagon{width:78px; height:auto; display:block;
  filter:drop-shadow(0 0 15px rgba(255,122,47,.4));}
html.js .vanlane.go .vanrun{
  animation:deliver 2.05s cubic-bezier(.36,0,.5,1) forwards;}
@keyframes deliver{ to{ transform:translateX(var(--travel,110vw)); } }
/* road only moves while the van is on it */
html.js .vanlane.go .vantrack::after{animation:vanlaneroad 1.4s linear infinite;}
@keyframes vanlaneroad{ to{ transform:translateX(-26px); } }

/* the tiles. offsetLeft is what sets --d, so the delay tracks horizontal
   position and the wake follows the van at any column count. */
.marks{position:relative;}
html.js .marks.wake .tmark{opacity:0; transform:translateY(-13px) scale(.9);}
html.js .marks.wake.drop .tmark{opacity:1; transform:none;
  transition:opacity .4s ease, transform .46s cubic-bezier(.2,.85,.3,1.25);
  transition-delay:var(--d,0ms);}

/* A van driving across a 390px screen is cramped, so it does not drive there.
   THE STAGGER GOES WITH IT. The van is the whole explanation for the wake: with
   no vehicle on screen the delay reads as tiles failing to load, and it is worse
   at that width than it looks, because the labels are hidden under 640px so each
   tile is a bare 26px icon and the grid lands on SEVEN columns, not two. That is
   950ms of icons popping column by column for no stated reason. The script
   returns before adding .wake below this breakpoint; these rules are the
   belt-and-braces for a desktop-to-phone resize taken mid-flight, which would
   otherwise strand whatever had not dropped yet. */
@media (max-width:639px){
  .vanlane{display:none;}
  html.js .marks.wake .tmark{opacity:1; transform:none; transition:none;}
}
@media (prefers-reduced-motion:reduce){
  .vanlane{display:none;}
  html.js .marks.wake .tmark{opacity:1; transform:none;}
}

/* ---------- light mode ----------
   See css/kesey.css for the palette. Only the practice components that
   hardcode a dark value appear here. */
:root[data-theme="light"] nav.site-nav{background:rgba(250,248,252,.9);}

/* The marks band on /stack sits every vendor logo on a faint chip, because
   near-black artwork vanishes against ink. On a light ground the artwork reads
   directly, so the chip inverts to a faint dark tint and the white one, which
   exists for logos that ship their own dark art, keeps its white. */
:root[data-theme="light"] .tico{background:rgba(20,18,32,.06);}
:root[data-theme="light"] .tico.glyph{background:#fff;
  box-shadow:inset 0 0 0 1px rgba(20,18,32,.08);}
:root[data-theme="light"] .tmark{opacity:1;}
