:root {
  color: #22201d;
  background: #f6f3ee;
  font-family: "Hiragino Sans", "Yu Gothic", system-ui, -apple-system, sans-serif;
  line-height: 1.6;
  --ink: #22201d;
  --muted: #6f6a63;
  --line: #d9d3ca;
  --accent: #7a4b8f;
  --accent-soft: #ece4f1;
  --paper: #fffdf9;
}

* {
  box-sizing: border-box;
}

body {
  margin: 0;
  min-width: 320px;
}

a {
  color: var(--accent);
}

/* The header block: the brand row plus the category menu under it. Both
   stay together at the top of every page. */
.site-top {
  background: var(--paper);
  border-bottom: 1px solid var(--line);
}

.site-top .site-header {
  border-bottom: none;
}

.site-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 0.75rem 1rem;
  border-bottom: 1px solid var(--line);
  background: var(--paper);
}

.site-header .brand {
  font-weight: 700;
  text-decoration: none;
  color: var(--ink);
}

.site-footer {
  max-width: 44rem;
  margin: 2rem auto 0;
  padding: 1rem;
  border-top: 1px solid var(--line);
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
  gap: 0.5rem 1rem;
  font-size: 0.85rem;
}

.site-footer nav {
  display: flex;
  gap: 1rem;
}

.site-header .sign-in,
.button {
  display: inline-block;
  padding: 0.4rem 0.9rem;
  border-radius: 999px;
  background: var(--accent);
  color: #fff;
  text-decoration: none;
  font-size: 0.9rem;
}

main {
  max-width: 44rem;
  margin: 0 auto;
  padding: 1rem;
}

.lede,
.meta,
.count,
.empty,
.crumbs {
  color: var(--muted);
  font-size: 0.9rem;
}

.thread-list ul {
  list-style: none;
  padding: 0;
  margin: 0;
}

.thread-item {
  display: flex;
  justify-content: space-between;
  gap: 1rem;
  padding: 0.6rem 0;
  border-bottom: 1px solid var(--line);
}

.post {
  padding: 0.8rem 0;
  border-bottom: 1px solid var(--line);
}

.post header {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem;
  align-items: baseline;
  font-size: 0.85rem;
  color: var(--muted);
}

.post .pseudonym {
  color: var(--ink);
  font-weight: 600;
}

.post .body {
  white-space: pre-wrap;
  margin: 0.4rem 0 0;
}

.badge {
  display: inline-block;
  padding: 0 0.5rem;
  border-radius: 999px;
  background: var(--accent-soft);
  color: var(--accent);
  font-size: 0.75rem;
}

.composer {
  display: grid;
  gap: 0.75rem;
}

.button.secondary {
  background: var(--paper);
  color: var(--accent);
  border: 1px solid var(--accent);
}

.button[disabled] {
  opacity: 0.6;
}

.composer input,
.composer select,
.composer textarea {
  width: 100%;
  padding: 0.5rem;
  border: 1px solid var(--line);
  border-radius: 6px;
  font: inherit;
}

.composer textarea {
  min-height: 10rem;
}

.notice {
  padding: 0.6rem 0.8rem;
  border-radius: 6px;
  background: var(--accent-soft);
}

.notice p {
  margin: 0 0 0.4rem;
}

.notice p:last-child {
  margin-bottom: 0;
}

.hint {
  color: var(--muted);
  font-size: 0.85rem;
  margin: 0.2rem 0 0;
}

.checks {
  border: 1px solid var(--line);
  border-radius: 6px;
  padding: 0.6rem 0.8rem;
  display: grid;
  gap: 0.3rem;
}

.checks legend {
  font-weight: 600;
}

.check {
  display: flex;
  align-items: center;
  gap: 0.4rem;
}

.check input {
  width: auto;
}

.check.radio {
  align-items: flex-start;
}

.check.radio .hint {
  display: block;
}

.composer label .hint {
  display: block;
}

.actions {
  margin: 0.5rem 0;
}

.mod-nav {
  display: flex;
  align-items: center;
  gap: 1rem;
  margin-bottom: 0.75rem;
}

.dev-toggle {
  font-size: 0.85rem;
  color: var(--muted);
  margin-bottom: 0.75rem;
}

.queue-item {
  padding: 0.8rem 0;
  border-bottom: 1px solid var(--line);
}

.queue-item header {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem;
  align-items: baseline;
  font-size: 0.85rem;
}

.queue-item .excerpt {
  white-space: pre-wrap;
  margin: 0.4rem 0;
}

.tag {
  display: inline-block;
  padding: 0 0.5rem;
  border-radius: 999px;
  background: var(--accent-soft);
  color: var(--accent);
  font-size: 0.75rem;
}

.tag.overdue {
  background: #f7dcd8;
  color: #8a2f21;
}

.mod-actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.6rem;
  margin-top: 0.4rem;
}

.mod-actions select {
  padding: 0.3rem;
  border: 1px solid var(--line);
  border-radius: 6px;
  font: inherit;
}

.intro {
  padding: 0.9rem 1rem;
  margin-bottom: 1rem;
  border: 1px solid var(--line);
  border-radius: 8px;
  background: var(--paper);
}

.intro h2 {
  margin: 0 0 0.3rem;
  font-size: 1.05rem;
}

.intro p {
  margin: 0 0 0.6rem;
}

.checks.columns {
  grid-template-columns: repeat(auto-fill, minmax(11rem, 1fr));
}

.checks.columns legend,
.checks.columns .hint {
  grid-column: 1 / -1;
}

.composer textarea.short {
  min-height: 5rem;
}

.thread-item > div {
  display: flex;
  flex-direction: column;
  gap: 0.2rem;
  min-width: 0;
}

/* The row's one link: the opener's thumbnail, when there is one, and the
   title beside it. A row without a picture is the same link without the
   square, so nothing reserves empty space for a thumbnail that never comes. */
.thread-link {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  min-width: 0;
}

/* A fixed square whatever the picture's own shape: `cover` crops it rather
   than letting a portrait photograph make one row twice as tall as the next.
   The `img` carries the same number as `width` and `height` (contracts'
   ROW_THUMBNAIL_PX), so the box is held before the bytes arrive. */
.thread-link .thumb {
  flex: none;
  width: 64px;
  height: 64px;
  object-fit: cover;
  border-radius: 6px;
  border: 1px solid var(--line);
  background: var(--line);
}

.thread-title {
  min-width: 0;
}

.chips {
  display: inline-flex;
  flex-wrap: wrap;
  gap: 0.3rem;
  margin: 0;
}

.chip {
  display: inline-block;
  padding: 0 0.55rem;
  border-radius: 999px;
  border: 1px solid var(--line);
  background: var(--paper);
  color: var(--ink);
  font: inherit;
  font-size: 0.78rem;
  line-height: 1.5;
  text-decoration: none;
  cursor: pointer;
}

.chip.space {
  border-color: var(--accent);
  color: var(--accent);
}

.chip.clinic,
.chip.doctor,
.chip.agent {
  background: var(--accent-soft);
}

.chip.selected {
  background: var(--accent);
  border-color: var(--accent);
  color: #fff;
}

.chip.clear {
  border-style: dashed;
  color: var(--muted);
}

.chip-with-remove {
  display: inline-flex;
  gap: 0.2rem;
  align-items: center;
}

.filter-bar {
  display: grid;
  gap: 0.5rem;
  padding: 0.6rem 0;
  border-top: 1px solid var(--line);
  border-bottom: 1px solid var(--line);
  margin-bottom: 0.5rem;
}

.filter-group {
  display: flex;
  flex-wrap: wrap;
  gap: 0.3rem;
  align-items: center;
}

.filter-group > .meta {
  min-width: 4.5rem;
}

.tag-filters {
  display: grid;
  gap: 0.35rem;
}

.free-picker label {
  flex: 1 1 12rem;
}

.notice.rule {
  font-size: 0.9rem;
}

.thread-context {
  display: flex;
  flex-wrap: wrap;
  gap: 0.4rem;
  align-items: center;
}

.me .pseudonym {
  font-weight: 600;
  margin: 0 0 1rem;
}

.survey-summary {
  margin-top: 1.5rem;
  padding-top: 0.75rem;
  border-top: 1px solid var(--line);
}

.survey-summary h3 {
  font-size: 0.95rem;
  margin: 0.6rem 0 0.2rem;
}

.counts {
  list-style: none;
  padding: 0;
  margin: 0;
  max-width: 20rem;
}

.counts li {
  display: flex;
  justify-content: space-between;
  padding: 0.15rem 0;
  border-bottom: 1px solid var(--line);
}

/* Categories: the way in (decision D-011). The menu scrolls sideways on a
   phone rather than collapsing into a dropdown, so a category is always one
   tap away; the grid on the front page is the same fourteen with counts. */
.category-menu {
  display: flex;
  gap: 0.3rem;
  padding: 0 1rem 0.6rem;
  overflow-x: auto;
  scrollbar-width: thin;
}

.category-menu .chip {
  white-space: nowrap;
}

.categories {
  margin-bottom: 0.5rem;
}

.categories h1 {
  margin-bottom: 0.2rem;
}

.category-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(9rem, 1fr));
  gap: 0.4rem;
  margin-bottom: 1.5rem;
}

.category-card {
  display: flex;
  flex-direction: column;
  gap: 0.1rem;
  padding: 0.6rem 0.7rem;
  border: 1px solid var(--line);
  border-radius: 8px;
  background: var(--paper);
  color: var(--ink);
  text-decoration: none;
}

.category-card .category-name {
  font-weight: 600;
}

.chip.category {
  border-color: var(--accent);
  color: var(--accent);
}

.chip.category.selected {
  background: var(--accent);
  color: #fff;
}

/* The composer's required category picker: every category visible, wrapping
   over as many rows as a phone needs. */
.category-picker {
  display: flex;
  flex-wrap: wrap;
  gap: 0.3rem;
}

.category-field .hint {
  margin-bottom: 0.4rem;
}

.filter-group.suggested .meta,
.filter-group.controlled .meta {
  min-width: 4.5rem;
}

/* The two actions under a composer's body field: attaching an image and
   quoting an article. They read as things to do, not as more form furniture,
   which is why they are pill buttons in the form's own flow rather than
   folds a writer has to think to open. On a phone they wrap and each takes a
   full-width, thumb-sized row. */
.composer-actions {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem;
  margin: 0;
}

.composer-actions .action {
  background: var(--paper);
  color: var(--accent);
  border: 1px solid var(--accent);
  border-radius: 999px;
  padding: 0.45rem 1rem;
  font: inherit;
  line-height: 1.4;
  cursor: pointer;
}

/* An open section is shown as such, so the button says what state it is in
   rather than only what it does. */
.composer-actions .action[aria-expanded="true"] {
  background: var(--accent-soft);
}

@media (max-width: 30rem) {
  .composer-actions .action {
    flex: 1 1 100%;
    min-height: 2.75rem;
    text-align: center;
  }
}

/* One disclosure for everything optional: the extra tags in the composer and
   the quotation block. Closed by default. */
.more {
  border: 1px solid var(--line);
  border-radius: 6px;
  background: var(--paper);
  padding: 0.5rem 0.8rem;
}

.more > summary {
  cursor: pointer;
  font-weight: 600;
  padding: 0.2rem 0;
}

.more[open] > summary {
  margin-bottom: 0.5rem;
  border-bottom: 1px solid var(--line);
}

.more > * {
  margin-top: 0.5rem;
}

.citation-fields .counter {
  display: block;
  text-align: right;
}

.citation-fields .counter.over {
  color: #8a2f21;
}

/* The image picker (decision D-013). One row per picked file, so that a
   refusal names the file it belongs to and a stored image shows what the
   Worker actually kept. */
.image-drafts {
  list-style: none;
  margin: 0;
  padding: 0;
}

.image-draft {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-start;
  gap: 0.5rem;
  padding: 0.5rem 0;
  border-top: 1px solid var(--line);
}

.image-draft .thumb {
  width: 6rem;
  height: auto;
  border-radius: 6px;
  border: 1px solid var(--line);
}

.image-draft label {
  flex: 1 1 12rem;
}

.image-draft .notice {
  margin: 0;
}

.image-fields input[type="file"] {
  display: block;
}

.image-fields input[type="file"]:disabled {
  color: var(--muted);
}

/* The identity control: two options, immediately above the submit button,
   decided per post. The name field belongs to the first option, so it is
   indented under it and hidden while the second one is picked. */
.identity-choice {
  gap: 0.5rem;
}

.identity-name {
  margin-left: 1.5rem;
}

.identity-name label {
  display: block;
}

.hidden {
  display: none;
}

.sign-in-note {
  margin: 0 0 0.6rem;
}

.sign-in-note .inline {
  white-space: nowrap;
}

.notice.held p:not(:first-child) {
  margin-top: 0.3rem;
}

.pseudonym.default {
  color: var(--muted);
  font-weight: 500;
}

/* The post's number: the handle a reader points at and copies. It leads the
   header, ahead of the name, because it is what a reply will name. */
.post .post-number {
  color: var(--muted);
  font-variant-numeric: tabular-nums;
  text-decoration: none;
}

.post .post-number::before {
  content: "#";
}

.post .post-number:hover,
.post .post-number:focus {
  color: var(--accent);
  text-decoration: underline;
}

/* 返信 sits at the end of the header, away from the number, so that pointing
   at a post and answering it are two separate targets on a phone. */
.post .post-reply {
  margin-left: auto;
  color: var(--accent);
  font-size: 0.8rem;
}

/* The post a reply answers, above the reply's own body: the number, who
   wrote it, and enough of it to recognise. A parent moderation took down
   shows the "gone" line instead and nothing it said. */
.reply-card {
  margin: 0.3rem 0 0;
  padding: 0.3rem 0.6rem;
  border-left: 3px solid var(--line);
  background: var(--paper);
  color: var(--muted);
  font-size: 0.85rem;
  overflow-wrap: anywhere;
}

.reply-card .excerpt {
  color: var(--muted);
}

.reply-card.removed {
  font-style: italic;
}

/* The same card above the composer, so that a writer sees what a reader
   will see, with the control that takes the reference off again. */
.reply-card.composer-reply {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 0.3rem;
  margin: 0.6rem 0 0;
}

.reply-card button.action {
  margin-left: auto;
}

.reply-card .reply-target,
.post .body .post-ref {
  color: var(--accent);
  font-variant-numeric: tabular-nums;
}

/* A quoted article (decision D-013): clearly separated from the post's own
   text, with the attribution under it. */
.citation {
  margin: 0.6rem 0 0;
  padding: 0.5rem 0.8rem;
  border-left: 3px solid var(--accent);
  background: var(--paper);
}

.citation blockquote {
  margin: 0;
  white-space: pre-wrap;
}

.citation figcaption {
  margin-top: 0.3rem;
}

/* Attached images (decision D-013). The Leptos thread view lays them out in
   the grid; the Worker's own thread page prints the same images without it,
   so the picture rules are written for both. */
.attachments {
  margin: 0.6rem 0 0;
}

.image-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(8rem, 1fr));
  gap: 0.4rem;
  margin: 0;
}

.image-grid a {
  display: block;
  line-height: 0;
}

.attachments img {
  max-width: 100%;
  height: auto;
  border-radius: 6px;
  border: 1px solid var(--line);
}

.image-grid img {
  width: 100%;
}

.attachments figcaption,
.attachments .own-work {
  margin: 0.3rem 0 0;
  color: var(--muted);
  font-size: 0.8rem;
}

/* The line under an evidence badge saying what was checked and what was not.
   It sits between the header and the body, quiet enough not to compete with
   the post and close enough to the badge to belong to it. */
.post .evidence-note {
  margin: 0.2rem 0 0.4rem;
  color: var(--muted);
  font-size: 0.8rem;
  line-height: 1.5;
}

/* The author's receipt control, under their own post's thread. */
.author-evidence {
  margin-top: 1.5rem;
}

.evidence-offer {
  margin-bottom: 0.75rem;
}

/* The sensitivity warning is the one thing here that must not read as fine
   print: it comes before the file picker and says what is on the document. */
.evidence-sensitive {
  line-height: 1.6;
}

.evidence-item .evidence-claim h3 {
  margin: 0.6rem 0 0.2rem;
  font-size: 0.9rem;
}

@media (max-width: 30rem) {
  .thread-item {
    flex-direction: column;
    gap: 0.2rem;
  }

  .category-grid {
    grid-template-columns: repeat(auto-fill, minmax(7.5rem, 1fr));
  }

  .site-header {
    flex-wrap: wrap;
    gap: 0.4rem;
  }
}

/* The server-rendered header when the reader has a session. */
.site-header nav.session {
  display: flex;
  align-items: center;
  gap: 0.75rem;
}

.site-header nav.session a {
  color: inherit;
  font-weight: 600;
  text-decoration: none;
}

.site-header nav.session a:hover,
.site-header nav.session a:focus-visible {
  text-decoration: underline;
}

/* Catalog pages: one clinic, doctor, or agent, and the evidence under each
   value. The source line is deliberately part of the value's own block, not
   a footnote, so a value can never be read without it. */
.catalog-page h2 {
  font-size: 1.05rem;
  margin: 1.4rem 0 0.4rem;
}

.catalog-subtitle {
  margin: 0.2rem 0 0.8rem;
}

.catalog-disclaimer {
  background: var(--paper);
}

.fact-card dl,
.agent-card dl {
  margin: 0;
}

.fact {
  border-top: 1px solid var(--line);
  display: grid;
  gap: 0.15rem 1rem;
  grid-template-columns: minmax(8rem, 12rem) 1fr;
  padding: 0.6rem 0;
}

.fact dt {
  color: var(--muted);
  font-size: 0.9rem;
}

.fact dd {
  display: flex;
  flex-direction: column;
  gap: 0.2rem;
  margin: 0;
}

.fact .fact-value {
  font-weight: 600;
}

.fact.stale .fact-value {
  color: var(--muted);
}

.badge.stale {
  background: #f3ece0;
  color: #7a5b23;
}

.badge.registered {
  background: var(--accent-soft);
  color: var(--accent);
  margin-left: 0.5rem;
}

.registration {
  align-items: center;
  display: flex;
  flex-wrap: wrap;
  margin: 0.4rem 0;
}

.catalog-threads {
  margin-top: 1.6rem;
}

@media (max-width: 34rem) {
  .fact {
    grid-template-columns: 1fr;
  }
}

/* Operator tag review: one row per free name, with the catalog candidates
   an operator may map it to. */
.tag-review .mod-actions input[type="search"] {
  flex: 1 1 12rem;
  min-width: 0;
}

.candidates {
  list-style: none;
  margin: 0.4rem 0 0;
  padding: 0;
}

.candidates li {
  align-items: center;
  border-top: 1px solid var(--line);
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem;
  padding: 0.4rem 0;
}

/* The kind of a post: every option visible, the chosen one obvious. A select
   would hide four of the five behind a click and read as more important than
   it is. */
.kind-chips {
  border: 0;
  margin: 0;
  padding: 0;
}

.kind-chips legend {
  color: var(--muted, #6b6b6b);
  font-size: 0.85rem;
  padding: 0;
}

.chip-row {
  display: flex;
  flex-wrap: wrap;
  gap: 0.4rem;
  margin-top: 0.35rem;
}

.chip-option {
  cursor: pointer;
}

.chip-option input {
  position: absolute;
  opacity: 0;
  pointer-events: none;
}

.chip-option span {
  border: 1px solid var(--line, #d9d4cd);
  border-radius: 999px;
  display: inline-block;
  font-size: 0.85rem;
  padding: 0.3rem 0.75rem;
}

.chip-option input:checked + span {
  background: var(--accent, #6b3f8f);
  border-color: var(--accent, #6b3f8f);
  color: #fff;
}

.chip-option input:focus-visible + span {
  outline: 2px solid var(--accent, #6b3f8f);
  outline-offset: 2px;
}

/* The shell's placeholder, shown only while the wasm loads. It carries the
   name and one line, so a slow connection sees a page arriving rather than a
   white screen. */
.boot {
  padding: 3rem 1.25rem;
  text-align: center;
}

.boot .brand {
  font-weight: 700;
  font-size: 1.25rem;
  margin: 0 0 0.5rem;
}

/* Votes: the two counts under a post, and the pair a listing row shows.
   The pressed one is filled, so a reader can see what they did without the
   page having to be told who they are. */
.votes {
  display: flex;
  gap: 0.5rem;
  margin: 0.5rem 0 0;
}

.votes .vote {
  align-items: baseline;
  background: none;
  border: 1px solid var(--line, #d9d4cd);
  border-radius: 999px;
  color: var(--ink, #2b2b2b);
  cursor: pointer;
  display: inline-flex;
  font: inherit;
  font-size: 0.85rem;
  gap: 0.35rem;
  padding: 0.2rem 0.7rem;
}

.votes .vote[disabled] {
  cursor: progress;
  opacity: 0.6;
}

.votes .vote:hover,
.votes .vote:focus-visible {
  border-color: var(--accent, #6b3f8f);
}

.votes .vote.pressed {
  background: var(--accent, #6b3f8f);
  border-color: var(--accent, #6b3f8f);
  color: #fff;
}

.votes .count {
  font-variant-numeric: tabular-nums;
}

.votes.read-only .vote {
  border: 0;
  padding: 0;
}

.thread-item .votes {
  display: inline;
}

/* A post's footer: the votes on the left, the link to its answers on the
   right, so a long thread shows at a glance which posts were argued with. */
.post-actions {
  align-items: center;
  display: flex;
  flex-wrap: wrap;
  gap: 0.75rem;
  justify-content: space-between;
  margin-top: 0.5rem;
}

.post-actions .votes {
  margin: 0;
}

.reply-count {
  font-size: 0.85rem;
}

/* The page holding one post and its answers: the post it is about sits
   apart from them. */
.replies-page .parent-post .post {
  border-left: 3px solid var(--accent, #6b3f8f);
  padding-left: 0.75rem;
}

.replies-page .replies-heading {
  margin: 1rem 0 0.5rem;
}

/* The follow control, above the posts on a thread. */
.follow {
  margin: 0.5rem 0 1rem;
}

.follow-button.following {
  background: var(--paper, #fdfbf7);
  border: 1px solid var(--accent, #6b3f8f);
  color: var(--accent, #6b3f8f);
}

.follow-check {
  margin-top: 0.5rem;
}

/* Votes a signed-out reader cannot cast: the counts, and the sign-in behind
   the same two marks. */
.votes.signed-out {
  display: flex;
  gap: 0.5rem;
  margin: 0;
}

.votes.signed-out .vote {
  align-items: baseline;
  border: 1px dashed var(--line, #d9d4cd);
  border-radius: 999px;
  color: var(--ink, #2b2b2b);
  display: inline-flex;
  font-size: 0.85rem;
  gap: 0.35rem;
  padding: 0.2rem 0.7rem;
  text-decoration: none;
}

/* The member menu: one door per line, with the line under it saying what is
   behind it. */
.me-menu {
  list-style: none;
  margin: 1rem 0;
  padding: 0;
}

.me-menu-item {
  border-top: 1px solid var(--line, #d9d4cd);
  display: flex;
  flex-direction: column;
  gap: 0.15rem;
  padding: 0.85rem 0;
}

.me-menu-item:last-child {
  border-bottom: 1px solid var(--line, #d9d4cd);
}

.me-menu-link {
  font-weight: 600;
}

/* The follow list, where a thread is dropped without opening it. A dropped
   row stays put, struck through, until the page is next loaded. */
.follow-list {
  list-style: none;
  margin: 1rem 0;
  padding: 0;
}

.follow-row {
  align-items: baseline;
  border-top: 1px solid var(--line, #d9d4cd);
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem;
  justify-content: space-between;
  padding: 0.75rem 0;
}

.follow-row:last-child {
  border-bottom: 1px solid var(--line, #d9d4cd);
}

.follow-row.dropped .thread-link {
  opacity: 0.55;
  text-decoration: line-through;
}

.follow .following-note {
  margin-right: 0.5rem;
}

/* The header menu: the reader's own name, with everything else behind it.
   `<details>` so that the Worker's pages, which carry no script, get the
   same control as the browser app. */
.session-menu {
  position: relative;
}

.session-menu > summary {
  cursor: pointer;
  font-weight: 600;
  list-style: none;
  padding: 0.35rem 0.6rem;
}

.session-menu > summary::-webkit-details-marker {
  display: none;
}

.session-menu > summary::after {
  content: " ▾";
  font-size: 0.8em;
}

.session-menu[open] > summary {
  border-bottom: 2px solid var(--accent, #6b3f8f);
}

.session-menu .session {
  background: var(--paper, #fdfbf7);
  border: 1px solid var(--line, #d9d4cd);
  border-radius: 0.4rem;
  display: flex;
  flex-direction: column;
  gap: 0.25rem;
  min-width: 9rem;
  padding: 0.5rem;
  position: absolute;
  right: 0;
  top: 100%;
  z-index: 20;
}

.session-menu .session a,
.session-menu .session button.link {
  background: none;
  border: 0;
  color: var(--ink, #2b2b2b);
  cursor: pointer;
  font: inherit;
  padding: 0.3rem 0.25rem;
  text-align: left;
  text-decoration: none;
  white-space: nowrap;
}

.session-menu .session a:hover,
.session-menu .session a:focus-visible,
.session-menu .session button.link:hover,
.session-menu .session button.link:focus-visible {
  color: var(--accent, #6b3f8f);
  text-decoration: underline;
}

/* The sign-in page: one button per way in, with the line that says what that
   way gives. */
.sign-in-options {
  display: flex;
  flex-direction: column;
  gap: 1rem;
  list-style: none;
  margin: 1.5rem 0;
  padding: 0;
}

.sign-in-options li {
  display: flex;
  flex-direction: column;
  gap: 0.3rem;
}

.sign-in-option {
  text-align: center;
}

.sign-in-option.line {
  background: #06c755;
  border-color: #06c755;
}

/* A catalog page is a conversation with a record beside it, not a record with
   a conversation under it. One column on a narrow screen, comments first
   either way — which is also the order they are in the document. */
.catalog-columns {
  display: grid;
  gap: 2rem;
  grid-template-columns: minmax(0, 2fr) minmax(0, 1fr);
  align-items: start;
}

@media (max-width: 800px) {
  .catalog-columns {
    grid-template-columns: minmax(0, 1fr);
  }
}

.catalog-record {
  background: var(--paper, #fdfbf7);
  border: 1px solid var(--line, #d9d4cd);
  border-radius: 0.5rem;
  font-size: 0.92rem;
  padding: 0.75rem 1rem;
}

.catalog-record h2 {
  font-size: 1rem;
}

.catalog-comments .composer.inline {
  margin-top: 1.5rem;
}
