/* /cohorts and /cohorts/<code>.
   Tokens come from app.css; nothing here declares a colour of its own.
   Every grid is auto-fit with a minmax whose MINIMUM is 0-safe: a fixed
   minimum wider than the viewport is how a page starts scrolling sideways,
   which notes/45b-org.md says must never happen. */

.cohgrid {
  list-style: none; margin: 24px 0 0; padding: 0;
  display: grid; gap: 14px;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 19rem), 1fr));
}
/* Never four across: past the width where auto-fit would fit a fourth 19rem
   column (~1258px), pin the track count at three and let the cards widen. */
@media (min-width: 75rem) {
  .cohgrid { grid-template-columns: repeat(3, minmax(0, 1fr)); }
}
.cohcard {
  position: relative; min-width: 0;
  background: var(--surface); border-radius: 12px; padding: 16px 18px;
  border: 1px solid rgb(var(--alt-text-rgb) / .08);
  display: grid; gap: 6px; align-content: start;
}
.cohcard:hover { border-color: color-mix(in srgb, var(--accent) 60%, transparent); }
/* The whole card is the hit area. The anchor stays a real link and ::after
   stretches it, so there is no nested-interactive markup and no click handler. */
.cohlink { text-decoration: none; }
.cohcard:hover .cohlink, .cohlink:focus-visible { color: var(--accent-bright); text-shadow: var(--link-glow); }
.cohlink::after { content: ""; position: absolute; inset: 0; border-radius: 12px; }
.cohcard h2 { margin: 0; overflow-wrap: anywhere; }

.cohstate {
  font-size: .75rem; letter-spacing: .04em; text-transform: uppercase;
  color: rgb(var(--alt-text-rgb) / .5);
}
/* The state word is a pill, matching .up-today on the schedule above - same
   shape, same size, same uppercase. Its rules are repeated here rather than
   shared with upcoming.css because that stylesheet only arrives when there is
   something upcoming to show, and this pill must not depend on that. */
.cohpill {
  display: inline-block;
  padding: .1em .7em;
  border-radius: var(--radius-btn);
  background: rgb(var(--alt-text-rgb) / .1);
  vertical-align: .1em;
}
.cohcard.is-running .cohpill {
  background: color-mix(in srgb, var(--alt-accent) 22%, transparent);
  color: var(--alt-accent);
}
.cohending { color: var(--warn); font-weight: 600; }
/* The open-ended counterpart: informational, not urgent, so the brand blue
   rather than amber. --accent itself is too dark to read on --bg, so it is
   lifted toward white - still the token, no new hex. */
.cohopen { color: color-mix(in srgb, var(--accent) 55%, #fff); font-weight: 600; }
.cohblurb { margin: .2em 0 0; font-size: .9rem; color: rgb(var(--alt-text-rgb) / .75); }

.cohstats {
  list-style: none; margin: .4em 0 0; padding: 0;
  display: flex; flex-wrap: wrap; gap: .2em 1em;
  font-size: .85rem; color: rgb(var(--alt-text-rgb) / .6);
}
.cohstats b { color: var(--alt-text); }

/* ---- one cohort ---- */
.cohsec { margin-block: 34px; }
.cohsec h2 { display: flex; align-items: baseline; gap: .5rem; }
.cohsec .count {
  font-family: Chivo, sans-serif; font-size: .8rem; font-weight: 400;
  color: rgb(var(--alt-text-rgb) / .5);
}

/* .calllist .cdesc lives in app.css - /calls lists descriptions too. */
.callgroup { display: flex; align-items: baseline; gap: .5rem; margin: 26px 0 10px; }
.callgroup:first-of-type { margin-top: 14px; }
.cohmore { text-align: center; margin-top: 24px; }
/* Linkable call-list headings: the heading is the link, # shows on hover. */
#calls, .callgroup[id] { scroll-margin-top: calc(var(--stickytop, 4.5rem) + 12px); }
.anchorlink { color: inherit; text-decoration: none; }
.anchorlink::after { content: " #"; opacity: 0; color: var(--accent); transition: opacity .15s; }
.anchorlink:hover::after, .anchorlink:focus-visible::after { opacity: .7; }

/* ---- updates ---- */
.updlist { list-style: none; margin: 0; padding: 0; display: grid; gap: 14px; }
.upd {
  min-width: 0; background: var(--surface); border-radius: 12px; padding: 14px 18px;
  border-left: 3px solid color-mix(in srgb, var(--accent) 70%, transparent);
}
.upd.is-draft { border-left-color: rgb(var(--alt-text-rgb) / .25); opacity: .85; }
.updhead { display: flex; align-items: center; gap: .6em; flex-wrap: wrap; }
.updon { font-size: .8rem; color: rgb(var(--alt-text-rgb) / .55); }
.updtitle { margin: .2em 0 .3em; font-size: 1.05rem; }
.updbody { margin: .4em 0; overflow-wrap: anywhere; }
.updadmin { display: flex; gap: 8px; flex-wrap: wrap; margin-top: .6em; }
.updadmin form { margin: 0; }
.updadmin .btn-secondary, .updadmin .btn-danger { padding: .2em .9em; font-size: .78rem; cursor: pointer; }

.updnew { margin-top: 18px; }
.updnew summary { cursor: pointer; color: rgb(var(--alt-text-rgb) / .75); }
.updform { max-width: 40rem; justify-items: stretch; }
.updform textarea {
  font: inherit; width: 100%; color: var(--alt-text); resize: vertical;
  background: var(--surface); border: 1px solid rgb(var(--alt-text-rgb) / .2);
  border-radius: 10px; padding: .55em .8em;
}
.updform textarea:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }
.updform label.inline { display: flex; align-items: center; gap: .5em; }
.updform button { justify-self: start; }

/* ---- testimonials ----
   The stage, bars and panes are app.css's, shared with /calls/<slug>; only
   what differs lives here. See templates/cohort_show.php. */
.tstage { margin-top: 6px; }
/* The transcript under a testimonial: half the /calls height, folded by an
   arrow left of its title. */
.ttrans > summary { list-style: none; cursor: pointer; display: flex; align-items: baseline; gap: .5rem; }
.ttrans > summary::-webkit-details-marker { display: none; }
.ttrans > summary::before {
  content: ""; width: .5em; height: .5em; flex: none; align-self: center;
  border-right: 2px solid currentColor; border-bottom: 2px solid currentColor;
  transform: rotate(-45deg); transition: transform .15s;
}
.ttrans[open] > summary::before { transform: rotate(45deg); }
.ttrans > summary h2 { margin: 0; }
.ttrans[open] > summary { margin-bottom: .6rem; }
.tstage .transcript { max-height: 31vh; }
@media (max-width: 640px) { .tstage .transcript { max-height: 25vh; } }
/* Who is on screen, where a call page has its depth switcher. */
.tnow {
  margin: 0; align-self: center; font-weight: 600; font-size: 1rem;
  min-width: 0; overflow-wrap: anywhere;
}
/* A participant is a LINK (to its .mp4, for no-JS), styled as a section row. */
a.sec { text-decoration: none; }
a.sec:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }
.sec.is-off { cursor: default; opacity: .6; }
/* The admin's flags go on their own line under the name (2026-09-28). Beside
   it, app.css's `.sec .st` (no shrink, no wrap) let three or four flags take
   the whole row and squeezed the name to one letter per line. */
.sec:has(.tflags) { flex-wrap: wrap; }
.sec .tflags { display: flex; flex: 1 1 100%; flex-wrap: wrap; gap: 4px; justify-content: flex-start; white-space: normal; }
.lang:disabled { opacity: .35; cursor: not-allowed; }
.lang:disabled:hover { background: transparent; }
.skipnote a { color: inherit; }
/* The cover as a play button, until the first play. Covers the native
   controls too, on purpose: before anything has played there is nothing for
   them to do that this does not. */
.tvidbox { position: relative; }
.tstart {
  position: absolute; inset: 0; width: 100%; height: 100%;
  border: 0; padding: 0; margin: 0; cursor: pointer;
  background: transparent; display: flex; align-items: center; justify-content: center;
}
.tstart[hidden] { display: none; }
.tstarticon {
  width: 76px; height: 76px; border-radius: 50%;
  background: color-mix(in srgb, var(--accent) 88%, transparent);
  box-shadow: 0 4px 18px rgb(0 0 0 / .35);
  position: relative; transition: transform .15s ease;
}
.tstarticon::after {
  content: ""; position: absolute; left: 30px; top: 22px;
  border-style: solid; border-width: 16px 0 16px 26px;
  border-color: transparent transparent transparent #fff;
}
.tstart:hover .tstarticon, .tstart:focus-visible .tstarticon { transform: scale(1.08); }
.tstart:focus-visible { outline: 2px solid var(--accent); outline-offset: -4px; }
@media (max-width: 640px) {
  .tstarticon { width: 60px; height: 60px; }
  .tstarticon::after { left: 23px; top: 17px; border-width: 13px 0 13px 21px; }
}

/* Typed testimonials, when there are any: quotes under the stage. */
.twritten { margin: 22px 0 10px; font-size: 1rem; }
.tlist {
  list-style: none; margin: 0; padding: 0;
  display: grid; gap: 14px;
  grid-template-columns: 1fr;
}
@media (min-width: 40rem) { .tlist { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (min-width: 62rem) { .tlist { grid-template-columns: repeat(3, minmax(0, 1fr)); } }
.tcard {
  min-width: 0; background: var(--surface); border-radius: 12px; padding: 14px 16px;
  display: grid; gap: 8px; align-content: start;
}
.tcard.is-private { border: 1px dashed rgb(var(--alt-text-rgb) / .25); background: transparent; }
.tname { margin: 0; font-size: 1rem; overflow-wrap: anywhere; }
.twhen {
  font-family: Chivo, sans-serif; font-weight: 400; font-size: .78rem;
  color: rgb(var(--alt-text-rgb) / .55);
}
.ttext {
  margin: 0; padding-left: .9em; font-size: .92rem;
  border-left: 2px solid color-mix(in srgb, var(--alt-accent) 60%, transparent);
  overflow-wrap: anywhere;
}
.warn { color: var(--alert); }

.tmissing { margin-top: 20px; font-size: .9rem; color: rgb(var(--alt-text-rgb) / .7); }
.tmissing h3 { font-size: .95rem; margin-bottom: .3em; }
.tmissing ul { margin: 0; padding-left: 1.2em; }

/* Recorded but not yet in the corpus, and the ones that never will be. Admin
   only. Deliberately quieter than .calllist: nothing here is a link, because
   there is no page to go to yet, and a row that looks clickable and is not is
   worse than a plain one. min-width:0 on the grid child is what stops a long
   Portuguese session title from pushing the page wider than the viewport. */
.pending { margin-top: 26px; }
.pending h3 { font-size: 1rem; margin-bottom: .35em; }
.pendlist { list-style: none; margin: 10px 0 0; padding: 0; display: grid; gap: 6px; }
.pendlist li {
  min-width: 0;
  padding: 8px 12px;
  border: 1px dashed rgb(var(--alt-text-rgb) / .22);
  border-radius: 8px;
  overflow-wrap: anywhere;
}
.pendlist .ct { font-weight: 500; font-size: .92rem; }
.pendlist .why { display: block; font-size: .8rem; color: var(--alert); margin-top: .25em; }

/* The intro block on '/' only - spaced like the .upcoming section below it. */
.landing-intro { margin-block: 4px 34px; }
.landing-intro .lede { margin-block: 0 14px; }
/* Sized like the page's h1 ("Cohorts") but kept an h2, so the page still has
   one h1. Mirrors app.css's h1 rule. */
.landing-intro h2 { font-size: 1.8rem; margin: 0 0 .2rem; }
/* Video beside the text only on a wide desktop; the player's own 2rem top
   margin is dropped there so its top lines up with the heading. */
@media (min-width: 75rem) {
  .landing-intro {
    display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1.2fr);
    gap: 32px; align-items: start;
  }
  .landing-intro .vp-row { margin-top: 0; }
}
/* The player a sixth smaller than on 45b.io/web3 (2026-09-24): 5/6 of its
   column, and 800px (5/6 of 960) at most. */
.landing-intro .vp-wrap { width: min(83.333%, 800px); }
