/* Player app. Builds on base.css: type, hairlines and the light — nothing boxed.
   Every view is a column of blocks, the direct children of #view; their rhythm lives here. */

/* ---------- frame ---------- */

.spine { transition: opacity var(--light-t) var(--ease-drama); }

.mast {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  min-height: 44px;
  margin: -12px 0 30px;
  transition: opacity var(--light-t) var(--ease-drama);
}
.mast .kicker { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.mast .text-btn { flex: none; min-height: 44px; padding: 0 0 0 20px; color: var(--dim); }

#view > * { margin: 0; animation: rise .5s var(--ease-out) backwards; transition: opacity .3s var(--ease-out); }
#view > * + * { margin-top: 60px; }
#view > .near { margin-top: 22px; }
#view > .band { margin: 0; animation: none; }
/* sections measure themselves for .fit (never #view: containment would trap the fixed band) */
#view > section { container-type: inline-size; }

/* a block arrives when its content changed — never on a mere re-render */
@keyframes rise { from { opacity: 0; transform: translateY(8px); } }

.sect-head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 16px;
  margin: 0 0 12px;
}
.sect-head > :last-child:not(:first-child) { text-align: right; }

/* ---------- type ---------- */

/* between .ritual-m and the cropped .ritual: big, but it wraps between words instead of
   cropping; 17vw keeps the longest headline word ("Förrädarna") inside a phone's measure */
.ritual-l {
  font-family: var(--f-ritual);
  font-weight: 800;
  font-size: clamp(48px, 17vw, 136px);
  line-height: .84;
  letter-spacing: -.01em;
  margin: 0 0 0 -.04em;
}

/* names in ritual type shrink with their length (Grenze runs ≈ .5em a letter) */
.fit { --fit: calc(190cqi / var(--len)); white-space: nowrap; overflow-wrap: normal; }
@supports not (width: 1cqi) { .fit { --fit: calc(150vw / var(--len)); } }
.ritual.fit { font-size: clamp(40px, min(23vw, var(--fit)), 150px); }
.ritual-l.fit { font-size: clamp(36px, min(17vw, var(--fit)), 136px); }
.tomb-name.fit { font-size: clamp(40px, min(25vw, var(--fit)), 170px); }

/* ---------- identity: the seat numeral, and the role under a held seal ---------- */

.who-stack { display: grid; align-items: end; }
.who-stack > * {
  grid-area: 1 / 1;
  min-width: 0;
  transition: opacity .32s var(--ease-out), visibility 0s linear .32s;
}
.who-secret { opacity: 0; visibility: hidden; }
.who.is-peeking .who-face { opacity: 0; }
.who.is-peeking .who-secret { opacity: 1; visibility: visible; transition-delay: 0s; }

/* numerals stay grotesk: blackletter X and I stop reading as numbers at this size */
.who-seat {
  font-weight: 700;
  font-size: clamp(150px, 50vw, 300px);
  line-height: .76;
  letter-spacing: -.075em;
  margin: 18px 0 0 -.06em;
  white-space: nowrap;
}
.who-name {
  margin: 14px 0 0;
  font-size: 40px;
  font-weight: 600;
  line-height: 1;
  letter-spacing: -.035em;
  overflow-wrap: anywhere;
}
.who-role {
  font-family: var(--f-ritual);
  font-weight: 800;
  font-size: clamp(64px, 20vw, 128px);
  line-height: .82;
  margin: 12px 0 20px -.04em;
  white-space: nowrap;
}
.who-line { margin: 0; font-size: 18px; line-height: 1.35; max-width: 28ch; }
/* a fallen ally is struck in the text's own colour: blood under the seal would be the one
   colour only a traitor's peek shows */
.who-line .is-gone {
  color: var(--dim);
  text-decoration-line: line-through;
  text-decoration-color: currentColor;
  text-decoration-thickness: 2px;
}
.who-secret > .item { margin-top: 16px; }

.who-peek { display: flex; align-items: center; gap: 22px; margin-top: 36px; }
.who-peek .seal { --size: 108px; flex: none; }
.who-hint { margin: 0; font-size: 15px; font-weight: 600; line-height: 1.3; color: var(--dim); max-width: 14ch; }
.who-hint b { color: var(--fg); }

/* while you peek, the rest of the page sinks into the dark */
#view:has(.who.is-peeking) > :not(.who) { opacity: .05; }

.seal[disabled] { opacity: .35; cursor: default; }

/* ---------- items: frost for the shield, steel for the dagger ---------- */

.item {
  display: grid;
  grid-template-columns: 30px 1fr;
  column-gap: 10px;
  align-items: start;
  margin: 0;
  font-size: 16px;
  line-height: 1.38;
  max-width: 34ch;
}
.item .sigil { width: 24px; height: 24px; color: var(--tone); }
.item b { color: var(--tone); font-weight: 700; }
.item.is-shield { --tone: color-mix(in srgb, var(--frost) 50%, var(--fg)); }
.item.is-dagger { --tone: color-mix(in srgb, var(--steel) 50%, var(--fg)); }

/* ---------- lists of lines ---------- */

.lines { list-style: none; margin: 0; padding: 0; }
.lines > li { border-top: 1px solid var(--faint); }
.lines > li:last-child { border-bottom: 1px solid var(--faint); }

.lines .seat {
  font-size: 13px;
  font-weight: 600;
  letter-spacing: .1em;
  color: var(--dim);
  font-variant-numeric: tabular-nums;
}

.letter {
  display: grid;
  grid-template-columns: 2.7em 1fr auto;
  column-gap: 8px;
  align-items: center;
  width: 100%;
  min-height: 62px;
  padding: 10px 0;
  border: 0;
  background: none;
  text-align: left;
}
.letter .sigil { width: 28px; height: 28px; color: var(--accent); transition: transform .4s var(--ease-out); }
.letter span { font-size: 22px; font-weight: 600; letter-spacing: -.02em; }
.letter time { font-size: 12px; font-weight: 600; letter-spacing: .16em; color: var(--dim); }
.letter:active .sigil { transform: rotate(-18deg) scale(.9); }

.chron > li,
.murmur > li,
.ledger > li {
  display: grid;
  grid-template-columns: 2.7em 1fr auto;
  column-gap: 8px;
  align-items: baseline;
  padding: 12px 0 11px;
}
.chron p, .murmur p, .ledger p { margin: 0; line-height: 1.36; overflow-wrap: anywhere; }
.chron p { font-size: 16px; }
.chron > li + li p { color: var(--dim); }

.news .lede { margin-top: 10px; }
.news b { color: var(--accent); font-weight: 600; }

/* ---------- cast extras ---------- */

.cast .tag.accent { color: var(--accent); }
.cast .tag.marks { color: var(--accent); font-size: 14px; letter-spacing: .14em; }

/* the end's traitors: a blackletter name needs the whole measure (it never breaks inside a
   word), so the tag steps down beneath it */
.cast > li.is-traitor { grid-template-columns: 2.7em 1fr; }
.cast > li.is-traitor .name {
  font-family: var(--f-ritual);
  font-weight: 800;
  font-size: clamp(30px, 10vw, 40px);
  line-height: .9;
  letter-spacing: 0;
  overflow-wrap: normal;
  color: var(--accent);
}
.cast > li.is-traitor .tag { grid-column: 2; text-align: left; margin-top: 6px; }

/* ---------- the dead ---------- */

.tomb-name {
  font-family: var(--f-ritual);
  font-weight: 800;
  font-size: clamp(76px, 25vw, 170px);
  line-height: .8;
  margin: 14px 0 0 -.05em;
  white-space: nowrap;
}
.tomb-line {
  margin: 18px 0 0;
  font-size: 13px;
  font-weight: 600;
  letter-spacing: .22em;
  text-transform: uppercase;
  color: var(--dim);
}

/* ---------- night ---------- */

body.is-sleep .spine,
body.is-sleep .mast { opacity: .16; }
body.is-sleep .stage { display: flex; flex-direction: column; }
/* centred vertically only: sections are inline-size containers and must keep their full width */
body.is-sleep #view { flex: 1; display: grid; align-content: center; }

.sleep { text-align: center; color: var(--dim); }
.sleep .breath { width: 80px; height: 80px; animation: breath 7.5s ease-in-out infinite; }
.sleep .ritual-m { margin-top: 34px; }
.sleep .lede { margin: 12px auto 0; }
@keyframes breath {
  0%, 100% { opacity: .14; transform: scale(.92); }
  50% { opacity: .55; transform: scale(1); }
}

.pack p:last-child { display: flex; flex-wrap: wrap; gap: 4px 24px; margin: 8px 0 0; font-size: 22px; font-weight: 600; letter-spacing: -.02em; }
.pack .seat { margin-right: 7px; font-size: 13px; letter-spacing: .1em; color: var(--accent); }

.whisper { display: flex; align-items: flex-end; gap: 18px; }
.whisper .field { flex: 1; min-width: 0; font-size: 22px; }
.whisper .text-btn { flex: none; min-height: 48px; }

.murmur p { font-size: 18px; }
.murmur b {
  display: block;
  margin-bottom: 3px;
  font-size: 11px;
  font-weight: 600;
  letter-spacing: .22em;
  text-transform: uppercase;
  color: var(--dim);
}

/* ---------- the round table ---------- */

/* the sealed vote peeks like the identity (.who). Its secret lies over the face without
   taking room, so the block is as tall for a short name as a long one, dagger or not. */
.sealed .who-stack { position: relative; }
.sealed .who-secret { position: absolute; left: 0; right: 0; bottom: 0; }
.sealed .who-face .lede { margin-top: 12px; }
.sealed .ritual-l { margin-top: 12px; }
.sealed .item { margin-top: 20px; }

.ticks { display: flex; gap: 9px; height: 32px; margin: 0 0 14px; }
.ticks i { width: 2px; background: var(--faint); transform: skewX(-14deg); transition: background-color .7s var(--ease-out); }
.ticks i.is-cast { background: var(--accent); }

.ledger p { font-size: 17px; }
.ledger b { font-weight: 600; }
.ledger .at-me b:last-child { color: var(--accent); }
.ledger .x { font-size: 12px; font-weight: 700; letter-spacing: .14em; color: color-mix(in srgb, var(--steel) 50%, var(--fg)); }

/* ---------- the omen: a private moment waiting (recruit.ts) ----------
   The scenes' gate brought into the page: the same words, the same pulsing seal. */

.omen {
  display: block;
  width: 100%;
  margin: 0;
  padding: 0;
  border: 0;
  background: none;
  color: inherit;
  font: inherit;
  text-align: left;
  user-select: none;
  -webkit-user-select: none;
  -webkit-touch-callout: none;
}
.omen > .kicker { display: block; }
.omen:active .omen-seal { border-color: var(--accent); }
.omen-row { display: flex; align-items: center; gap: 22px; margin-top: 16px; }
.omen-seal {
  position: relative;
  flex: none;
  width: 108px;
  height: 108px;
  border-radius: 50%;
  border: 1.5px solid var(--fg);
  display: grid;
  place-items: center;
  color: var(--accent);
  animation: omen 3.2s ease-in-out infinite;
}
.omen-seal::after {
  content: "";
  position: absolute;
  inset: -1.5px;
  border-radius: 50%;
  border: 1px solid var(--accent);
  animation: omen-echo 3.2s ease-out infinite;
}
.omen-seal svg { width: 52%; height: 52%; }
.omen-words { display: grid; gap: 12px; min-width: 0; }
.omen-line {
  font-family: var(--f-ritual);
  font-weight: 700;
  font-size: clamp(30px, 9vw, 52px);
  line-height: .9;
}
.omen-hint { color: var(--fg); }
.omen:focus-visible { outline: none; }
.omen:focus-visible .omen-seal { border-color: var(--accent); }
@keyframes omen { 0%, 100% { transform: scale(.95); opacity: .7; } 50% { transform: scale(1.03); opacity: 1; } }
/* the echo stays clear of the spine */
@keyframes omen-echo { 0% { transform: scale(1); opacity: .9; } 70%, 100% { transform: scale(1.45); opacity: 0; } }

/* ---------- the way in ---------- */

.join-hero .lede { margin-top: 26px; }
.join-fields { margin-top: 64px; }
.join-fields > .kicker { display: block; margin-bottom: 2px; }
.join-code { margin-top: 38px; }
.join-code > .kicker { display: block; margin-bottom: 2px; }
.join-code .field { max-width: 5.6em; text-transform: uppercase; letter-spacing: .3em; }
.join-note { margin: 12px 0 0; font-size: 15px; line-height: 1.4; color: var(--dim); max-width: 32ch; }

@media (max-width: 719px) {
  .join-hero .ritual { font-size: 27vw; }
}

@media (min-width: 720px) {
  #view > * + * { margin-top: 80px; }
  #view > .near { margin-top: 26px; }
  .who-name { font-size: 52px; }
  .who-peek .seal { --size: 124px; }
}

@media (prefers-reduced-motion: reduce) {
  @keyframes rise { from { opacity: 0; } }
  @keyframes breath { 0%, 100% { opacity: .14; } 50% { opacity: .55; } }
  @keyframes omen { 0%, 100% { opacity: .65; } 50% { opacity: 1; } }
  .omen-seal::after { animation: none; opacity: 0; }
}

/* Safari before 16.2 has no color-mix(): the frost and steel tones, mixed half with each light's fg */
@supports not (color: color-mix(in srgb, red 50%, blue)) {
  :root, html[data-light="night"] { --frost-on: #c4d5e2; --steel-on: #caccce; }
  html[data-light="day"]   { --frost-on: #546779; --steel-on: #5a5e64; }
  html[data-light="blood"] { --frost-on: #c7d0e3; --steel-on: #cdc7cf; }
  html[data-light="ash"]   { --frost-on: #abbbc9; --steel-on: #b1b3b5; }
  .item.is-shield { --tone: var(--frost-on); }
  .item.is-dagger { --tone: var(--steel-on); }
  .ledger .x { color: var(--steel-on); }
}
