/*
  Local tokens, not brocade. The design system is not wired up yet and
  pretending otherwise would be worse than this — when brocade lands, this
  block is the seam to replace.

  The colours and faces below are the GROUND STATE, not Ansel's. An adventure
  carries its own and the shell sets them on the root at mount, so a beach
  adventure is not looked at through a valley in October. Everything here is
  what shows before an adventure has said otherwise.

  --them is mixed rather than given, so bubbles follow the paper they sit on.
  It used to be a literal, which meant one October colour would have survived
  onto every other theme.
*/
:root {
  --paper: #f6f3ec;
  --ink: #2e2a24;
  --ink-soft: #6d675d;
  --rule: #ddd6c8;
  --accent: #8a5a2b;
  --display: Georgia, "Iowan Old Style", serif;
  --body: Georgia, "Iowan Old Style", serif;
  --them: color-mix(in srgb, var(--paper) 86%, var(--ink) 14%);
  --measure: 34rem;
  --gap: 1rem;
  --radius: 0.9rem;
  --face: 3rem;
  --pace: 220ms;
  /* The ledger voice: labels, roles, small print. Dry on purpose, so the prose
     beside it stays the warm part. */
  --mono: ui-monospace, "SF Mono", "Cascadia Mono", Menlo, monospace;
  --small: 0.8rem;
  --tracking: 0.14em;
  --print: color-mix(in srgb, var(--paper) 45%, #fff);
  --lift: 0 0.15rem 0.8rem color-mix(in srgb, var(--ink) 16%, transparent);
  --pocket-w: 2.6rem;
  --pocket-h: 4.2rem;
  --pocket-tilt: -6deg;
  --icon: 3.6rem;
  --portrait-w: 4.4rem;
}

* { box-sizing: border-box; }

body {
  margin: 0;
  min-height: 100dvh;
  display: flex;
  flex-direction: column;
  background: var(--paper);
  color: var(--ink);
  font: 1rem/1.6 var(--body);
}

vellum-host { display: contents; }

header {
  padding: var(--gap);
  border-bottom: 1px solid var(--rule);
  text-align: center;
}
header b { font-family: var(--display); font-weight: 600; }
header span { display: block; color: var(--ink-soft); font-size: 0.85rem; }

#shell-root {
  flex: 1;
  display: flex;
  flex-direction: column;
  min-height: 0;
}

/* ---------- catalog ---------- */

.catalog {
  flex: 1;
  overflow-y: auto;
  scroll-snap-type: y mandatory;
}
.card {
  scroll-snap-align: start;
  min-height: 100%;
  display: flex;
  flex-direction: column;
  padding: 0 0 var(--gap);
  background: var(--paper);
  color: var(--ink);
  /* Designed for a phone; kept to a phone's measure on anything wider, or a
     full-bleed landscape is the whole screen and the words fall below it. */
  max-width: var(--measure);
  margin: 0 auto;
}
/* The mount does the work. Kind chooses the shape; theme chooses everything
   else, so two adventures may share a shape and share nothing else. */
.mount { position: relative; margin-bottom: var(--gap); }
.mount img { display: block; width: 100%; }
/* The photograph takes about half the card, so the name and the line are on
   paper rather than below the fold. */
.mount.both .land, .mount.place .land {
  max-height: 46vh;
  object-fit: cover;
}
.mount.both .who {
  position: absolute;
  right: var(--gap);
  bottom: calc(var(--gap) * -1.5);
  width: 28%;
  max-width: 8rem;
  /* A fixed display aspect, because the masters do not agree: Ansel's
     portraits were drawn square before kinds carried aspects and Ilberry's
     are 4:5. Two cards should differ by theme, not by when they were made. */
  aspect-ratio: 4 / 5;
  object-fit: cover;
  border: 3px solid var(--paper);
  border-radius: 2px;
  box-shadow: 0 1px 4px rgb(0 0 0 / 0.18);
}
.mount.people .who { width: 100%; max-height: 46vh; object-fit: cover; }
.mount.neither .mood { height: 6rem; background: var(--accent); opacity: 0.5; }

.card .kicker {
  margin: var(--gap) var(--gap) 0.2rem;
  font-size: 0.75rem;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--ink-soft);
}
.card h1 {
  font-family: var(--display);
  font-size: 1.9rem;
  font-weight: 600;
  margin: 0 var(--gap) 0.4rem;
}
.card .line { margin: 0 var(--gap) auto; color: var(--ink-soft); }
.card .go { margin: var(--gap) var(--gap) 0; align-self: flex-start; }

/* ---------- town ---------- */

.town {
  max-width: var(--measure);
  margin: 0 auto;
  padding: var(--gap);
  width: 100%;
}
.town h1 { font-family: var(--display); font-size: 1.3rem; font-weight: 600; margin: 0 0 0.3rem; }
.scene { color: var(--ink-soft); margin: 0 0 1.4rem; }

.people { list-style: none; margin: 0 0 1.6rem; padding: 0; display: grid; gap: 0.5rem; }
.person {
  width: 100%;
  text-align: left;
  font: inherit;
  color: inherit;
  display: flex;
  align-items: center;
  gap: 0.75rem;
  padding: 0.7rem 0.9rem;
  background: #fff;
  border: 1px solid var(--rule);
  border-radius: var(--radius);
  cursor: pointer;
}
.person:hover { background: var(--them); }
.person b { display: block; font-weight: 600; }
.person .said span { color: var(--ink-soft); font-size: 0.9rem; }

/* A portrait is authored ahead of play and never changes, so it is safe to
   crop hard: the same face sits in the same place every time you meet them. */
.face {
  flex: none;
  width: var(--face);
  height: var(--face);
  border-radius: 50%;
  object-fit: cover;
  background: var(--them);
  border: 1px solid var(--rule);
}

.possible {
  color: var(--accent);
  font-size: 0.7em;
  margin-left: 0.45em;
  vertical-align: 0.15em;
}

.ways { display: flex; flex-wrap: wrap; gap: 0.5rem; border-top: 1px solid var(--rule); padding-top: var(--gap); }
.go {
  font: inherit;
  color: var(--ink-soft);
  background: none;
  border: 1px solid var(--rule);
  border-radius: var(--radius);
  padding: 0.45rem 0.9rem;
  cursor: pointer;
}
.go:hover { color: var(--ink); background: #fff; }

/* ---------- conversation ---------- */

.conversation {
  flex: 1;
  display: flex;
  flex-direction: column;
  min-height: 0;
  width: 100%;
}
.who {
  max-width: var(--measure);
  width: 100%;
  margin: 0 auto;
  padding: var(--gap) var(--gap) 0.6rem;
  display: flex;
  align-items: center;
  justify-content: space-between;
}
.whom { display: flex; align-items: center; gap: 0.6rem; }
.who b { font-weight: 600; }
.leave {
  font: inherit;
  font-size: 0.9rem;
  color: var(--ink-soft);
  background: none;
  border: 0;
  cursor: pointer;
  text-decoration: underline;
}
.leave:hover { color: var(--ink); }

.log {
  flex: 1;
  overflow-y: auto;
  max-width: var(--measure);
  width: 100%;
  margin: 0 auto;
  padding: 0 var(--gap);
  display: flex;
  flex-direction: column;
  gap: 0.6rem;
}
.turn {
  padding: 0.6rem 0.9rem;
  border-radius: var(--radius);
  max-width: 85%;
  white-space: pre-wrap;
  animation: rise var(--pace) ease-out;
}
.them { background: var(--them); align-self: flex-start; }
.you  { align-self: flex-end; color: var(--ink-soft); }
.note { align-self: center; color: var(--ink-soft); font-size: 0.85rem; font-style: italic; }
@keyframes rise { from { opacity: 0; transform: translateY(0.25rem); } }

form {
  border-top: 1px solid var(--rule);
  padding: var(--gap);
  display: flex;
  gap: 0.5rem;
  max-width: var(--measure);
  margin: 0 auto;
  width: 100%;
}
input {
  flex: 1;
  font: inherit;
  padding: 0.6rem 0.8rem;
  border: 1px solid var(--rule);
  border-radius: var(--radius);
  background: #fff;
  color: inherit;
}
input:focus { outline: 2px solid var(--ink-soft); outline-offset: -1px; }
form button {
  font: inherit;
  padding: 0.6rem 1.1rem;
  border: 1px solid var(--rule);
  border-radius: var(--radius);
  background: #fff;
  color: inherit;
  cursor: pointer;
}
form button:disabled { opacity: 0.5; cursor: default; }

@media (prefers-reduced-motion: reduce) { .turn { animation: none; } }

/* ---------- postcards ---------- */

.post {
  display: block;
  width: 100%;
  font: inherit;
  text-align: left;
  margin: 0 0 1.2rem;
  padding: 0.7rem 0.9rem;
  background: #fff;
  border: 1px solid var(--rule);
  border-left: 3px solid var(--ink-soft);
  border-radius: var(--radius);
  cursor: pointer;
}
.post:hover { background: var(--them); }

.postcards {
  max-width: var(--measure);
  margin: 0 auto;
  padding: var(--gap);
  width: 100%;
}
.postcards h1 { font-family: var(--display); font-size: 1.3rem; font-weight: 600; margin: 0 0 1rem; }

.gallery { display: grid; gap: 1rem; margin-bottom: 1.4rem; }
.postcard { margin: 0; }
.postcard img {
  width: 100%;
  display: block;
  border: 1px solid var(--rule);
  border-radius: var(--radius);
  background: var(--them);
}
.postcard figcaption { padding-top: 0.4rem; font-size: 0.9rem; }
.postcard figcaption span { color: var(--ink-soft); }

.ask { border-top: 1px solid var(--rule); padding-top: var(--gap); }
.ask select {
  font: inherit;
  padding: 0.45rem 0.6rem;
  margin-right: 0.4rem;
  border: 1px solid var(--rule);
  border-radius: var(--radius);
  background: #fff;
  color: inherit;
}

/* ---------- the phone in your pocket (APP-0056) ----------
   A paper object low and left, where a hand is. Chrome, not a place. */
.pocket {
  position: fixed;
  left: var(--gap);
  bottom: var(--gap);
  width: var(--pocket-w);
  height: var(--pocket-h);
  padding: 0.3rem;
  border: 1px solid var(--rule);
  border-radius: calc(var(--radius) * 0.6);
  background: var(--print);
  box-shadow: var(--lift);
  transform: rotate(var(--pocket-tilt));
  transition: transform var(--pace) ease-out;
  cursor: pointer;
}
.pocket:hover, .pocket:focus-visible { transform: rotate(0deg) translateY(-0.2rem); }
.pocket-screen {
  display: block;
  height: 100%;
  border-radius: calc(var(--radius) * 0.4);
  background: color-mix(in srgb, var(--ink) 12%, var(--paper));
}
.pocket .wrote { position: absolute; top: -0.35rem; right: -0.35rem; color: var(--accent); }
/* The town scrolls under the pocket rather than behind it. */
.town { padding-bottom: calc(var(--pocket-h) + var(--gap) * 2); }

/* ---------- your phone's home screen (APP-0060) ---------- */
.phone {
  flex: 1;
  display: flex;
  flex-direction: column;
  padding: calc(var(--gap) * 1.5) var(--gap) var(--gap);
  background:
    linear-gradient(color-mix(in srgb, var(--ink) 30%, transparent), color-mix(in srgb, var(--ink) 55%, transparent)),
    var(--wallpaper) center / cover no-repeat;
  color: var(--paper);
}
.phone-where {
  margin: 0 0 calc(var(--gap) * 2);
  font: var(--small) var(--mono);
  letter-spacing: var(--tracking);
  text-transform: uppercase;
  text-align: center;
}
.phone-apps {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: var(--gap);
  justify-items: center;
  align-content: start;
  flex: 1;
}
.app-icon {
  display: grid;
  justify-items: center;
  gap: 0.35rem;
  padding: 0;
  border: 0;
  background: none;
  color: inherit;
  font: inherit;
  cursor: pointer;
}
.app-tile {
  display: grid;
  place-items: center;
  width: var(--icon);
  height: var(--icon);
  border-radius: calc(var(--radius) * 1.1);
  background: var(--print);
  color: var(--ink);
  box-shadow: var(--lift);
  font-size: 1.6rem;
}
.app-icon:focus-visible .app-tile { outline: 2px solid var(--paper); outline-offset: 2px; }
.app-label { font: var(--small) var(--body); }
.phone-away {
  align-self: center;
  margin-top: var(--gap);
  padding: 0.5rem 1.2rem;
  border: 1px solid color-mix(in srgb, var(--paper) 50%, transparent);
  border-radius: 999px;
  background: color-mix(in srgb, var(--ink) 35%, transparent);
  color: var(--paper);
  font: var(--small) var(--body);
  cursor: pointer;
}

/* ---------- contacts (APP-0035, APP-0040) ---------- */
.contacts {
  width: min(100%, var(--measure));
  margin: 0 auto;
  padding: var(--gap) var(--gap) calc(var(--gap) * 2);
}
.contacts-top { border-bottom: 1px solid var(--rule); padding-bottom: var(--gap); margin-bottom: var(--gap); }
.phone-back {
  padding: 0.2rem 0.4rem 0.2rem 0;
  border: 0;
  background: none;
  color: var(--ink-soft);
  font: 1.2rem var(--body);
  cursor: pointer;
}
.phone-back:hover { color: var(--ink); }
.contacts h1 { margin: 0.3rem 0 0; font: 600 2rem/1.1 var(--display); }
.contacts-under, .contacts h2, .contact-role {
  font-family: var(--mono);
  font-size: var(--small);
  color: var(--ink-soft);
}
.contacts-under { margin: 0.2rem 0 0; letter-spacing: 0.06em; }
.contacts h2 {
  margin: calc(var(--gap) * 1.4) 0 0.6rem;
  font-weight: 400;
  letter-spacing: var(--tracking);
  text-transform: uppercase;
}
.contacts-group ul { list-style: none; margin: 0; padding: 0; display: grid; gap: calc(var(--gap) * 1.2); }
.contact {
  display: flex;
  gap: var(--gap);
  align-items: flex-start;
  width: 100%;
  padding: 0;
  border: 0;
  background: none;
  color: inherit;
  font: inherit;
  text-align: left;
  cursor: pointer;
}
.contact:hover .contact-name, .contact:focus-visible .contact-name { text-decoration: underline; text-underline-offset: 0.2em; }
/* The canonical portrait: straight, 3:4, the calmest object on the surface. */
.contact-face {
  flex: none;
  width: var(--portrait-w);
  aspect-ratio: 3 / 4;
  padding: 0.25rem;
  background: var(--print);
  box-shadow: var(--lift);
}
.contact-face img { display: block; width: 100%; height: 100%; object-fit: cover; }
.contact-who { min-width: 0; }
.contact-name { font: 600 1.25rem/1.2 var(--display); margin-right: 0.5rem; }
.contact-role { line-height: 1.3; }
.contact-seems { margin: 0.3rem 0 0; }
.contact-seems.unread { color: var(--ink-soft); }
.contacts-empty { color: var(--ink-soft); font-style: italic; }

/* ---------- a contact card (APP-0036, APP-0037, APP-0039) ---------- */
.contact-card {
  width: min(100%, var(--measure));
  margin: 0 auto;
  padding: var(--gap) var(--gap) calc(var(--gap) * 2);
}
.card-top { display: flex; gap: var(--gap); align-items: flex-end; margin: 0.5rem 0 var(--gap); }
.card-print {
  flex: none;
  width: calc(var(--portrait-w) * 2.2);
  aspect-ratio: 3 / 4;
  margin: 0;
  padding: 0.4rem;
  background: var(--print);
  box-shadow: var(--lift);
}
.card-print img { display: block; width: 100%; height: 100%; object-fit: cover; }
.card-named h1 { margin: 0; font: 600 2rem/1.1 var(--display); }
.card-role { margin: 0.3rem 0 0; font: var(--small)/1.3 var(--mono); color: var(--ink-soft); }
.card-part { border-top: 1px solid var(--rule); padding-top: 0.8rem; margin-top: var(--gap); }
.card-part h2 {
  margin: 0 0 0.4rem;
  font: 400 var(--small) var(--mono);
  letter-spacing: var(--tracking);
  text-transform: uppercase;
  color: var(--ink-soft);
}
.card-part p { margin: 0; }
.card-quiet { color: var(--ink-soft); }
.card-ledger { list-style: none; margin: 0; padding: 0; display: grid; gap: 0.4rem; }
.card-ledger li { padding-bottom: 0.4rem; border-bottom: 1px solid var(--rule); }
.card-ledger li:last-child { border-bottom: 0; }

.card-write {
  margin-top: calc(var(--gap) * 1.5);
  padding: 0.6rem 1.2rem;
  border: 0;
  border-radius: 999px;
  background: var(--accent);
  color: var(--paper);
  font: 1rem var(--body);
  cursor: pointer;
}

/* ---------- the text thread (§11; APP-0048, APP-0027) ---------- */
.thread {
  flex: 1;
  min-height: 0;
  display: flex;
  flex-direction: column;
  width: min(100%, var(--measure));
  margin: 0 auto;
}
.thread-head {
  display: flex;
  gap: 0.8rem;
  align-items: flex-start;
  padding: var(--gap);
  border-bottom: 1px solid var(--rule);
  text-align: left;
}
.thread-head .contact-face { width: calc(var(--portrait-w) * 0.8); }
.thread-named { min-width: 0; }
.thread-named .contact-role { display: block; }
.thread-how { margin: 0.3rem 0 0; color: var(--ink-soft); font-size: 0.9rem; }
.thread-log {
  flex: 1;
  overflow-y: auto;
  display: flex;
  flex-direction: column;
  gap: 0.6rem;
  padding: var(--gap);
}
.text {
  max-width: 80%;
  padding: 0.6rem 0.9rem;
  border-radius: var(--radius);
  white-space: pre-wrap;
}
.text.theirs { align-self: flex-start; background: var(--print); box-shadow: var(--lift); }
.text.mine { align-self: flex-end; background: color-mix(in srgb, var(--accent) 16%, var(--paper)); }
.text-note { align-self: center; margin: 0; color: var(--ink-soft); font-size: 0.85rem; font-style: italic; }
.typing { display: flex; gap: 0.3rem; padding: 0.8rem 1rem; }
.typing span {
  width: 0.4rem;
  height: 0.4rem;
  border-radius: 50%;
  background: var(--ink-soft);
  opacity: 0.4;
}
@media (prefers-reduced-motion: no-preference) {
  .typing span { animation: typing calc(var(--pace) * 5) ease-in-out infinite; }
  .typing span:nth-child(2) { animation-delay: calc(var(--pace) * 0.8); }
  .typing span:nth-child(3) { animation-delay: calc(var(--pace) * 1.6); }
}
@keyframes typing { 50% { opacity: 1; } }
.composer {
  display: flex;
  gap: 0.5rem;
  padding: 0.8rem var(--gap) var(--gap);
  border-top: 1px solid var(--rule);
}
.composer input { flex: 1; border-radius: 999px; }
.composer-send {
  flex: none;
  width: 2.8rem;
  height: 2.8rem;
  border: 0;
  border-radius: 50%;
  background: var(--accent);
  color: var(--paper);
  font-size: 1.2rem;
  cursor: pointer;
}
.composer-send:disabled { opacity: 0.5; cursor: default; }
