/* ============================================================
   PROTOCOL — the Pathway.
   Extends protocol.css; adds nothing that protocol.css already owns.
   Every surface here is .card / .rows / .row from the shared system —
   what this file adds is the four things the Pathway needs and the
   marketing site does not: the standing panel, the progress ring, the
   lesson row's three states, and the stage pip.

   BRAND LAW, enforced below and worth stating where it is easy to break:
   green is "a human verified this" and NOTHING else — so it marks a
   cleared lesson and a granted pass, never availability, never a hue.
   Red is "locked or failed" — so it marks a hold. A lesson that is
   merely ahead of you is neither: it is white at low opacity.
   ============================================================ */

.pathway{min-height:100svh}

/* ---- gate states ---- */
/* Fixed and full-bleed, and therefore the one surface on the site that can
   silently swallow its own content: `align-items:center` on a fixed box with no
   overflow rule centres a too-tall child and clips BOTH ends with no way to
   reach them. On the post-payment screen the thing clipped is the Pathway link
   — the only way back into a membership someone has just been charged for. */
.cstate{
  position:fixed;inset:0;z-index:20;display:flex;align-items:center;justify-content:center;
  padding:var(--pad-x);background:var(--bg);
  overflow-y:auto;overscroll-behavior:contain;
  -webkit-overflow-scrolling:touch;
}
/* centred when it fits, scrolled from the top when it does not */
.cstate-in{margin:auto 0}
.cstate-in{max-width:44ch;text-align:center;display:flex;flex-direction:column;align-items:center;gap:18px}
.cstate .wm{margin:0}
.cstate .wm.dim{opacity:.28;animation:cpulse 1.9s var(--ease) infinite}
@keyframes cpulse{0%,100%{opacity:.22}50%{opacity:.5}}
/* The Pathway link and the Stripe reference live in here, and it had no rules
   of its own — so a 60-character URL in a <code> ran straight off both sides of
   a phone. It is the single most important string on the page. */
.keybox{
  width:100%;max-width:44ch;
  display:flex;flex-direction:column;align-items:stretch;gap:12px;
  padding:16px;border-radius:var(--r-3);
  background:var(--s-1);border:1px solid var(--line);
}
.keybox code{
  font-family:var(--mono);font-size:12.5px;line-height:1.5;color:var(--text);
  text-align:left;word-break:break-all;overflow-wrap:anywhere;
  padding:12px;border-radius:var(--r-2);background:rgba(0,0,0,.45);
  border:1px solid var(--line);
  /* selectable by design — copy is the primary action, tapping to select is
     the fallback when the clipboard API is blocked */
  user-select:all;-webkit-user-select:all;
}
.keybox .btn{width:100%}
.keybox .dat{text-align:center;letter-spacing:.14em;color:var(--text-3);min-height:1em}

.cstate-t{font-size:20px;font-weight:600;letter-spacing:-.02em;line-height:1.3}
.cstate-p{font-size:15.5px;line-height:1.65;color:var(--text-2)}
@media(prefers-reduced-motion:reduce){.cstate .wm.dim{animation:none;opacity:.4}}

/* ---- header ---- */
.chead{
  position:sticky;top:0;z-index:10;
  display:flex;align-items:center;gap:12px;
  padding:16px var(--pad-x);
  background:rgba(0,0,0,.62);backdrop-filter:blur(24px) saturate(1.3);
  border-bottom:1px solid var(--line);
}
.chead .wm{margin-right:auto;text-decoration:none}
.chead-name{white-space:nowrap;overflow:hidden;text-overflow:ellipsis;max-width:38vw}
@media(max-width:560px){.chead-name{display:none}}

.cwrap{
  max-width:860px;margin:0 auto;padding:28px var(--pad-x) 96px;
  display:flex;flex-direction:column;gap:20px;
}

/* the shared .rows draws its own border and radius; inside a .card it is a
   plain list and must not repeat either, or every panel reads double-walled */
.rows.flush{background:none;border:0;border-radius:0;box-shadow:none;backdrop-filter:none}

.cbody{padding:var(--pad-body) var(--pad-in)}
.cfootnote{padding:12px var(--pad-in) 16px;border-top:1px solid var(--line-soft)}

/* ============================================================
   STANDING — the one thing he opens the Pathway to see
   ============================================================ */
.standing-in{
  display:grid;grid-template-columns:1fr auto;gap:24px;align-items:center;
  padding:clamp(24px,4vw,36px) var(--pad-in);
}
.standing .lbl{
  display:block;font-family:var(--mono);font-size:11px;font-weight:500;
  text-transform:uppercase;letter-spacing:.14em;color:var(--text-3);margin-bottom:12px;
}
.standing h2{font-size:clamp(22px,3.4vw,31px);font-weight:600;letter-spacing:-.03em;line-height:1.14}
.standing-p{margin-top:12px;font-size:16px;line-height:1.6;color:var(--text-2);max-width:46ch}
.standing-meta{margin-top:14px}
@media(max-width:620px){
  .standing-in{grid-template-columns:1fr;gap:22px}
  .ring{justify-self:start}
}

/* the ring — cleared lessons out of eight. Green because a cleared lesson is
   exactly the thing green is reserved for: a human checked it. */
.ring{position:relative;width:128px;height:128px;flex:none}
.ring svg{width:100%;height:100%;transform:rotate(-90deg)}
.ring circle{fill:none;stroke-width:7;stroke-linecap:round}
.ring-bg{stroke:var(--s-3)}
/* The ring carries its true stroke-dashoffset as an inline style from the
   moment it renders, and this rule adds no animation of its own. The sweep is
   an ENHANCEMENT, applied by pathway.js only once the document is actually
   visible.

   It has to be this way round. A Pathway link arrives in a message, so it is
   routinely cmd-clicked into a background tab — where no frames are produced,
   a CSS animation sits at currentTime 0, and its `from` keyframe wins over the
   inline value. Written the obvious way, every man opening his link in a
   background tab would find a permanently empty ring reading "5 of 8". */
.ring-fg{
  stroke:var(--verified);
  stroke-dasharray:345.6;          /* 2πr, r=55 */
}
.ring-fg.sweep{animation:ringsweep 900ms var(--ease)}
@keyframes ringsweep{from{stroke-dashoffset:345.6}}
@media(prefers-reduced-motion:reduce){.ring-fg.sweep{animation:none}}
.ring-c{
  position:absolute;inset:0;display:flex;flex-direction:column;
  align-items:center;justify-content:center;gap:1px;
}
.ring-c b{font-size:34px;font-weight:600;letter-spacing:-.04em;line-height:1;font-variant-numeric:tabular-nums}
.ring-c .dat{font-size:11px;letter-spacing:.1em;text-transform:uppercase;color:var(--text-3)}
@media(prefers-reduced-motion:reduce){.ring-fg{transition:none}}

/* last verdict — the only place red appears in the Pathway */
.verdictbar{
  display:flex;gap:14px;align-items:flex-start;
  padding:16px var(--pad-in);border-top:1px solid var(--line);
  background:rgba(255,255,255,.022);
}
.verdictbar p{font-size:15px;line-height:1.55;color:var(--text-2)}
.verdictbar .chip{flex:none;margin-top:1px}

/* ============================================================
   THE MAP — a lesson row is cleared, current, or ahead
   ============================================================ */
.row.lesson{align-items:flex-start;padding-top:15px;padding-bottom:15px}
.row.lesson .ic{font-family:var(--mono);font-size:12px;letter-spacing:.02em;color:var(--text-3);padding-top:0}
.row.lesson .lt{font-size:16px;font-weight:500;letter-spacing:-.012em;line-height:1.35}
.row.lesson .ls{
  margin-top:4px;font-size:13.5px;line-height:1.5;color:var(--text-3);
  max-width:56ch;
  /* an ahead lesson shows its title and nothing else — the detail is the
     lesson, and giving it away on the map is giving away the product */
}
.row.lesson .rt{font-family:var(--mono);font-size:11px;font-weight:500;letter-spacing:.12em;text-transform:uppercase;color:var(--text-3);white-space:nowrap;padding-top:3px}

/* cleared — green, and only here */
.row.lesson.done .ic{background:var(--verified-dim);border-color:rgba(48,209,88,.32);color:var(--verified)}
.row.lesson.done .rt{color:var(--verified)}

/* current — full white, the only row at full strength */
.row.lesson.now{background:rgba(255,255,255,.035)}
.row.lesson.now .ic{background:var(--text);border-color:var(--text);color:#000;font-weight:600}
.row.lesson.now .lt{font-weight:600}
.row.lesson.now .rt{color:var(--text)}

/* ahead — present, legible, plainly not yours yet. Dimmed, never red:
   a lesson you have not reached is not a failure. */
.row.lesson.ahead{opacity:.5}
.row.lesson.ahead .rt{letter-spacing:.1em}
.row.lesson.ahead .lt{font-weight:400}

.row.rule{align-items:flex-start;padding-top:13px;padding-bottom:13px}
.row.rule .ic{font-size:11px;color:var(--text-3);padding-top:0}
.row.rule p{font-size:15px;line-height:1.55;color:var(--text-2)}

/* The old single-card placement gate lived here — .gatecard / .gate-in /
   .gate-t / .gate-btns. It was replaced by the full-screen placement SECTION
   (see below) and by the .gate card further down, and no markup has referenced
   any of it since. Deleted rather than left: the one live class it still fed
   was .gate-p, which the new gate card also declares, so the two were quietly
   fighting over the same selector from opposite ends of the file. */

/* ============================================================
   THE WELCOME + THE NEXT SESSION
   ============================================================ */
.hello{padding:6px 2px 2px}
.hello-eyebrow{letter-spacing:.16em;color:var(--text-3);margin-bottom:10px;display:block}
.hello-t{font-size:clamp(28px,5vw,44px);font-weight:600;letter-spacing:-.035em;line-height:1.08}
.hello-p{margin-top:12px;font-size:16.5px;line-height:1.6;color:var(--text-2);max-width:62ch}

/* The next live session. The one card on the page that is allowed to shout,
   because missing it is the only thing a member can do that cannot be undone. */
.nextcard{border-color:rgba(255,255,255,.17);background:rgba(255,255,255,.05)}
.next-in{
  display:grid;grid-template-columns:1fr auto;gap:22px;align-items:center;
  padding:clamp(22px,3.4vw,30px) var(--pad-in);
}
.next-in .lbl{
  display:block;font-family:var(--mono);font-size:11px;font-weight:500;
  text-transform:uppercase;letter-spacing:.14em;color:var(--text-3);margin-bottom:11px;
}
.next-t{font-size:clamp(20px,2.6vw,27px);font-weight:600;letter-spacing:-.025em;line-height:1.2}
.next-when{margin-top:10px;color:var(--text);font-size:13px;letter-spacing:.06em}
.next-tz{margin-top:4px;color:var(--text-3)}

.countdown{
  display:flex;flex-direction:column;align-items:center;justify-content:center;gap:2px;
  min-width:104px;padding:16px 14px;border-radius:var(--r-2);
  background:var(--s-2);border:1px solid var(--line);box-shadow:var(--toplight);
}
.countdown b{font-size:34px;font-weight:600;letter-spacing:-.04em;line-height:1}
.countdown .dat{font-size:10px;letter-spacing:.11em;color:var(--text-3);text-align:center}
/* live is the one moment green is right here: a human is actually in the room */
/* NOT green, though it was. This file's own header says green marks a cleared
   lesson and a granted pass, "never availability" — and a call being live right
   now is exactly availability. It gets urgency from weight and a white edge
   instead, which is what the rest of the site does with a live state. */
.countdown.live{background:var(--s-3);border-color:var(--text)}
.countdown.live b{font-size:22px;color:var(--text)}
.countdown.live .dat{color:var(--text)}
/* A member who was HELD is barred from the room that is live right now. The
   card is already red-edged for exactly that reason, and a green NOW pulsing
   in the corner of it invited them to a call they are not allowed in — two
   opposite signals on one surface. On a behind card the countdown goes quiet. */
.nextcard.behind .countdown,
.nextcard.behind .countdown.live{background:var(--s-1);border-color:var(--line)}
.nextcard.behind .countdown b,
.nextcard.behind .countdown .dat{color:var(--text-3)}

/* behind the room — red, because this IS the locked/failed state */
.nextcard.behind{border-color:rgba(255,69,58,.3);background:rgba(255,69,58,.05)}
.nextcard.behind .next-tz{color:var(--fail)}

.next-foot{
  display:flex;align-items:center;gap:14px;flex-wrap:wrap;
  padding:16px var(--pad-in);border-top:1px solid var(--line);background:rgba(255,255,255,.022);
}
@media(max-width:620px){
  .next-in{grid-template-columns:1fr;gap:18px}
  .countdown{align-self:start;flex-direction:row;gap:9px;align-items:baseline;min-width:0;padding:12px 16px}
  .countdown b{font-size:26px}
}

/* ---- the session list ---- */
.row.sess{align-items:center;padding-top:14px;padding-bottom:14px}
.row.sess .ic{font-family:var(--mono);font-size:12px;color:var(--text-3);padding-top:0}
.row.sess .lt{font-size:15.5px;font-weight:500;letter-spacing:-.012em}
.row.sess .ls{margin-top:3px;font-family:var(--mono);font-size:11.5px;letter-spacing:.04em;color:var(--text-3)}
.row.sess .rt{font-family:var(--mono);font-size:10.5px;font-weight:500;letter-spacing:.12em;color:var(--text-3);white-space:nowrap}
.row.sess.now{background:rgba(255,255,255,.045)}
.row.sess.now .ic{background:var(--text);border-color:var(--text);color:#000;font-weight:600}
.row.sess.now .lt{font-weight:600}
.row.sess.now .rt{color:var(--text)}
.row.sess.past{opacity:.45}
/* NOT green. This row goes "past" because the calendar moved, which is not the
   same as anybody verifying anything — and green on this site means exactly
   one thing. The verified colour lives on passes, and nowhere else. */
.row.sess.past .rt{color:var(--text-3)}

/* ============================================================
   THE PLACEMENT SCREEN — four sealed doors
   Reo's photographs, held down in the black. The point is that all four look
   equally possible and none of them is yours yet; the drama is entirely in
   the state change when one becomes yours.

   Each card carries its path hue as a duotone push and a single edge light —
   identity, never state, which is the one job these hues have.
   ============================================================ */
.placement{display:flex;flex-direction:column;gap:clamp(26px,4vw,40px);padding:8px 0 20px}
.pl-eyebrow{letter-spacing:.18em;color:var(--text-3)}
.pl-t{font-size:clamp(30px,5.4vw,50px);font-weight:600;letter-spacing:-.035em;line-height:1.05;margin-top:12px}
.pl-p{margin-top:14px;font-size:16.5px;line-height:1.6;color:var(--text-2);max-width:56ch}

/* Four across, always — a 3+1 wrap makes one path look like an afterthought,
   and these four are meant to read as equally possible. Two-up below 900. */
.pl-grid{display:grid;grid-template-columns:repeat(4,1fr);gap:14px}
@media(max-width:900px){.pl-grid{grid-template-columns:repeat(2,1fr)}}

.pl-card{
  position:relative;overflow:hidden;isolation:isolate;
  aspect-ratio:4/5;border-radius:var(--r-3);
  border:1px solid var(--line);background:#050506;
  display:flex;flex-direction:column;justify-content:flex-end;
  padding:20px;
  transition:transform var(--d-element) var(--ease),border-color var(--d-tint) ease;
}
/* the photograph, pushed right down — present, not readable */
.pl-card img{
  position:absolute;inset:0;width:100%;height:100%;object-fit:cover;z-index:-2;
  filter:grayscale(.55) brightness(.34) contrast(1.08);
  transition:filter var(--d-seq) var(--ease),transform var(--d-seq) var(--ease);
}
/* the hue wash — this is what makes four different photographs one system */
.pl-card:after{
  content:"";position:absolute;inset:0;z-index:-1;pointer-events:none;
  background:
    linear-gradient(180deg, transparent 30%, rgba(0,0,0,.82) 100%),
    linear-gradient(180deg, color-mix(in srgb, var(--hue) 26%, transparent) 0%, transparent 62%);
}
/* one edge light, the path's own colour */
.pl-card:before{
  content:"";position:absolute;left:0;top:16%;bottom:16%;width:2px;z-index:1;
  background:var(--hue);opacity:.75;border-radius:2px;
}
.pl-name{font-family:var(--mono);font-size:12.5px;font-weight:500;letter-spacing:.16em;color:var(--text)}
/* two lines reserved, so the four NAMES sit on one line across the row —
   bottom-aligned blocks with different wrap counts push the names to
   different heights, which reads as sloppy rather than as variety */
.pl-tag{margin-top:7px;font-size:13.5px;line-height:1.45;color:var(--text-2);max-width:24ch;min-height:2.9em}
.pl-seal{
  position:absolute;top:16px;right:16px;z-index:1;
  font-family:var(--mono);font-size:9.5px;letter-spacing:.14em;color:var(--text-3);
  padding:5px 9px;border-radius:var(--r-pill);
  background:rgba(0,0,0,.5);border:1px solid var(--line);backdrop-filter:blur(10px);
}
@media(hover:hover){
  .pl-card:hover{transform:translateY(-3px);border-color:var(--line-strong)}
  .pl-card:hover img{filter:grayscale(.3) brightness(.5) contrast(1.05);transform:scale(1.03)}
}

/* ---- the action ---- */
.pl-act{display:flex;flex-direction:column;gap:22px;align-items:flex-start;max-width:420px}
.pl-act > .btn{width:100%}
.pl-key{width:100%}
.pl-keyrow{display:flex;gap:10px}
.pl-keyrow input{
  flex:1;min-width:0;font-family:var(--mono);
  /* 16px, not 15 — iOS Safari zooms the whole page when a field under 16px
     takes focus, and the two key inputs are the only fields a member ever
     types into. */
  font-size:16px;letter-spacing:.14em;text-transform:uppercase;
  background:var(--s-2);border:1px solid var(--line);border-radius:var(--r-2);
  padding:14px 16px;color:var(--text);
}
.pl-keyrow input:focus{border-color:var(--line-strong);background:var(--s-3)}
/* `outline:none` used to sit in the rule above, which killed the focus ring on
   both key inputs. Focus is a law here (protocol.css §focus): it is restated
   rather than removed. */
.pl-keyrow input:focus-visible{outline:2px solid var(--text);outline-offset:2px}
.pl-keyrow input::placeholder{color:var(--text-3);letter-spacing:.14em}
.pl-keyrow .btn{flex:none}
#plMsg,#gateMsg{display:block;margin-top:10px}
#plMsg.ok,#gateMsg.ok{color:var(--verified)}
#plMsg.no,#gateMsg.no{color:var(--fail)}
.pl-foot{margin-top:4px;color:var(--text-3)}

/* ---- the three beats ----
   The same mechanic runs every gate in the course, so it gets one shape and is
   never re-explained in prose. Numbers sit in the margin so the sentences line
   up as a column of statements rather than a bulleted list. */
/* padding-left:0 matters: this is an <ol>, and the UA's 40px start padding was
   pushing all three beats a clear 40px right of every other block on the card.
   The numbers are drawn by .howto-n, absolutely positioned in the 40px well
   .howto li reserves for itself. */
.howto{list-style:none;padding-left:0;margin:0;display:flex;flex-direction:column;gap:14px;max-width:62ch}
.howto li{
  position:relative;padding-left:40px;
  font-size:15px;line-height:1.55;color:var(--text-2);
}
.howto li b{color:var(--text);font-weight:500}
.howto-n{
  position:absolute;left:0;top:1px;font-size:11px;letter-spacing:.14em;color:var(--text-3);
}
.howto.tight{gap:11px;margin:18px 0 22px}
.howto.tight li{font-size:14.5px}

/* ---- the gate ---- */
.gate .cbody{display:flex;flex-direction:column}
.gate-p{font-size:15.5px;line-height:1.6;color:var(--text-2);max-width:var(--measure)}
/* Work passed, call outstanding. A lifted edge and nothing else — this is a
   good moment, and it must not be green: green on this site means a human
   verified something, and the verification is what got them HERE. Colouring
   the waiting state with it would say the wrong thing twice. */
.gate.ready{border-color:var(--line-strong);background:var(--s-1)}
.gate.ready .card-head{background:rgba(255,255,255,.04)}

.gate .pl-key{max-width:420px}
@media(max-width:600px){.gate .pl-key{max-width:none}}

/* At 320px an 8-character key, a 16px mono face and a 96px Unlock button do not
   fit on one line — the field clipped the code as it was typed, which is the
   worst possible moment for it. Below 380px the button takes its own row. */
@media(max-width:380px){
  .pl-keyrow{flex-wrap:wrap}
  .pl-keyrow input{flex:1 1 100%}
  .pl-keyrow .btn{flex:1 1 100%}
}

@media(max-width:600px){
  .pl-grid{gap:10px}
  .pl-card{padding:14px;aspect-ratio:3/4}
  .pl-name{font-size:11px}
  .pl-tag{font-size:12px}
  .pl-act{max-width:none}
}

/* ============================================================
   THE TRACK — the path, running left to right
   Nine stops on one rail. It reads as a journey rather than a checklist,
   and it is the same component the about page uses to tell the story.

   COLOUR, strictly:
     the RAIL carries the path's hue — identity, which is the only job a
     path hue is allowed to do
     a PASSED stop is green — a human granted it, which is the only thing
     green ever means here
     the CURRENT stop is white — the brightest thing on the rail
     a LOCKED stop is a hollow ring at low light — dim, never red, because
     not having arrived somewhere is not a failure

   State never rests on colour alone: passed carries a tick, current is
   larger and ringed, locked carries a padlock.
   ============================================================ */
.track{
  --hue:var(--text-2);
  position:relative;
  display:flex;align-items:flex-start;gap:0;
  overflow-x:auto;overscroll-behavior-x:contain;
  padding:34px var(--pad-in) 26px;
  scroll-snap-type:x proximity;scrollbar-width:none;
  -webkit-overflow-scrolling:touch;
}
.track::-webkit-scrollbar{display:none}

/* one stop = a fixed-width column: node on the rail, label beneath */
/* The stops are <li> now (see pathway.js — an aria-label on a role-less div is
   dropped entirely). role="list" is set on .track in JS; these two lines stop
   the UA drawing markers into a horizontal rail. */
.track{list-style:none;padding-left:0;margin:0}
.stop{
  position:relative;flex:0 0 var(--stop-w,132px);
  display:flex;flex-direction:column;align-items:center;gap:14px;
  scroll-snap-align:center;
  /* --lift moves a stop off the centre line. It is what makes four paths four
     different journeys rather than one component reskinned four times, and it
     works in greyscale — the hue is the LAST carrier of identity, not the
     first. Set per path below. */
  transform:translateY(var(--lift,0));
}

/* ---- each path routes differently ----
   EXECUTION  a dead-straight line. It is the path about not deviating.
   BODY       an even alternation. Reps.
   ATTRACTION mirrored pairs — out and back, out and back.
   DIRECTION  one long sweep across the whole run. Navigation, not repetition. */
.track[data-path="execution"] .stop{--lift:0}

.track[data-path="body"] .stop:nth-child(odd){--lift:-9px}
.track[data-path="body"] .stop:nth-child(even){--lift:9px}

.track[data-path="attraction"] .stop:nth-child(4n+1),
.track[data-path="attraction"] .stop:nth-child(4n+2){--lift:-8px}
.track[data-path="attraction"] .stop:nth-child(4n+3),
.track[data-path="attraction"] .stop:nth-child(4n+4){--lift:8px}

.track[data-path="direction"] .stop:nth-child(1){--lift:14px}
.track[data-path="direction"] .stop:nth-child(2){--lift:10px}
.track[data-path="direction"] .stop:nth-child(3){--lift:5px}
.track[data-path="direction"] .stop:nth-child(4){--lift:0}
.track[data-path="direction"] .stop:nth-child(5){--lift:-5px}
.track[data-path="direction"] .stop:nth-child(6){--lift:-9px}
.track[data-path="direction"] .stop:nth-child(7){--lift:-12px}
.track[data-path="direction"] .stop:nth-child(8){--lift:-14px}
.track[data-path="direction"] .stop:nth-child(9){--lift:-15px}

/* the waypoint's own form also differs, so the paths stay distinct with the
   colour removed entirely */
.track[data-path="body"] .stop-node{border-radius:9px}          /* squircle */
.track[data-path="direction"] .stop-node{border-radius:5px;transform:rotate(45deg)}
.track[data-path="direction"] .stop-node > *{transform:rotate(-45deg)}

@media(prefers-reduced-motion:reduce){.stop{transform:none}}

/* THE RAIL — drawn by each stop as a segment reaching back to the previous
   one, so the line and the nodes can never fall out of alignment the way two
   separately-positioned elements would. */
.stop + .stop::before{
  content:"";position:absolute;top:15px;right:50%;width:100%;height:1px;
  background:var(--line);
}
/* lit as far as you have actually travelled */
.stop.done + .stop::before,
.stop.done + .stop.now::before{background:var(--hue);opacity:.55}
.stop.done + .stop.done::before{background:var(--hue);opacity:.55}

.stop-node{
  position:relative;z-index:1;
  width:31px;height:31px;border-radius:50%;
  display:grid;place-items:center;
  background:var(--bg);border:1px solid var(--line-strong);
  font-family:var(--mono);font-size:11px;color:var(--text-3);
  transition:transform var(--d-control) var(--ease);
}
.stop-lab{
  text-align:center;max-width:118px;
  font-size:12.5px;line-height:1.35;color:var(--text-3);
  letter-spacing:-.005em;
}
.stop-n{
  display:block;font-family:var(--mono);font-size:9.5px;letter-spacing:.14em;
  color:var(--text-3);opacity:.7;margin-bottom:4px;
}

/* ---- passed ---- */
.stop.done .stop-node{
  background:var(--verified-dim);border-color:rgba(48,209,88,.45);color:var(--verified);
}
.stop.done .stop-node:after{content:"✓";font-size:12px;line-height:1}
.stop.done .stop-node span{display:none}
.stop.done .stop-lab{color:var(--text-2)}

/* ---- current — the brightest thing on the rail ---- */
.stop.now .stop-node{
  width:39px;height:39px;margin-top:-4px;
  background:var(--text);border-color:var(--text);color:#000;font-weight:600;font-size:12.5px;
  box-shadow:0 0 0 5px rgba(255,255,255,.09), 0 6px 22px -6px rgba(255,255,255,.35);
}
.stop.now .stop-lab{color:var(--text);font-weight:550}

/* ---- locked ---- */
.stop.locked .stop-node{border-style:dashed;opacity:.55}
.stop.locked .stop-node span{opacity:.6}
/* was opacity .42 on --text-2, which computed to about 1.8:1 against the panel
   — below any readability threshold, on the labels telling a member what is
   still ahead of them. Locked reads as locked from the dashed node and the
   padlock; the words themselves have to stay legible. */
.stop.locked .stop-lab{opacity:1;color:var(--text-3)}
.stop.locked .stop-lab .stop-n:after{content:" 🔒";letter-spacing:0}

/* the rail should fade out at the edges rather than stop dead, so it reads as
   continuing rather than as a component that ends */
.trackwrap{position:relative}
.trackwrap:before,.trackwrap:after{
  content:"";position:absolute;top:0;bottom:0;width:38px;pointer-events:none;z-index:2;
}
.trackwrap:before{left:0;background:linear-gradient(90deg,var(--bg),transparent)}
.trackwrap:after{right:0;background:linear-gradient(270deg,var(--bg),transparent)}

@media(max-width:600px){
  .track{--stop-w:112px;padding-top:28px}
  .stop-lab{font-size:11.5px;max-width:100px}
}

/* ============================================================
   ROSTER — position as a pip strip. Never ordered by progress.
   ============================================================ */
.row.man .ic{font-size:13px;font-weight:600;color:var(--text-2);font-family:var(--sans)}
.row.man .lt{font-size:15.5px;font-weight:500;letter-spacing:-.01em}
.row.man .ls{margin-top:3px;font-family:var(--mono);font-size:11px;letter-spacing:.1em;text-transform:uppercase;color:var(--text-3)}
.row.man.you{background:rgba(255,255,255,.045)}
.row.man.you .ic{background:var(--text);border-color:var(--text);color:#000}

.pips{display:flex;gap:4px;align-items:center}
.pip{width:7px;height:7px;border-radius:50%;background:var(--s-3);flex:none}
.pip.on{background:var(--verified)}
.pip.at{background:var(--text);box-shadow:0 0 0 3px rgba(255,255,255,.12)}
.pips .wait{font-family:var(--mono);font-size:10.5px;font-weight:500;letter-spacing:.12em;text-transform:uppercase;color:var(--text-3)}
@media(max-width:520px){.pips .pip{width:6px;height:6px;gap:3px}}

/* ============================================================
   EVIDENCE
   ============================================================ */
.evreq{
  font-size:14.5px;line-height:1.6;color:var(--text-2);
  padding:14px 16px;margin-bottom:20px;
  background:var(--s-2);border:1px solid var(--line);border-radius:var(--r-1);
}
.evreq b{color:var(--text);font-weight:600}
.fl{display:block;font-family:var(--mono);font-size:11px;font-weight:500;text-transform:uppercase;letter-spacing:.13em;color:var(--text-3);margin:0 0 8px}
.fl .opt{text-transform:none;letter-spacing:.02em;opacity:.7}
.pathway textarea,.pathway input[type=url]{
  width:100%;font-family:var(--sans);font-size:16px;line-height:1.55;color:var(--text);
  background:var(--s-2);border:1px solid var(--line);border-radius:var(--r-2);
  padding:14px 16px;margin-bottom:20px;resize:vertical;
  transition:border-color var(--d-tint) ease,background var(--d-tint) ease;
}
.pathway textarea:focus,.pathway input[type=url]:focus{
  border-color:var(--line-strong);background:var(--s-3);
}
/* `outline:none` used to sit in the rule above. The border it swapped in goes
   from .10 to .20 alpha on black — about 1.5:1, which is not a focus indicator,
   it is a hint. Unlike the booking form (protocol.css §.f, where a lifted row
   IS the indicator), nothing else here marks focus, so the ring stays. */
.pathway textarea:focus-visible,.pathway input[type=url]:focus-visible{
  outline:2px solid var(--text);outline-offset:2px;
}
.pathway textarea::placeholder,.pathway input::placeholder{color:var(--text-3)}
.evrow{display:flex;align-items:center;gap:16px;flex-wrap:wrap}
.evfoot{margin-top:16px}
/* ---- the repair loop ----
   A hold is a "not yet", not a failure, and the surface has to read that way:
   one sentence set large enough to be the point of the card, on a lifted
   surface with a neutral rule. NOT red — red is reserved for locked/failed,
   and painting the fix red would tell someone their work is the problem when
   the whole design of a hold is that ONE thing is. */
.repair{
  margin-bottom:20px;padding:18px 20px;border-radius:var(--r-tile);
  background:var(--s-2);border:1px solid var(--line-strong);
  border-left:2px solid var(--text-2);
}
.repair-lbl{display:block;letter-spacing:.16em;color:var(--text-3)}
.repair-t{
  margin-top:10px;font-size:17.5px;line-height:1.45;color:var(--text);
  letter-spacing:-.012em;text-wrap:pretty;
}
.repair-p{margin-top:11px;font-size:14.5px;line-height:1.55;color:var(--text-2);text-wrap:pretty}

/* the deadline under the next session in the schedule */
.lsdue{margin-top:4px;letter-spacing:.13em;color:var(--text-3)}
.row.sess.now .lsdue{color:var(--text-2)}

.evstate-ok{color:var(--verified)}
.evstate-no{color:var(--fail)}

/* Was justify-content:space-between with exactly two children. It now carries
   six links, and space-between would fling them to the corners of a wide
   screen. The note claims the row, the links follow it and wrap together. */
.cfoot{
  display:flex;align-items:center;gap:10px 18px;
  padding-top:12px;flex-wrap:wrap;
}
.cfoot > span:first-child{margin-right:auto}
.cfoot a{color:var(--text-3);text-decoration:none;border-bottom:1px solid var(--line)}
.cfoot a:hover{color:var(--text-2)}
@media(max-width:620px){
  .cfoot{gap:8px 14px}
  .cfoot > span:first-child{margin-right:0;flex-basis:100%}
}
/* Six links on one line on a phone, each one line of 11px text tall. The
   site-wide coarse-pointer floor never reached them because it is scoped to
   selectors these two footers do not use. */
.cfoot a,.wfoot a{display:inline-flex;align-items:center;min-height:32px}
@media(pointer:coarse){.cfoot a,.wfoot a{min-height:44px}}

/* The welcome page's own foot — the legal links have to be reachable from the
   screen someone lands on straight after paying, not one navigation away.

   It has to be FIXED and above .cstate, not in normal flow: every state on that
   page is `position:fixed; inset:0` with an opaque background, so a footer in
   the flow behind them was painted and then completely covered. It looked
   correct in the markup and did not exist on screen. */
.wfoot{
  position:fixed;left:0;right:0;bottom:0;z-index:30;
  display:flex;flex-wrap:wrap;justify-content:center;gap:10px 20px;
  padding:0 var(--pad-x) 28px;
  padding-bottom:calc(28px + env(safe-area-inset-bottom));
}
/* and the states have to leave room for it rather than centre content under it */
.cstate{padding-bottom:calc(var(--pad-x) + 76px)}
.wfoot a{color:var(--text-3);text-decoration:none;border-bottom:1px solid var(--line)}
.wfoot a:hover{color:var(--text-2)}

/* header emoji in a .card-head — sized off the mono label, per the emoji layer */
.hem{font-size:var(--em-label);line-height:1}

/* ============================================================
   THE CHAPTER GRID (2026-08-19)

   Replaced the path map, the schedule rail, the gate card and the room
   roster — all four belonged to cohorts and sealed modules.

   The one rule this component exists to hold: THE BAR AND THE VERDICT ARE
   DIFFERENT THINGS AND MUST LOOK IT. The bar is white-on-grey and says
   nothing about quality; green appears only on `.is-verified`, and only a
   human can put it there. Never style a full bar as green.
   ============================================================ */
.chapters{display:flex;flex-direction:column;gap:12px;margin-bottom:22px}

.chcard{
  background:var(--s-1);border:1px solid var(--line);border-radius:var(--r-card);
  overflow:hidden;position:relative;
}
.chcard:before{content:"";position:absolute;left:0;top:0;bottom:0;width:3px;background:var(--h);opacity:.55}
.chcard.is-verified{border-color:rgba(48,209,88,.3)}
.chcard.is-verified:before{background:var(--verified);opacity:1}

.chhead{
  width:100%;display:grid;gap:4px 12px;align-items:center;text-align:left;
  grid-template-columns:auto auto 1fr;grid-template-areas:"num glyph mid" "bar bar bar" "state state state";
  background:none;border:0;color:inherit;cursor:pointer;padding:16px 18px 14px 21px;font:inherit;
}
.chhead:hover{background:var(--s-2)}
.chnum{grid-area:num;font-size:11px;letter-spacing:.1em;color:var(--glow);opacity:.6}
/* The same iOS tinted tile as the landing page, so the two surfaces are
   visibly one system rather than two that happen to share a palette. */
.chglyph{
  grid-area:glyph;width:38px;height:38px;display:grid;place-items:center;
  font-size:19px;line-height:1;border-radius:var(--r-field);
  background:color-mix(in srgb,var(--h) 15%,transparent);
  border:1px solid color-mix(in srgb,var(--h) 22%,transparent);
}
.chmid{grid-area:mid;display:flex;flex-direction:column;gap:2px;min-width:0}
.chname{font-size:16.5px;font-weight:600;letter-spacing:-.015em}
.chtag{font-size:12.5px;color:var(--text-3)}

.chbar{grid-area:bar;position:relative;height:5px;border-radius:var(--r-pill);background:rgba(255,255,255,.1);overflow:hidden;margin-top:11px}
.chbar i{display:block;height:100%;background:var(--text-3);border-radius:var(--r-pill);transition:width var(--d-element) var(--ease)}
/* Green on the bar ONLY once a human has verified — never on a full bar. */
.chcard.is-verified .chbar i{background:var(--verified)}
.chstate{grid-area:state;font-size:10.5px;letter-spacing:.07em;color:var(--text-3);margin-top:8px}
.chstate.ok{color:var(--verified)}

.chbody{padding:4px 18px 20px 21px;border-top:1px solid var(--line)}
.chblurb{font-size:13.5px;line-height:1.55;color:var(--text-2);margin:14px 0 16px}

.chlessons{list-style:none;display:flex;flex-direction:column;gap:2px;margin:0 0 20px;padding:0}
.chl{
  display:grid;grid-template-columns:auto 1fr auto;gap:4px 10px;align-items:start;
  padding:9px 0;border-bottom:1px solid var(--line);
}
.chl:last-child{border-bottom:0}
/* 15px is a 15px tap target. The box stays visually small — it sits in a
   dense list — but the touch area is padded out to a usable size without
   changing the layout. */
.chtick{margin-top:3px;accent-color:var(--glow);width:15px;height:15px;cursor:pointer;position:relative}
.chtick:before{content:"";position:absolute;left:50%;top:50%;width:44px;height:44px;transform:translate(-50%,-50%)}
.chl-l{display:flex;gap:9px;align-items:baseline;cursor:pointer;min-width:0}
.chl-n{font-size:10.5px;color:var(--text-3);flex:none}
.chl-t{font-size:14px;line-height:1.4}
.chtick:checked + .chl-l .chl-t{color:var(--text-3)}
/* Honest empty state. The row is present, readable and tickable — it is not
   dimmed into looking disabled, because nothing here is withheld. */
/* 9.5px at --text-3 with opacity .75 composited to 3.38:1 — under the 4.5:1
   AA floor for text this size. The honest "NOT FILMED YET" state is exactly
   the label that must not be hard to read, so the opacity is gone and the
   colour steps up. */
.chl-soon{font-size:10px;letter-spacing:.08em;color:var(--text-2);border:1px solid var(--line);border-radius:var(--r-pill);padding:2px 7px;flex:none}
.chl-ev{grid-column:2/-1;font-size:12px;line-height:1.45;color:var(--text-3);margin:0}

.chev{border-top:1px solid var(--line);padding-top:17px}
.chev-lbl{display:block;font-size:10.5px;letter-spacing:.07em;margin-bottom:6px}
.chev-p{font-size:13px;line-height:1.5;color:var(--text-2);margin:0}
.chev-ok{background:rgba(48,209,88,.06);border:1px solid rgba(48,209,88,.26);border-radius:var(--r-tile);padding:14px 15px}
.chev-ok .chev-lbl{color:var(--verified)}
.chev-filed{background:var(--s-2);border:1px solid var(--line);border-radius:var(--r-tile);padding:13px 15px;margin-bottom:15px}
.chev-req{font-size:12.5px;line-height:1.5;color:var(--text-3);margin:0 0 15px}
.chev-note,.chev-link{
  width:100%;background:var(--s-2);border:1px solid var(--line);border-radius:var(--r-tile);
  color:var(--text);font:inherit;font-size:14px;padding:11px 13px;margin-bottom:13px;resize:vertical;
}
.chev-note:focus,.chev-link:focus{outline:none;border-color:var(--line-strong)}
.chev-row{display:flex;align-items:center;gap:13px;flex-wrap:wrap}
.chev-state{font-size:11px;letter-spacing:.06em;color:var(--text-3)}
.chev-foot{font-size:10.5px;letter-spacing:.05em;color:var(--text-3);margin-top:12px;opacity:.8}

@media(max-width:560px){
  .chhead{padding:14px 15px 13px 18px}
  .chbody{padding:4px 15px 18px 18px}
}

/* ---- the photograph, in the Console ----
   Same asset and same tint as the landing page, so a member recognises the
   card he clicked. It lives INSIDE .chhead, so it covers the header exactly
   however tall the header happens to be — no hardcoded height to fall out of
   step with a wrapped chapter name.

   The expanded body is deliberately clean: a lesson list and an evidence form
   over a portrait is unreadable, and the eye should be on the work. */
.chcard{isolation:isolate}
.chhead{position:relative;isolation:isolate}
.chhead > *{position:relative;z-index:3}
.chhead .pshot{
  position:absolute;z-index:0;inset:0 0 0 auto;width:34%;
  overflow:hidden;pointer-events:none;border-radius:0;
}
.chhead .pshot img{
  width:100%;height:100%;object-fit:cover;object-position:52% 18%;display:block;
  filter:grayscale(1) contrast(1.1) brightness(.5);
}
.chhead .pshot:before{content:"";position:absolute;inset:0;background:var(--h);mix-blend-mode:color;opacity:.8}
/* Scrim across the whole header, not just the panel — a scrim only as wide as
   the photograph leaves a hard vertical seam (same bug, same fix, as the
   landing page). */
.chhead:after{
  content:"";position:absolute;z-index:1;inset:0;pointer-events:none;
  background:linear-gradient(90deg,rgba(9,9,10,.96) 46%,rgba(10,10,11,.88) 66%,rgba(10,10,11,.4) 86%,rgba(0,0,0,0) 100%);
}
.chhead .pshot,.chhead:after{transition:opacity var(--d-element) var(--ease)}
.chhead[aria-expanded="true"] .pshot,
.chhead[aria-expanded="true"]:after{opacity:0}

/* ============================================================
   THE LESSON PAGE

   One lesson, one URL. Narrower measure than the Pathway because this page is
   read rather than scanned, and the film wants to be the widest thing on it.
   ============================================================ */
.lwrap{max-width:760px}
.lback{
  font-size:13.5px;color:var(--text-2);text-decoration:none;
  padding:6px 12px;border-radius:var(--r-pill);border:1px solid var(--line);
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis;max-width:46vw;
}
.lback:hover{color:var(--text);border-color:var(--line-strong)}

.lhead{padding:8px 2px 22px}
.leyebrow{display:block;letter-spacing:.16em;color:var(--text-3);margin-bottom:11px}
.lt{font-size:clamp(26px,4.4vw,40px);font-weight:600;letter-spacing:-.035em;line-height:1.1;text-wrap:balance}
.lleaves{margin-top:14px;font-size:16.5px;line-height:1.6;color:var(--text-2);max-width:60ch}

/* ---- the film ---- */
.lfilm{margin-bottom:14px}
.lvideo{
  position:relative;border-radius:var(--r-card);overflow:hidden;
  border:1px solid var(--line);background:#000;
}
.lvideo video{display:block;width:100%;aspect-ratio:16/9;background:#000}

/* Honest reserved state. Deliberately NOT red and deliberately not a disabled
   play button — nothing has failed and nothing is being withheld; the film
   simply does not exist yet, and the brief below is genuinely enough to work
   from. */
.lsoon{
  border:1px solid var(--line);border-radius:var(--r-card);background:var(--s-1);
  padding:34px 28px;text-align:center;
}
.lsoon-mark{font-size:26px;line-height:1;display:block;margin-bottom:14px;opacity:.75}
.lsoon-t{font-size:17px;font-weight:600;letter-spacing:-.02em;margin-bottom:9px}
.lsoon-p{font-size:14px;line-height:1.6;color:var(--text-2);max-width:52ch;margin:0 auto}

/* ---- the PDF ---- */
.lpdf{
  display:flex;align-items:center;gap:14px;text-decoration:none;color:inherit;
  border:1px solid var(--line);border-radius:var(--r-tile);background:var(--s-1);
  padding:15px 17px;margin-bottom:22px;
  transition:border-color var(--d-tint) ease,background var(--d-tint) ease;
}
.lpdf:hover{border-color:var(--line-strong);background:var(--s-2)}
.lpdf-ic{
  width:38px;height:38px;flex:none;display:grid;place-items:center;font-size:18px;
  border-radius:var(--r-field);
  background:color-mix(in srgb,var(--h) 15%,transparent);
  border:1px solid color-mix(in srgb,var(--h) 22%,transparent);
}
.lpdf-tx{display:flex;flex-direction:column;gap:3px;min-width:0;flex:1}
.lpdf-tx b{font-size:14.5px;font-weight:600;letter-spacing:-.01em}
.lpdf-tx span{font-size:12.5px;color:var(--text-3);line-height:1.4}
.lpdf-go{font-size:10.5px;letter-spacing:.12em;color:var(--text-3);flex:none}
.lpdf:hover .lpdf-go{color:var(--h)}

/* ---- evidence ---- */
.levcard{margin-bottom:16px}
.lev{font-size:15px;line-height:1.6}
.lev-note{margin-top:13px;font-size:13px;line-height:1.55;color:var(--text-3)}
.levcard .btn{margin-top:17px}

/* ---- mark done ---- */
.ldone{
  display:flex;align-items:center;justify-content:space-between;gap:14px;flex-wrap:wrap;
  border:1px solid var(--line);border-radius:var(--r-tile);background:var(--s-1);
  padding:16px 18px;margin-bottom:26px;
}
.ldone-row{display:flex;align-items:flex-start;gap:12px;cursor:pointer;flex:1;min-width:0}
.ldone-tx{display:flex;flex-direction:column;gap:3px}
.ldone-tx b{font-size:14.5px;font-weight:600;letter-spacing:-.01em}
.ldone-tx span{font-size:12.5px;line-height:1.5;color:var(--text-3)}
#lDoneState{font-size:10.5px;letter-spacing:.1em;color:var(--text-3);flex:none}

/* ---- prev / next ---- */
.lrail{display:grid;grid-template-columns:1fr 1fr;gap:12px;margin-bottom:30px}
@media(max-width:620px){.lrail{grid-template-columns:1fr}}
.lrail-a{
  display:flex;flex-direction:column;gap:6px;text-decoration:none;color:inherit;
  border:1px solid var(--line);border-radius:var(--r-tile);background:var(--s-1);
  padding:15px 17px;min-width:0;
  transition:border-color var(--d-tint) ease,background var(--d-tint) ease;
}
.lrail-a:hover{border-color:var(--line-strong);background:var(--s-2)}
.lrail-a .dat{font-size:10px;letter-spacing:.14em;color:var(--text-3)}
.lrail-a b{font-size:14px;font-weight:600;letter-spacing:-.015em;line-height:1.35}
/* next sits right and reads right, so the pair works as a spread */
.lrail-a.is-next,.lrail-a.is-end{text-align:right;grid-column:2}
@media(max-width:620px){.lrail-a.is-next,.lrail-a.is-end{grid-column:1;text-align:left}}

/* The lesson title is a link out to the lesson page; the tick stays a tick.
   `.chl-l` was a <label> — clicking the title toggled the checkbox, which
   meant a man could not open a lesson without also claiming he had done it. */
.chl-l{text-decoration:none;color:inherit;flex:1}
.chl-l:hover .chl-t{color:var(--h)}
.chl-go{
  width:6px;height:6px;flex:none;align-self:center;margin-left:2px;
  border-right:1.5px solid var(--text-3);border-bottom:1.5px solid var(--text-3);
  transform:rotate(-45deg);opacity:0;
  transition:opacity var(--d-tint) ease,transform var(--d-tint) ease;
}
.chl-l:hover .chl-go{opacity:1;transform:rotate(-45deg) translate(2px,-2px)}
.chl-l:focus-visible{outline:2px solid var(--focus);outline-offset:3px;border-radius:var(--r-field)}

/* ============================================================
   THE JOIN FLOW  (welcome.html, login.html)

   One column, one thing at a time. The steps are siblings swapped with
   [hidden]; protocol.css carries `[hidden]{display:none!important}` so a
   display-setting class can never leave two steps on screen at once — a bug
   this project has shipped three times.
   ============================================================ */
.join{min-height:100dvh}
.jstep{min-height:100dvh;display:grid;place-items:center;padding:40px 20px}
.jin{width:100%;max-width:440px;text-align:center}
.jform{text-align:left}
.jin .wm{display:block;margin-bottom:22px;text-align:center}
.jstepn{display:block;letter-spacing:.16em;color:var(--text-3);margin-bottom:12px}
.jt{font-size:clamp(26px,4.6vw,36px);font-weight:600;letter-spacing:-.035em;line-height:1.12;text-wrap:balance}
.jp{margin-top:12px;font-size:15.5px;line-height:1.6;color:var(--text-2)}
.jform .jp{margin-bottom:26px}

.jfield{margin-bottom:18px}
.jfield input,.jfield textarea,.jfield select{
  width:100%;background:var(--s-1);border:1px solid var(--line);border-radius:var(--r-tile);
  color:var(--text);font:inherit;font-size:15px;padding:13px 15px;resize:vertical;
  transition:border-color var(--d-tint) ease,background var(--d-tint) ease;
}
.jfield input:focus,.jfield textarea:focus,.jfield select:focus{
  outline:none;border-color:var(--line-strong);background:var(--s-2);
}
.jfield input:focus-visible,.jfield textarea:focus-visible,.jfield select:focus-visible{
  outline:2px solid var(--focus);outline-offset:2px;
}
.jhint{margin-top:7px;font-size:12.5px;line-height:1.5;color:var(--text-3)}
.jstep .btn{width:100%;margin-top:8px}

/* Red is semantic here and correctly so — this IS a failure state, a form that
   would not submit. It is never used for a member who simply has not done
   something yet. */
.jerr{
  margin-top:14px;font-size:13.5px;line-height:1.5;color:var(--fail);
  background:rgba(255,69,58,.08);border:1px solid rgba(255,69,58,.3);
  border-radius:var(--r-tile);padding:11px 13px;
}

/* ============================================================
   THE CONSOLE HOME — greeting, tabs, six square cards, stats, the room
   ============================================================ */

.hello{padding:10px 2px 22px}
.hello-t{font-size:clamp(27px,4.6vw,40px);font-weight:600;letter-spacing:-.035em;line-height:1.1;text-wrap:balance}
.hello-p{margin-top:11px;font-size:16px;line-height:1.6;color:var(--text-2);max-width:58ch}

/* ---- tabs ---- */
.tabs{display:flex;gap:6px;margin-bottom:20px;border-bottom:1px solid var(--line);padding-bottom:0}
.tab{
  background:none;border:0;border-bottom:2px solid transparent;color:var(--text-3);
  font:inherit;font-size:14.5px;font-weight:500;padding:9px 13px 11px;cursor:pointer;
  transition:color var(--d-tint) ease,border-color var(--d-tint) ease;
}
.tab:hover{color:var(--text-2)}
.tab.is-on{color:var(--text);border-bottom-color:var(--text)}
.tab:focus-visible{outline:2px solid var(--focus);outline-offset:2px;border-radius:var(--r-field)}

/* ---- the six square cards ----
   Near-square so all six read as one set at a glance. THE BAR IS THE CHAPTER'S
   OWN COLOUR and turns green only on `verified` — a green bar filling from
   self-ticked lessons would make watching look like proof, which is the one
   thing this product cannot say. */
.sqgrid{display:grid;grid-template-columns:repeat(3,1fr);gap:12px;margin-bottom:14px}
@media(max-width:820px){.sqgrid{grid-template-columns:repeat(2,1fr)}}
@media(max-width:400px){.sqgrid{grid-template-columns:1fr}}

.sq{
  position:relative;isolation:isolate;overflow:hidden;aspect-ratio:1/1;
  display:flex;flex-direction:column;justify-content:flex-end;
  background:var(--s-1);border:1px solid var(--line);border-radius:var(--r-card);
  padding:16px;text-decoration:none;color:inherit;
  transition:transform var(--d-element) var(--ease),border-color var(--d-element) var(--ease);
}
@media(max-width:400px){.sq{aspect-ratio:auto;min-height:180px}}
.sq:hover{transform:translateY(-3px);border-color:color-mix(in srgb,var(--h) 38%,var(--line))}
.sq:focus-visible{outline:2px solid var(--focus);outline-offset:3px}
.sq > *{position:relative;z-index:3}

.sq-shot{position:absolute;z-index:0;inset:0;overflow:hidden;pointer-events:none}
.sq-shot img{width:100%;height:100%;object-fit:cover;object-position:52% 16%;display:block;
  filter:grayscale(1) contrast(1.1) brightness(.52)}
.sq-shot:before{content:"";position:absolute;inset:0;background:var(--h);mix-blend-mode:color;opacity:.8}
/* Vertical scrim — the text sits along the bottom of a square, not beside a
   panel, so the ramp runs top-to-bottom here rather than left-to-right. */
/* MONOTONIC, AND IT ENDS OPAQUE. This finished on var(--s-1), which is
   rgba(255,255,255,.035) — a translucent white OVERLAY token, not a dark
   surface. So the scrim peaked at .72 halfway up (empty space) and decayed to
   almost nothing by 92%, which is exactly where .sq-foot sits: the 9.5px
   "3/8 · UNVERIFIED" line measured 1.86:1 at worst against the photo beneath
   it. The two lines that carry the verification state were the least legible
   things on the card.
   --s-* are overlay tokens and must never terminate a gradient. */
.sq:after{
  content:"";position:absolute;z-index:1;inset:0;pointer-events:none;
  background:linear-gradient(180deg,
    rgba(0,0,0,0) 10%,
    rgba(0,0,0,.42) 42%,
    rgba(0,0,0,.78) 72%,
    rgba(0,0,0,.92) 100%);
}
.sq:before{content:"";position:absolute;z-index:4;left:0;top:0;bottom:0;width:3px;background:var(--h);opacity:.8}
.sq.is-verified:before{background:var(--verified);opacity:1}
.sq.is-verified{border-color:rgba(48,209,88,.34)}

.sq-num{position:absolute;top:14px;left:16px;font-size:10.5px;letter-spacing:.12em;color:#fff;opacity:.8}
.sq-glyph{position:absolute;top:12px;right:14px;font-size:20px;line-height:1}
.sq-body{margin-bottom:12px}
.sq-name{display:block;font-size:16px;font-weight:600;letter-spacing:-.02em;line-height:1.2;text-wrap:balance}
.sq-tag{display:block;margin-top:4px;font-size:12px;line-height:1.4;color:var(--text-2)}

.sq-bar{display:block;height:5px;border-radius:var(--r-pill);background:rgba(255,255,255,.16);overflow:hidden;margin-bottom:8px}
.sq-bar i{display:block;height:100%;border-radius:var(--r-pill);background:var(--h);
  transition:width var(--d-element) var(--ease)}
.sq.is-verified .sq-bar i{background:var(--verified)}
.sq-state{display:block;font-size:9.5px;letter-spacing:.09em;color:var(--text-2)}
.sq-state.ok{color:var(--verified)}

/* ---- the weekly call ---- */
.weekcard{
  display:flex;flex-wrap:wrap;align-items:center;gap:12px 14px;margin-bottom:22px;
  background:var(--s-1);border:1px solid var(--line);border-radius:var(--r-card);padding:16px 18px;
}
/* The booker is the only weekcard that goes somewhere, so it is the only one
   that looks clickable. A touch more light than the weekly call beside it,
   because it is the thing a member paid for and the weekly call is included
   with everything else. */
.weekcard-book{
  text-decoration:none;color:inherit;margin-bottom:10px;
  border-color:rgba(255,255,255,.16);background:rgba(255,255,255,.045);
  transition:border-color .18s ease,background .18s ease,transform .18s ease;
}
.weekcard-book:hover{border-color:rgba(255,255,255,.28);background:rgba(255,255,255,.07)}
.weekcard-book:active{transform:translateY(1px)}
@media (prefers-reduced-motion:reduce){
  .weekcard-book{transition:none}
  .weekcard-book:active{transform:none}
}
.weekcard-ic{font-size:19px;line-height:1;flex:none}
/* A basis, not `flex:1`: with four children on a 395px phone the text column
   was shrinking to 71px and setting one word per line. It now claims 220px or
   takes its own row, and the badge and button wrap beneath it. */
.weekcard-tx{display:flex;flex-direction:column;gap:3px;flex:1 1 220px;min-width:0}
.weekcard-tx b{font-size:14.5px;font-weight:600;letter-spacing:-.01em}
.weekcard-tx span{font-size:12.5px;line-height:1.5;color:var(--text-3)}
.weekcard-meta{font-size:10px;letter-spacing:.12em;color:var(--text-3);flex:none;margin-left:auto}

/* ---- stats ---- */
.statgrid{display:grid;grid-template-columns:repeat(4,1fr);gap:12px;margin-bottom:16px}
@media(max-width:820px){.statgrid{grid-template-columns:repeat(2,1fr)}}
.stat{background:var(--s-1);border:1px solid var(--line);border-radius:var(--r-card);padding:17px 16px}
.stat.is-ok{border-color:rgba(48,209,88,.3);background:rgba(48,209,88,.05)}
.stat-n{display:block;font-family:var(--mono);font-size:26px;font-weight:500;letter-spacing:-.03em}
.stat.is-ok .stat-n{color:var(--verified)}
.stat-l{display:block;margin-top:7px;font-size:9.5px;letter-spacing:.11em;color:var(--text-3)}
.stat-note{display:block;margin-top:9px;font-size:12px;line-height:1.45;color:var(--text-3)}

/* ---- the list ---- */
.todo-note{font-size:13px;line-height:1.55;color:var(--text-3);margin-bottom:16px}
.todo-add{display:flex;gap:9px;margin-bottom:14px}
.todo-add input{
  flex:1;background:var(--s-2);border:1px solid var(--line);border-radius:var(--r-tile);
  color:var(--text);font:inherit;font-size:14.5px;padding:11px 13px;
}
.todo-add input:focus{outline:none;border-color:var(--line-strong)}
.todo-add input:focus-visible{outline:2px solid var(--focus);outline-offset:2px}
.todo-add .btn{flex:none;padding:11px 20px}
.todo-list{list-style:none;margin:0;padding:0;display:flex;flex-direction:column}
.todo{display:flex;align-items:flex-start;gap:11px;padding:10px 0;border-bottom:1px solid var(--line)}
.todo:last-child{border-bottom:0}
.todo-t{flex:1;font-size:14.5px;line-height:1.45}
.todo.is-done .todo-t{color:var(--text-3);text-decoration:line-through}
.todo-x{
  background:none;border:0;color:var(--text-3);font:inherit;font-size:13px;cursor:pointer;
  padding:2px 6px;border-radius:var(--r-field);flex:none;
}
.todo-x:hover{color:var(--text)}
.todo-x:focus-visible{outline:2px solid var(--focus);outline-offset:2px}
.todo-empty{padding:14px 0;font-size:13.5px;color:var(--text-3)}

/* ---- the room ---- */
#postText{
  width:100%;background:var(--s-2);border:1px solid var(--line);border-radius:var(--r-tile);
  color:var(--text);font:inherit;font-size:14.5px;padding:12px 14px;resize:vertical;
}
#postText:focus{outline:none;border-color:var(--line-strong)}
#postText:focus-visible{outline:2px solid var(--focus);outline-offset:2px}
.post-row{display:flex;align-items:center;gap:13px;margin-top:13px}
.post-row .dat{font-size:11px;letter-spacing:.06em;color:var(--text-3)}

.fpost{
  background:var(--s-1);border:1px solid var(--line);border-radius:var(--r-card);
  padding:18px 20px;margin-bottom:12px;
}
.f-line{margin-bottom:2px}
.f-head{display:flex;align-items:baseline;gap:10px;margin-bottom:6px}
.f-who{font-size:14px;font-weight:600;letter-spacing:-.01em}
.f-at{font-size:10.5px;letter-spacing:.06em;color:var(--text-3)}
.f-del{
  margin-left:auto;background:none;border:0;color:var(--text-3);font:inherit;font-size:11.5px;
  cursor:pointer;padding:2px 6px;border-radius:var(--r-field);
}
.f-del:hover{color:var(--fail)}
.f-del:focus-visible{outline:2px solid var(--focus);outline-offset:2px}
.f-text{font-size:14.5px;line-height:1.6;white-space:pre-wrap;word-break:break-word;color:var(--text-2)}
.f-comments{margin-top:14px}
.f-comment{border-left:2px solid var(--line);padding-left:14px;margin-top:14px}
.f-reply{border-left:2px solid var(--line);padding-left:14px;margin-top:12px}
.f-add{display:flex;gap:8px;margin-top:10px}
.f-add input{
  flex:1;background:var(--s-2);border:1px solid var(--line);border-radius:var(--r-pill);
  color:var(--text);font:inherit;font-size:13.5px;padding:9px 14px;
}
.f-add input:focus{outline:none;border-color:var(--line-strong)}
.f-add input:focus-visible{outline:2px solid var(--focus);outline-offset:2px}
.f-send{
  flex:none;background:var(--s-2);border:1px solid var(--line);border-radius:var(--r-pill);
  color:var(--text-2);font:inherit;font-size:13px;padding:9px 16px;cursor:pointer;
}
.f-send:hover{color:var(--text);border-color:var(--line-strong)}
.f-send:focus-visible{outline:2px solid var(--focus);outline-offset:2px}
.feed-empty{padding:26px 4px;font-size:14px;color:var(--text-3)}

/* ---- the chapter page ---- */
.chprog{margin-top:20px}
.chprog-bar{display:block;height:6px;border-radius:var(--r-pill);background:rgba(255,255,255,.1);overflow:hidden;margin-bottom:9px}
.chprog-bar i{display:block;height:100%;border-radius:var(--r-pill);background:var(--h);
  transition:width var(--d-element) var(--ease)}
.chprog.is-verified .chprog-bar i{background:var(--verified)}
.chprog .dat{font-size:10.5px;letter-spacing:.09em;color:var(--text-3)}
.chprog .dat.ok{color:var(--verified)}

.slots{display:flex;flex-wrap:wrap;gap:9px;margin-top:14px}
.slot{
  display:flex;flex-direction:column;gap:3px;text-align:left;
  background:var(--s-2);border:1px solid var(--line);border-radius:var(--r-tile);
  color:inherit;font:inherit;padding:10px 14px;cursor:pointer;
  transition:border-color var(--d-tint) ease,background var(--d-tint) ease;
}
.slot:hover{border-color:color-mix(in srgb,var(--h) 40%,var(--line));background:var(--s-3)}
.slot:focus-visible{outline:2px solid var(--focus);outline-offset:2px}
.slot:disabled{cursor:default}

/* THE SHUT-DOOR MARKER, IN A COLUMN TILE.
   protocol.css draws 🔒 and 📞 as a ::before, authored for the landing page
   where .slot is a single centred ROW and the marker sits inline. Here .slot is
   a two-line column, so that same ::before became a third stacked line: the
   blocked tiles grew taller than the bookable ones beside them and the marker
   centred itself over left-aligned text. Pinned to the corner instead, so a
   row of tiles keeps one height whatever state each is in.

   The old `opacity:.45` is gone with it. Reo's note of 5 August stands — fading
   a tile reads as a loading state, not a closed door — and protocol.css already
   gives these the hatch, the dashed rim and the strike-through. */
.slot{position:relative;padding-right:26px}
.slot.off:before,.slot.is-comm:before{
  position:absolute;top:7px;right:9px;margin:0;font-size:9.5px;
}
.slot.off{gap:3px}
/* The corner is reserved on EVERY tile, not just the marked ones. Padding only
   the blocked ones made them the widest things in the row, so the eye landed on
   the slot that cannot be booked before the ones that can. */
.slot-d{font-size:9.5px;letter-spacing:.1em;color:var(--text-3)}
.slot-t{font-size:14.5px;font-weight:600;letter-spacing:-.01em}

.chev-req-t{font-size:13px;font-weight:600;margin-bottom:9px}
.chev-req-l{list-style:none;margin:0 0 4px;padding:0;display:flex;flex-direction:column;gap:6px}
.chev-req-l li{font-size:12.5px;line-height:1.5;color:var(--text-3);display:flex;gap:7px}
.chev-req-l b{color:var(--text-2);flex:none}


/* Visible to a screen reader, not to the eye. Used by the join flow's
   announcer, which replaced role="status" on <main> — that override deleted
   the page's only landmark and read the whole form aloud on every step. */
.sr-only{
  position:absolute;width:1px;height:1px;padding:0;margin:-1px;
  overflow:hidden;clip:rect(0 0 0 0);clip-path:inset(50%);white-space:nowrap;border:0;
}

/* The waiting list that replaced the checkout button while nothing is for sale. */
.waitform{display:flex;flex-direction:column;gap:9px;margin-top:auto}
.waitform input{
  background:var(--s-2);border:1px solid var(--line);border-radius:var(--r-tile);
  color:var(--text);font:inherit;font-size:15px;padding:12px 14px;
}
.waitform input:focus{outline:none;border-color:var(--line-strong)}
.waitform input:focus-visible{outline:2px solid var(--focus);outline-offset:2px}
.waitform .btn{width:100%}
#waitMsg{font-size:11px;letter-spacing:.06em;color:var(--text-3);min-height:1.2em}

/* The community hour, while it is actually happening. Green is reserved for
   verified work everywhere else on this site, so a live call borrows the hue
   for its rim only and never for a bar — nothing here has been earned. */
.weekcard.is-live{border-color:color-mix(in srgb,var(--verified) 45%,var(--line));background:color-mix(in srgb,var(--verified) 7%,var(--s-1))}
.weekcard.is-live .weekcard-meta{color:var(--verified)}
.weekcard-go{flex:none;margin-left:2px;padding:9px 16px;font-size:12.5px}

/* ---- chat ----
   A fixed-height log with the composer pinned under it, rather than a page that
   grows: a chat that extends the document means every new message moves the
   whole Console and the tab strip walks off the top of the screen. */
.chatwrap{display:flex;flex-direction:column;gap:12px}
.chanbar{display:flex;flex-wrap:wrap;gap:7px}
.chan{
  background:var(--s-2);border:1px solid var(--line);border-radius:999px;
  color:var(--text-3);font:inherit;font-size:12.5px;padding:7px 14px;cursor:pointer;
  transition:color var(--d-tint) ease,border-color var(--d-tint) ease,background var(--d-tint) ease;
}
.chan:hover{color:var(--text-2);border-color:var(--line-strong)}
.chan.is-on{background:var(--text);color:#000;border-color:var(--text);font-weight:500}
.chan:focus-visible{outline:2px solid var(--focus);outline-offset:2px}

.chatbox{border:1px solid var(--line);border-radius:var(--r-panel);background:var(--s-1);overflow:hidden}
.chatlog{
  /* clamp, not min(): min(56vh,460px) has no floor, so a short window collapses
     the log to nothing and the room looks broken rather than small. And 56vh
     was too tall on a phone — at 390x844 it pushed the message box below the
     fold behind a 460px scroll region that eats the swipe, so the one control
     you came for was the one you could not reach. */
  height:clamp(200px,46vh,460px);
  overflow-y:auto;overscroll-behavior:contain;
  padding:16px 16px 8px;display:flex;flex-direction:column;gap:2px;
}
@media (max-width:600px){
  /* Shorter still, so the composer and a few messages share one screen. */
  .chatlog{height:clamp(170px,38vh,300px)}
}
.chat-note{color:var(--text-3);font-size:13px;margin:auto;text-align:center;padding:20px}

.cmsg{padding:3px 0}
.cmsg.is-run{padding-top:0}
.cmsg-h{display:flex;align-items:baseline;gap:8px;margin-bottom:2px;margin-top:9px}
.cmsg-n{font-size:13px;font-weight:600;letter-spacing:-.01em}
.cmsg.is-me .cmsg-n{color:var(--verified)}
.cmsg-t{font-size:10px;color:var(--text-3)}
/* pre-wrap so a typed line break survives, break-word so one long unbroken
   string cannot push the whole log sideways */
.cmsg-b{font-size:14px;line-height:1.5;color:var(--text-2);margin:0;white-space:pre-wrap;overflow-wrap:anywhere}

.chatform{display:flex;gap:9px;align-items:flex-end;padding:11px 12px;border-top:1px solid var(--line);background:var(--s-2)}
.chatform textarea{
  flex:1;min-width:0;resize:none;background:var(--s-1);border:1px solid var(--line);
  border-radius:var(--r-field);color:var(--text);font:inherit;font-size:14px;
  padding:10px 12px;line-height:1.45;max-height:140px;
}
.chatform textarea:focus-visible{outline:2px solid var(--focus);outline-offset:1px;border-color:var(--line-strong)}
.chatform .btn{flex:none;padding:10px 18px;font-size:13px}
.chatform.is-locked textarea{opacity:.55}
.chat-err{margin:0;padding:9px 14px;font-size:12.5px;color:var(--fail);border-top:1px solid var(--line);background:var(--s-2)}
/* The standing note about the room — a ban, or a room that would not open.
   Lives above the log rather than inside it, because the log is emptied. */
.chat-state{margin:0;padding:13px 16px;border-bottom:1px solid var(--line);background:var(--s-2);text-align:left}
.chat-count{flex:none;font-size:11px;color:var(--text-3);align-self:center}
.chat-count.is-over{color:var(--fail)}
/* The withdrawal waiver, stated plainly where a member can find it again. */
.waiver{font-size:11.5px;line-height:1.65;color:var(--text-3);margin:0 0 18px;max-width:62ch;letter-spacing:0}

/* ---- the contact page ---- */
.contactbox{max-width:min(620px,100%)}
.contactbox textarea{
  width:100%;resize:vertical;min-height:140px;
  background:var(--s-1);border:1px solid var(--line);border-radius:var(--r-field);
  color:var(--text);font:inherit;font-size:16px;line-height:1.55;padding:13px 14px;
}
.contactbox textarea:focus-visible{outline:2px solid var(--focus);outline-offset:1px;border-color:var(--line-strong)}
.contactbox textarea::placeholder{color:var(--text-3)}
.cnote{display:block;margin-top:7px;font-size:11px;color:var(--text-3)}
/* The honeypot. Off-screen rather than display:none — a bot that reads styles
   skips a hidden field, and skipping it is the behaviour being detected. */
.hp{position:absolute;left:-9999px;width:1px;height:1px;overflow:hidden}
.cdirect{margin-top:26px;padding-top:20px;border-top:1px solid var(--line);display:flex;flex-direction:column;gap:12px}
.cfoot{margin-top:22px;color:var(--text-3)}
.cfoot a{color:var(--text-2)}
