/* Speakers review. The page chrome and the common card parts come from
   media-cards.css; this sheet is only what a speaker card adds. The card
   anatomy is the Odyssey voice samples page, restyled with this site's tokens. */

/* Collapsed cards are short, so the cast is laid out as a grid and a whole
   book can be skimmed at once: three columns on a wide screen, two on a
   laptop, one on a phone. A card that is opened grows in its own column. */
.cards { display:grid; gap:var(--s4); align-items:start;
  grid-template-columns:repeat(auto-fill, minmax(280px, 1fr)); }

.card.spk { padding:var(--s4); }

/* -- the header: portrait, name, pills, chips, the arrow ------------------ */
.card.spk .card-head { display:flex; flex-wrap:nowrap; align-items:flex-start;
  gap:var(--s3); margin:0 0 var(--s2); }
.card.spk .headshot { flex:0 0 64px; width:64px; height:64px; padding:0;
  border:1px solid var(--rule); border-radius:var(--r-md); overflow:hidden;
  background:var(--warm-1); cursor:zoom-in; }
.card.spk .headshot img { display:block; width:100%; height:100%;
  object-fit:cover; object-position:center top; }
.card.spk .headshot.none { display:flex; align-items:center;
  justify-content:center; border-style:dashed; cursor:default;
  color:var(--faint); font:500 var(--t-h4)/1 var(--serif); }
.card.spk .headtext { flex:1 1 auto; min-width:0; }
.card.spk .headline { display:flex; flex-wrap:wrap; align-items:center;
  gap:var(--s1) var(--s2); }
.card.spk .headline .cname { margin-right:0; }

.card.spk .disclose { flex:0 0 auto; width:32px; height:32px; padding:0;
  display:flex; align-items:center; justify-content:center;
  border:1px solid var(--line); border-radius:var(--r-full);
  background:var(--card); color:var(--ink); cursor:pointer;
  transition:border-color var(--tr), background-color var(--tr); }
.card.spk .disclose:hover:not(:disabled) { border-color:var(--ink);
  background:var(--subtle); }
.card.spk .disclose::after { content:""; width:7px; height:7px; margin-top:-3px;
  border-right:2px solid currentColor; border-bottom:2px solid currentColor;
  transform:rotate(45deg); transition:transform var(--tr); }
.card.spk[data-open="1"] .disclose::after { margin-top:3px;
  transform:rotate(-135deg); }

.vh { position:absolute; width:1px; height:1px; padding:0; margin:-1px;
  overflow:hidden; clip:rect(0 0 0 0); white-space:nowrap; border:0; }

/* -- the description, plain text, three lines until the card is open ----- */
.card.spk .desc { margin:0 0 var(--s3); color:var(--ink-2);
  font-size:var(--t-md); line-height:1.5; }
.card.spk[data-open="0"] .desc { display:-webkit-box; -webkit-line-clamp:3;
  -webkit-box-orient:vertical; overflow:hidden; }

/* -- the player, with a target worth pressing ---------------------------- */
.card.spk .playrow { display:flex; flex-wrap:wrap; align-items:center;
  gap:var(--s3); margin:0 0 var(--s2); }
.card.spk .playbtn { flex:0 0 auto; width:48px; height:48px; padding:0;
  display:flex; align-items:center; justify-content:center;
  border:1px solid var(--ink); border-radius:var(--r-full);
  background:var(--ink); color:var(--lds-page); cursor:pointer;
  transition:background-color var(--tr); }
.card.spk .playbtn:hover:not(:disabled) { background:var(--muted); }
.card.spk .playbtn:disabled { background:var(--card); color:var(--faint);
  border-color:var(--line); cursor:not-allowed; }
.card.spk .playbtn .tri { width:0; height:0; margin-left:4px;
  border-left:14px solid currentColor; border-top:9px solid transparent;
  border-bottom:9px solid transparent; }
.card.spk .playbtn.on .tri { width:14px; height:16px; margin-left:0;
  border:0; border-left:5px solid currentColor;
  border-right:5px solid currentColor; }
.card.spk .playrow .player { flex:1 1 150px; min-width:0; margin:0; }
.card.spk .playrow .act.small { flex:0 0 auto; padding:var(--s2) var(--s3);
  font-size:var(--t-sm); }
/* The version and the time belong to the open card; the chip beside the name
   already says the sample is ready. A card with nothing to play keeps the
   line, because it is the one that says so. */
.card.spk[data-open="0"][data-status="ok"] .playrow .caption
  { display:none; }
.card.spk .cardmsg:empty { min-height:0; margin:0; }

/* -- everything the arrow opens ------------------------------------------ */
.card.spk .carddetail { margin-top:var(--s3); padding-top:var(--s3);
  border-top:1px solid var(--rule); }

/* An anthology carries several works. The heading runs the width of the grid
   so the cards under it read as one group. */
.cards .workhead { grid-column:1 / -1; margin:var(--s4) 0 0;
  font:500 var(--t-h4)/1.25 var(--serif); letter-spacing:-.01em;
  padding-bottom:var(--s2); border-bottom:1px solid var(--rule); }
.cards .workhead:first-child { margin-top:0; }

.card.spk fieldset.profile { border:1px solid var(--rule);
  border-radius:var(--r-md); padding:var(--s3); margin:0 0 var(--s3);
  min-width:0; }
.card.spk fieldset.profile legend { padding:0 var(--s1); margin:0; }
.card.spk .profile .grid { display:grid; gap:var(--s2) var(--s3);
  grid-template-columns:repeat(auto-fit, minmax(140px, 1fr)); }
.card.spk .profile .field { margin:0; }

.card.spk .sample textarea { font-family:var(--serif);
  font-size:var(--t-read); line-height:1.5; }

/* The audio and the portrait sit side by side, and stack when the card is
   narrow. The portrait block itself is styled in media-cards.css. */
.card.spk .mediarow { display:flex; flex-wrap:wrap; gap:var(--s4);
  margin:0 0 var(--s3); }
.card.spk .mediarow .player { flex:1 1 220px; min-width:0; margin:0; }
/* The prompt is a paragraph of text the reviewer edits, so the portrait side
   of the row is given room to hold it. */
.card.spk .mediarow .portraitbox { flex:1 1 420px; min-width:0; }
.card.spk .mediarow .portraitbox .thin { margin:0; }
/* The prompt is the thing being edited, so the note above it says where its
   first lines come from and the box itself reads as text sent to a model. */
.card.spk .portrait .field .thin { margin:0 0 var(--s1);
  font:var(--t-sm)/1.4 var(--sans); color:var(--faint); }
.card.spk .portrait textarea[data-prompt] { font:var(--t-sm)/1.5 var(--mono);
  max-height:22em; }
/* Approving the whole cast is the main thing the book bar is for. */
.bookbar .pillbtn.go { background:var(--ink); color:var(--lds-page);
  border-color:var(--ink); }
.bookbar .pillbtn.go:hover:not(:disabled) { background:var(--muted);
  color:var(--lds-page); }

.card.spk .player { margin:0 0 var(--s3); }
.card.spk .player .lab { display:block;
  font:500 var(--t-label)/1.2 var(--sans); letter-spacing:.08em;
  text-transform:uppercase; color:var(--muted); margin:0 0 var(--s1); }
.card.spk audio { width:100%; height:36px; display:block; }
.card.spk .caption { margin:var(--s1) 0 0; font-family:var(--sans);
  font-size:var(--t-sm); color:var(--faint); }

.card.spk .takes { padding:0 var(--s3) var(--s3); font-size:var(--t-md); }
.card.spk .take { border-top:1px solid var(--rule); padding:var(--s3) 0 0;
  margin:var(--s3) 0 0; }
.card.spk .take:first-child { border-top:0; margin-top:0; padding-top:0; }
.card.spk .takehead { margin:0 0 var(--s1); font-family:var(--sans);
  font-size:var(--t-sm); }
.card.spk .take details { background:var(--card); margin:var(--s2) 0 0; }

@media (max-width:640px) {
  .cards { grid-template-columns:1fr; }
  .card.spk .headshot { flex:0 0 56px; width:56px; height:56px; }
}
