:root {
  color-scheme: light;
  --page-bg: #ffffff;
  --body-background: var(--page-bg);
  --ink: #0b3ea8;
  --ink-soft: #315fb9;
  --line: #b7c9ef;
  --panel: #f7faff;
  --input-bg: #ffffff;
  --button-bg: #f7faff;
  --button-alt-bg: #eef5ff;
  --feedback-ok-bg: #eef5ff;
  --feedback-error-bg: #fff3f3;
  --status-error: #8f1f1f;
  --status-ok: #1f5e2e;
  --status-warning: #9a6400;
  --active-bg: #dce8ff;
  --active-ink: #082f7f;
  --active-line: #4d79d8;
  --active-ring: rgba(11, 62, 168, 0.14);
  --body-font: Georgia, "Times New Roman", serif;
  --ui-font: "Trebuchet MS", "Segoe UI", sans-serif;
  --code-font: "SFMono-Regular", Consolas, "Liberation Mono", Menlo, monospace;
}

/* Auto/System theme: system dark colors must be in the critical block,
   or the light defaults paint first while site.css loads. */
@media (prefers-color-scheme: dark) {
  :root:not([data-theme]) {
    color-scheme: dark;
    --body-background: var(--page-bg);
    --page-bg: #0b1220;
    --ink: #d9e7ff;
    --ink-soft: #9fb8e8;
    --line: #344a73;
    --panel: #111b31;
    --input-bg: #0f1729;
    --button-bg: #16233d;
    --button-alt-bg: #1b2b49;
    --feedback-ok-bg: #13263f;
    --feedback-error-bg: #3a1a23;
    --status-error: #ffb7c3;
    --status-ok: #a7efb8;
    --status-warning: #f2c66d;
    --active-bg: #263858;
    --active-ink: #f3f8ff;
    --active-line: #86a9e8;
    --active-ring: rgba(134, 169, 232, 0.18);
  }
}

* {
  box-sizing: border-box;
}

html {
  min-height: 100%;
  background-color: var(--page-bg);
}

body {
  margin: 0;
  min-height: 100vh;
  position: relative;
  isolation: isolate;
  font-family: var(--body-font);
  background: transparent;
  color: var(--ink);
  line-height: 1.5;
}

body::before {
  content: "";
  position: fixed;
  inset: 0;
  z-index: -1;
  pointer-events: none;
  background: var(--body-background);
  background-repeat: no-repeat;
  background-size: cover;
}

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

label {
  display: block;
  font-family: var(--ui-font);
  font-weight: 600;
}

input,
textarea,
button {
  width: 100%;
  margin-top: 0.35rem;
  border: 1px solid var(--line);
  border-radius: 0;
  padding: 0.65rem 0.7rem;
  font: inherit;
  color: var(--ink);
  background: var(--input-bg);
}

/* iOS Safari gives date/time inputs an intrinsic width that ignores width: 100%,
   so they overflow narrow containers and center their value. Drop the native
   appearance so they size like text inputs, and keep the value left-aligned. */
input:is([type="date"], [type="time"], [type="datetime-local"], [type="month"], [type="week"]) {
  appearance: none;
  -webkit-appearance: none;
  display: block;
  min-width: 0;
  max-width: 100%;
  min-height: calc(1.5em + 1.3rem + 2px);
}

input::-webkit-date-and-time-value {
  text-align: left;
}

button {
  appearance: none;
  -webkit-appearance: none;
  cursor: pointer;
  background: var(--button-bg);
  font-family: var(--ui-font);
}

button[type="button"] {
  background: var(--button-alt-bg);
}

pre {
  white-space: pre-wrap;
  word-break: break-word;
  margin: 0;
  font-family: var(--code-font);
}

.shell {
  width: min(100%, 760px);
  margin: 0 auto;
  padding: 1rem;
}

.site-header {
  padding: 0.5rem 0 1rem;
}

.site-header-actions {
  display: flex;
  align-items: center;
  gap: 0.75rem;
  justify-content: space-between;
}

.site-status-bar {
  display: none;
}

.app-version-banner {
  position: sticky;
  top: 0;
  z-index: 20;
}

.app-version-banner__inner {
  width: min(100%, 760px);
  margin: 0 auto;
  padding: 0.75rem 1rem 0;
  display: flex;
  align-items: center;
  justify-content: flex-start;
  gap: 0.75rem;
  flex-wrap: wrap;
}

.app-version-banner__text,
.app-version-banner__reload {
  border: 1px solid var(--line);
  background: var(--panel);
  font-family: var(--ui-font);
}

.app-version-banner__text {
  display: inline-block;
  padding: 0.55rem 0.7rem;
}

.app-version-banner__reload {
  width: auto;
  margin-top: 0;
  white-space: nowrap;
}

.offline-mode-bar {
  position: fixed;
  top: 0;
  right: 0;
  z-index: 15;
  border: 1px solid var(--line);
  border-top: 0;
  border-right: 0;
  background: var(--panel);
  color: var(--muted);
  font-family: var(--ui-font);
  font-size: 0.8rem;
  letter-spacing: 0.06em;
  line-height: 1;
  padding: 0 0.6rem;
  text-transform: uppercase;
  display: flex;
  align-items: center;
  gap: 0.6rem;
}

.offline-mode-bar a {
  display: inline-flex;
  align-items: center;
  min-height: 2.75rem;
  padding: 0 0.3rem;
}

.offline-mode-bar[hidden] {
  display: none;
}

.eyebrow {
  margin: 0 0 0.5rem;
  font-family: var(--ui-font);
  font-size: 0.8rem;
  text-transform: uppercase;
  letter-spacing: 0.08em;
}

.nav {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem;
  flex: 1 1 auto;
}

/* Page links: Previous at the left edge, Next and First page at the right, so
   a lone Next on page 1 stays where it will be on every later page. */
.pagination-nav {
  justify-content: flex-end;
}

.pagination-nav > .nav-link[rel="prev"] {
  margin-right: auto;
}

.nav-link {
  display: inline-block;
  padding: 0.45rem 0.7rem;
  border: 1px solid var(--line);
  text-decoration: none;
  background: var(--input-bg);
  font-family: var(--ui-font);
}

.nav-link.is-active {
  background: var(--panel);
}

/* Unread Messages: outline only, so the button's size and caption never change. */
.nav-link[data-unread-count]:not([data-unread-count="0"]) {
  outline: 2px solid var(--active-line);
  outline-offset: 2px;
}

.board-controls-nav .nav-link:disabled {
  width: auto;
  margin-top: 0;
  cursor: not-allowed;
  opacity: 0.55;
}

.tools-nav-divider {
  align-self: center;
  width: 1px;
  height: 1.4rem;
  background: var(--line);
  flex: 0 0 auto;
}

.nav-link-standalone-marker {
  margin-left: 0.2rem;
  opacity: 0.7;
}

.board-controls-nav > *:last-child:not([data-nav-key]) {
  margin-left: auto;
}

.theme-toggle {
  width: 1.5rem;
  min-width: 1.5rem;
  height: 1.5rem;
  margin-top: 0;
  flex: 0 0 auto;
}

.theme-swatch {
  padding: 0;
  border-radius: 999px;
  border: 1px solid var(--line);
  background: transparent;
  box-shadow: inset 0 0 0 0.22rem var(--page-bg);
}

.theme-swatch[data-theme-mode="auto"] {
  background:
    linear-gradient(135deg, #fff59a 0 50%, #17233f 50% 100%);
}

.theme-menu {
  position: relative;
  display: flex;
  align-items: center;
  gap: 0;
  padding: 0.15rem 0 0.15rem 0.15rem;
  border: 1px solid var(--line);
  border-radius: 999px;
  background: var(--input-bg);
  flex: 0 0 auto;
}

/* The palette is positioned outside the theme menu to preserve its size/anchor. */
.lcd-palette { display: none; }
.lcd-palette {
  position: absolute;
  z-index: 31;
  right: calc(100% + 0.5rem);
  top: 50%;
  transform: translateY(-50%);
}
.lcd-palette__trigger {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 2rem;
  height: 2rem;
  padding: 0;
  margin: 0;
  border: 1px solid var(--line);
  background: var(--input-bg);
}
.lcd-palette__chip {
  display: inline-block;
  width: 1rem;
  height: 1rem;
  flex: 0 0 auto;
  background: var(--lcd-chip, #a2b578);
  border: 1px solid var(--ink);
}
[data-palette-chip="green"] { --lcd-chip: #a2b578; }
[data-palette-chip="amber"], :root[data-lcd-palette="amber"] { --lcd-chip: #b6ab8b; }
[data-palette-chip="purple"], :root[data-lcd-palette="purple"] { --lcd-chip: #aaa1b7; }
[data-palette-chip="gray"], :root[data-lcd-palette="gray"] { --lcd-chip: #acb5aa; }
.lcd-palette__trigger:focus-visible {
  outline: 2px solid var(--ink);
  outline-offset: 2px;
}

.theme-menu__trigger {
  width: auto;
  min-width: 0;
  height: 1.5rem;
  margin-top: 0;
  padding: 0 0.4rem 0 0.3rem;
  border: none;
  border-radius: 0 999px 999px 0;
  background: transparent;
  color: var(--ink-soft);
  font-family: var(--ui-font);
  font-size: 0.7rem;
  line-height: 1;
  flex: 0 0 auto;
}

.theme-menu__trigger:hover,
.theme-menu__trigger[aria-expanded="true"] {
  color: var(--ink);
  background: var(--button-alt-bg);
}

.theme-menu__popover {
  position: absolute;
  right: 0;
  top: calc(100% + 0.4rem);
  z-index: 30;
  min-width: 11rem;
  border: 1px solid var(--line);
  background-color: var(--page-bg);
  background-image: linear-gradient(var(--panel), var(--panel));
  padding: 0.3rem;
  display: grid;
  gap: 4px;
  /* Fixed so a theme's body line height (Arena's 1.65) doesn't make the
     menu taller than the screen. */
  line-height: 1.5;
}

.theme-menu__popover[hidden] {
  display: none;
}

/* Light and dark columns: each row is a theme beside its counterpart in the
   other mode (ThemeRegistry::menuLayout); Auto spans both. */
.theme-menu__popover--columns {
  grid-template-columns: repeat(2, minmax(9.5rem, 1fr));
  min-width: 20rem;
}

.theme-menu__popover--columns [data-theme-column="both"],
.theme-menu__divider {
  grid-column: 1 / -1;
}

.theme-menu__heading {
  padding: 0.25rem 0.55rem 0;
  color: var(--ink-soft);
  font-family: var(--ui-font);
  font-size: 0.68rem;
  letter-spacing: 0.06em;
  text-transform: uppercase;
}

.theme-menu__divider {
  width: 100%;
  margin: 0.15rem 0;
  border: 0;
  border-top: 1px solid var(--line);
}

.theme-menu__empty {
  min-height: 2rem;
}

.theme-menu__option {
  display: flex;
  align-items: center;
  gap: 0.55rem;
  width: 100%;
  margin-top: 0;
  padding: 0.4rem 0.55rem;
  border: 1px solid transparent;
  background: transparent;
  font-family: var(--ui-font);
  font-size: 0.78rem;
  min-height: 2rem;
  text-align: left;
  cursor: pointer;
}

.theme-menu__option:not([data-theme-option="auto"]) {
  background: var(--body-background);
  background-color: var(--page-bg);
  color: var(--ink);
  border: 1px solid var(--line);
}

.theme-menu__option:hover {
  border-color: var(--ink-soft);
}

.theme-menu__option:focus-visible {
  outline: 2px solid var(--ink);
  outline-offset: -2px;
}

.theme-menu__option[aria-checked="true"] {
  border-color: var(--ink);
}

.theme-menu__option[aria-checked="true"]::after {
  content: "✓";
  margin-left: auto;
}

.theme-menu__swatch {
  width: 1rem;
  min-width: 1rem;
  height: 1rem;
  flex: 0 0 auto;
}

.main {
  display: block;
}

.stack > * + * {
  margin-top: 1rem;
}

.card {
  border: 1px solid var(--line);
  background: var(--panel);
  padding: 0.9rem;
  overflow-wrap: anywhere;
}

/* The card's padding is the space above its first line; a heading's default
   top margin would add a blank line on top of it. */
.card > :first-child,
.card > .visually-hidden:first-child + * {
  margin-top: 0;
}

/* App shell (`navigation` slot `app`): one row with the wordmark, the main
   destinations, New post and the account menu. Scoped so other sites keep
   today's header. The phone tab bar reuses the same nav. */
[data-shell="app"] .site-header--app {
  display: flex;
  align-items: center;
  gap: 1rem;
  padding: 0.5rem 0 1rem;
}

[data-shell="app"] .site-header--app .eyebrow {
  margin: 0;
  flex: 0 0 auto;
}

.site-brand {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  color: inherit;
  text-decoration: none;
}

.site-brand__mark:empty {
  display: none;
}

[data-shell="app"] .site-header--app .site-header-actions {
  flex: 1 1 auto;
  justify-content: flex-start;
}

[data-shell="app"] .site-header--app .nav {
  flex: 0 1 auto;
}

/* Desktop: the bar holds every main destination, which is wider than the
   760px content column. The header spans up to 1180px, centred on the column,
   and the links sit a little tighter; below that the nav wraps. */
@media (min-width: 640px) {
  [data-shell="app"] .site-header--app {
    --app-header-width: min(100vw - 3rem, 1180px);
    width: var(--app-header-width);
    margin-inline: calc((100% - var(--app-header-width)) / 2);
    align-items: flex-start;
  }

  [data-shell="app"] .site-header--app .site-header-actions {
    align-items: flex-start;
  }

  [data-shell="app"] .site-header--app .eyebrow {
    margin-top: 0.55rem;
  }

  [data-shell="app"] .site-header--app .nav {
    gap: 0.35rem;
  }

  [data-shell="app"] .site-header--app .nav > .nav-link {
    padding: 0.4rem 0.6rem;
  }

  /* Word97, Midnight, Chicago and LCD frame the header. Other themes have nothing
     marking its edges, so a rule across the page makes it a bar. A border-image outset, unlike a wide
     pseudo-element, cannot cause sideways scrolling. */
  :root:not([data-theme="word97"], [data-theme="midnight"], [data-theme="chicago"], [data-theme="lcd"]) [data-shell="app"] .site-header--app {
    margin-bottom: 0.75rem;
    padding-bottom: 0.75rem;
    border-bottom: 1px solid var(--line);
    border-image: linear-gradient(var(--line), var(--line)) 1 / 0 0 1px / 0 100vw;
  }
}

/* With room in the margins, the links start at the content's left edge and the
   name sits outside it. Percentages here resolve against the content column.
   Sticker's wide links set the width: below it they would wrap. */
@media (min-width: 1240px) {
  :root:not([data-theme="word97"], [data-theme="midnight"], [data-theme="chicago"], [data-theme="lcd"]) [data-shell="app"] .site-header--app {
    position: relative;
    padding-left: calc((var(--app-header-width) - 100%) / 2);
  }

  :root:not([data-theme="word97"], [data-theme="midnight"], [data-theme="chicago"], [data-theme="lcd"]) [data-shell="app"] .site-header--app .eyebrow {
    position: absolute;
    top: 0.5rem;
    left: 0;
  }
}

/* `:root` outranks themes' general link colors so the button keeps its own ink. */
:root [data-shell="app"] .new-post-button {
  display: inline-flex;
  align-items: center;
  gap: 0.35rem;
  margin-left: auto;
  padding: 0.45rem 0.8rem;
  border: 1px solid var(--line);
  background: var(--input-bg);
  color: var(--ink);
  font-family: var(--ui-font);
  font-weight: 600;
  text-decoration: none;
  white-space: nowrap;
}

/* Only the compose page, where it is the current destination, gets the selected colors. */
:root [data-shell="app"] .new-post-button:where(.is-active) {
  border-color: var(--active-line);
  background: var(--active-bg);
  color: var(--active-ink);
}

/* Deploy now, by the site name: deploy_prompt.js reveals it for an operator's
   browser. It sits outside .site-header-actions, so the phone tab bar keeps its tabs. */
.deploy-prompt {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  margin-left: 0.75rem;
  vertical-align: middle;
}

.deploy-prompt[hidden] {
  display: none;
}

/* Wider screens: under the site name, so the destinations beside it neither shift nor wrap. */
@media (min-width: 640px) {
  .deploy-prompt {
    display: flex;
    width: max-content;
    margin: 0.3rem 0 0;
  }
}

:root .deploy-prompt__button {
  padding: 0.2rem 0.6rem;
  border: 1px solid var(--active-line, var(--line));
  background: var(--active-bg, var(--input-bg));
  color: var(--active-ink, var(--ink));
  font: 600 0.85rem/1.2 var(--ui-font);
  cursor: pointer;
}

.deploy-prompt__button:disabled {
  cursor: progress;
  opacity: 0.7;
}

.deploy-prompt__status {
  font: 0.8rem/1.2 var(--ui-font);
  text-transform: none;
  letter-spacing: normal;
}

.deploy-prompt__status:empty {
  display: none;
}

.new-post-button__icon {
  font-size: 1.1em;
  line-height: 1;
}

.account-menu {
  position: relative;
  flex: 0 0 auto;
}

.account-menu > summary {
  list-style: none;
}

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

.account-menu__trigger {
  display: inline-flex;
  align-items: center;
  gap: 0.35rem;
  padding: 0.45rem 0.7rem;
  border: 1px solid var(--line);
  background: var(--input-bg);
  font-family: var(--ui-font);
  cursor: pointer;
}

.account-menu__icon {
  width: 1.1rem;
  height: 1.1rem;
  border-radius: 50%;
  border: 2px solid currentColor;
  flex: 0 0 auto;
}

.account-menu[open] > .account-menu__trigger {
  background: var(--panel);
}

/* Desktop: on a page listed in the account menu (Account, Invite, own Profile) the
   You button is the current destination, so it takes the selected look. Phones show
   that page's name on the More tab instead (data-current below). */
@media (min-width: 640px) {
  :root .account-menu[data-current-menu] > .account-menu__trigger {
    border-color: var(--active-line);
    background: var(--active-bg);
    color: var(--active-ink);
    font-weight: 600;
  }
}

/* The trigger reads "You" on desktop and "More" on phones; the More list of
   bar destinations exists only for phones. Both are decided in CSS so the
   server HTML is the same at every width. */
.account-menu__label--more,
.account-menu__label--current,
.account-menu__links.account-menu__more {
  display: none;
}

.account-menu__panel {
  position: absolute;
  right: 0;
  top: calc(100% + 0.4rem);
  z-index: 30;
  display: grid;
  gap: 0.75rem;
  min-width: 14rem;
  padding: 0.6rem;
  border: 1px solid var(--line);
  /* Some themes make --panel translucent; the page color underneath keeps the menu opaque. */
  background: linear-gradient(var(--panel), var(--panel)), var(--page-bg, Canvas);
  box-shadow: 0 10px 24px rgba(0, 0, 0, 0.14);
}

.account-menu__links {
  display: grid;
  gap: 0.35rem;
}

.account-menu__links .nav-link {
  display: block;
}

.account-menu__controls {
  display: flex;
  align-items: center;
  justify-content: flex-end;
  gap: 0.5rem;
  flex-wrap: wrap;
}

/* Phones: the same nav, New post and account menu become a bottom tab bar,
   in document order. Bottom-pinned page parts move up by the bar height. */
@media (max-width: 639px) {
  [data-shell="app"] {
    --app-tabbar-height: calc(3.5rem + env(safe-area-inset-bottom, 0px));
    /* What bottom-pinned parts clear: the bar while shown, only the safe area while hidden. */
    --app-tabbar-offset: var(--app-tabbar-height);
  }

  [data-shell="app"][data-tabbar="hidden"] {
    --app-tabbar-offset: env(safe-area-inset-bottom, 0px);
  }

  /* Pages without the bar (a single conversation): bottom-pinned parts clear only the safe area. */
  [data-shell="app"][data-tabbar-page="none"] {
    --app-tabbar-height: env(safe-area-inset-bottom, 0px);
    --app-tabbar-offset: env(safe-area-inset-bottom, 0px);
  }

  [data-shell="app"] .main {
    padding-bottom: var(--app-tabbar-height);
  }

  [data-shell="app"] .site-header--app {
    padding-bottom: 0.5rem;
  }

  [data-shell="app"] .site-header--app .site-header-actions {
    position: fixed;
    left: 0;
    right: 0;
    bottom: 0;
    z-index: 25;
    display: flex;
    align-items: stretch;
    gap: 0.25rem;
    min-height: var(--app-tabbar-height);
    padding: 0.3rem 0.3rem calc(0.3rem + env(safe-area-inset-bottom, 0px));
    border-top: 1px solid var(--line);
    background: linear-gradient(var(--panel), var(--panel)), var(--page-bg, Canvas);
    transition: transform 0.2s ease;
  }

  /* tab_bar_scroll.js hides the bar while scrolling down. The shown state keeps
     `transform: none` so the menu's fixed popovers position against the screen. */
  [data-shell="app"][data-tabbar="hidden"] .site-header--app .site-header-actions {
    transform: translateY(100%);
  }

  [data-shell="app"][data-tabbar-page="none"] .site-header--app .site-header-actions {
    display: none;
  }

  /* Without the bar the page fills the screen, so a short page can still end at the bottom edge. */
  [data-shell="app"][data-tabbar-page="none"] {
    display: flex;
    flex-direction: column;
    min-height: 100svh;
    padding-bottom: 0;
  }

  [data-shell="app"][data-tabbar-page="none"] .main {
    flex: 1 0 auto;
    display: flex;
    flex-direction: column;
  }

  [data-shell="app"] .site-header--app .nav {
    display: contents;
  }

  /* The disclosure itself takes no space, so its trigger is a tab like the
     links, with the same padding and border and therefore the same width. */
  [data-shell="app"] .site-header--app .account-menu {
    display: contents;
  }

  [data-shell="app"] .site-header--app .nav > .nav-link,
  [data-shell="app"] .site-header--app .new-post-button,
  [data-shell="app"] .site-header--app .account-menu__trigger {
    flex: 1 1 0;
    display: flex;
    align-items: center;
    justify-content: center;
    min-width: 0;
    min-height: 2.75rem;
    margin: 0;
    padding: 0.25rem;
    font-size: 0.85rem;
    text-align: center;
  }

  [data-shell="app"] .site-header--app .nav > .nav-link,
  [data-shell="app"] .site-header--app .account-menu__trigger {
    border-color: transparent;
    background: transparent;
  }

  /* `:root` outranks themes' general link colors so the highlighted tab keeps readable ink. */
  :root [data-shell="app"] .site-header--app .nav > .nav-link.is-active,
  :root [data-shell="app"] .account-menu[open] > .account-menu__trigger {
    border-color: var(--line);
    background: var(--active-bg);
    color: var(--active-ink);
  }

  [data-shell="app"] .site-header--app .new-post-button__label {
    white-space: normal;
    line-height: 1.1;
  }

  /* More: the panel fills the screen above the tab bar; the More tab stays
     visible and highlighted, and tapping it again closes the panel. Items sit
     at the bottom, by the tab bar. The auto margin drops to zero when they
     overflow, so a short screen can still scroll to the first one. */
  [data-shell="app"] .account-menu__panel {
    position: fixed;
    top: 0;
    left: 0;
    right: 0;
    bottom: var(--app-tabbar-height);
    display: flex;
    flex-direction: column;
    width: auto;
    max-height: none;
    padding: 1rem 1rem 1.5rem;
    overflow-y: auto;
  }

  [data-shell="app"] .account-menu__panel > :first-child {
    margin-top: auto;
  }

  [data-shell="app"] .site-header--app .nav > .nav-link[data-phone="more"],
  [data-shell="app"] .account-menu__label--you {
    display: none;
  }

  /* Phone tabs: <html data-nav-slots="board calendar recent"> (the server's
     starting tabs, replaced before paint by the browser's saved choice) shows
     those destinations as tabs, in bar order, before New post and More. */
  html[data-nav-slots~="board"] [data-shell="app"] .site-header--app .nav > .nav-link[data-tab="board"],
  html[data-nav-slots~="lobby"] [data-shell="app"] .site-header--app .nav > .nav-link[data-tab="lobby"],
  html[data-nav-slots~="recent"] [data-shell="app"] .site-header--app .nav > .nav-link[data-tab="recent"],
  html[data-nav-slots~="calendar"] [data-shell="app"] .site-header--app .nav > .nav-link[data-tab="calendar"],
  html[data-nav-slots~="gallery"] [data-shell="app"] .site-header--app .nav > .nav-link[data-tab="gallery"],
  html[data-nav-slots~="profiles"] [data-shell="app"] .site-header--app .nav > .nav-link[data-tab="profiles"],
  html[data-nav-slots~="messages"] [data-shell="app"] .site-header--app .nav > .nav-link[data-tab="messages"],
  html[data-nav-slots~="inbox"] [data-shell="app"] .site-header--app .nav > .nav-link[data-tab="inbox"],
  html[data-nav-slots~="search"] [data-shell="app"] .site-header--app .nav > .nav-link[data-tab="search"],
  html[data-nav-slots~="about"] [data-shell="app"] .site-header--app .nav > .nav-link[data-tab="about"],
  html[data-nav-slots~="tools"] [data-shell="app"] .site-header--app .nav > .nav-link[data-tab="tools"] {
    display: flex;
    order: 1;
  }

  [data-shell="app"] .site-header--app .new-post-button {
    order: 2;
  }

  [data-shell="app"] .site-header--app .account-menu__trigger {
    order: 3;
  }

  [data-shell="app"] .account-menu__links.account-menu__more {
    display: grid;
  }

  /* On a page listed in the panel, the More tab shows that page's name and the
     selected look, unless the page holds a slot and is highlighted there. Only the
     name carries the look, so that one per-section list decides all of it. */
  [data-shell="app"] .account-menu[data-current] {
    --more-tab-word: none;
    --more-tab-name: inline;
    --more-tab-icon: none;
  }

  html[data-nav-slots~="board"] [data-shell="app"] .account-menu[data-current="board"],
  html[data-nav-slots~="lobby"] [data-shell="app"] .account-menu[data-current="lobby"],
  html[data-nav-slots~="recent"] [data-shell="app"] .account-menu[data-current="recent"],
  html[data-nav-slots~="calendar"] [data-shell="app"] .account-menu[data-current="calendar"],
  html[data-nav-slots~="gallery"] [data-shell="app"] .account-menu[data-current="gallery"],
  html[data-nav-slots~="profiles"] [data-shell="app"] .account-menu[data-current="profiles"],
  html[data-nav-slots~="messages"] [data-shell="app"] .account-menu[data-current="messages"],
  html[data-nav-slots~="inbox"] [data-shell="app"] .account-menu[data-current="inbox"],
  html[data-nav-slots~="search"] [data-shell="app"] .account-menu[data-current="search"],
  html[data-nav-slots~="about"] [data-shell="app"] .account-menu[data-current="about"],
  html[data-nav-slots~="tools"] [data-shell="app"] .account-menu[data-current="tools"] {
    --more-tab-word: initial;
    --more-tab-name: initial;
    --more-tab-icon: initial;
  }

  [data-shell="app"] .account-menu__label--more {
    display: var(--more-tab-word, inline);
  }

  [data-shell="app"] .account-menu__label--current {
    display: var(--more-tab-name, none);
    color: var(--active-ink);
    font-weight: 600;
    white-space: nowrap;
  }

  [data-shell="app"] .account-menu__label--current::before {
    content: "";
    position: absolute;
    z-index: -1;
    inset: -1px;
    border: 1px solid var(--line);
    background: var(--active-bg);
  }

  [data-shell="app"] .site-header--app .account-menu__trigger {
    position: relative;
    isolation: isolate;
  }

  /* Themes without their own More glyph (all but the icon themes in theme-nav-icons.css): three bars, drawn in the tab's ink. On a
     renamed tab an arrow replaces them, leaving room for the name. */
  :root:not([data-theme="word97"], [data-theme="chicago"], [data-theme="midnight"], [data-theme="gloss"], [data-theme="glossdark"], [data-theme="engagify"], [data-theme="bubblegum"]) [data-shell="app"] .account-menu__icon {
    display: var(--more-tab-icon, inline-block);
    border: 0;
    border-radius: 0;
    background:
      linear-gradient(currentColor, currentColor) 0 15% / 100% 2px no-repeat,
      linear-gradient(currentColor, currentColor) 0 50% / 100% 2px no-repeat,
      linear-gradient(currentColor, currentColor) 0 85% / 100% 2px no-repeat;
  }

  :root:not([data-theme="word97"], [data-theme="chicago"], [data-theme="midnight"], [data-theme="gloss"], [data-theme="glossdark"], [data-theme="engagify"], [data-theme="bubblegum"]) [data-shell="app"] .account-menu__label--current::after {
    content: "\25B4";
    position: absolute;
    top: -0.05rem;
    left: 0;
    right: 0;
    font-size: 1.1rem;
    line-height: 1;
    text-align: center;
  }

  [data-shell="app"] .account-menu__more .nav-link,
  [data-shell="app"] .account-menu__links .nav-link {
    padding: 0.7rem 0.8rem;
    font-size: 1rem;
  }

  /* Two links to a row, so the whole panel, theme menu included, fits one
     phone screen without scrolling. */
  [data-shell="app"] .account-menu__links {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }

  [data-shell="app"] .account-menu__links .nav-link {
    overflow-wrap: anywhere;
  }

  /* Unread Messages shows on the More tab the same way it shows on the link. */
  [data-shell="app"] .account-menu__trigger[data-unread-count]:not([data-unread-count="0"]) {
    outline: 2px solid var(--active-line);
    outline-offset: -2px;
  }

  /* The LCD palette's centering transform would make its fixed popover
     position against the palette instead of the screen. */
  [data-shell="app"] .account-menu .lcd-palette {
    top: 0;
    transform: none;
  }

  /* Theme and LCD palette popovers open upward and stay inside the screen. */
  [data-shell="app"] .account-menu .theme-menu__popover {
    position: fixed;
    top: auto;
    right: 0.3rem;
    /* clear the menu's controls row so the theme and palette buttons stay usable */
    bottom: calc(var(--app-tabbar-height) + 3.75rem);
    max-height: calc(100vh - var(--app-tabbar-height) - 4.5rem);
    overflow-y: auto;
  }

  /* Decorative theme status bars (Word 97, Midnight) give way to the tab bar. */
  :root [data-shell="app"] > .site-status-bar {
    display: none;
  }
}

@media (max-width: 639px) and (prefers-reduced-motion: reduce) {
  [data-shell="app"] .site-header--app .site-header-actions {
    transition: none;
  }
}

@media (max-width: 639px) and (pointer: coarse) {
  :root [data-shell="app"] [data-reply-panel][data-reply-panel].reply-panel-reading {
    bottom: calc(var(--app-tabbar-offset) + max(var(--reply-panel-bottom, 8px), 0px));
  }
}

/* List board (`boardCard` slot `list`): a toolbar with separate filter and
   sort controls, then pinned and latest threads as hairline-separated rows. */
.board-toolbar {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.5rem;
}

.board-filter {
  display: flex;
  gap: 0.25rem;
}

.board-filter .nav-link[aria-current] {
  border-color: var(--active-line);
  background: var(--active-bg);
  color: var(--active-ink);
}

.board-sort {
  position: relative;
}

.visually-hidden {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

.board-sort > summary {
  list-style: none;
  cursor: pointer;
}

.board-sort > summary::-webkit-details-marker {
  display: none;
}

.board-sort > summary::after {
  content: " \25BE";
}

.board-sort__menu {
  position: absolute;
  top: calc(100% + 0.3rem);
  left: 0;
  z-index: 20;
  display: grid;
  gap: 0.25rem;
  min-width: 10rem;
  padding: 0.4rem;
  border: 1px solid var(--line);
  background: linear-gradient(var(--panel), var(--panel)), var(--page-bg, Canvas);
}

.board-sort__menu--end {
  left: auto;
  right: 0;
}

.board-sort__menu .nav-link[aria-current] {
  color: var(--active-ink);
  background: var(--active-bg);
}

.board-tags-link {
  margin-left: auto;
}

.section-label {
  margin: 0.4rem 0 -0.4rem;
  font-family: var(--ui-font);
  font-size: 0.8rem;
  font-weight: 600;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--ink-soft);
}

.thread-rows {
  border: 1px solid var(--line);
  background: var(--panel);
}

/* A module: one card holding its heading, its list and its actions (Messages,
   and each Unread section). The list sits inside the card instead of being a
   second window below it. */
.card > .thread-rows,
.card > .inbox-catch-up,
.card > .message-list-footer:has(> :not([hidden]):not(.visually-hidden)) {
  margin-top: 0.75rem;
}

.message-list-rows > .message-list-row + .message-list-row {
  border-top: 1px solid var(--line);
}

.message-list-rows:not(:has(> [data-conversation-row]:not([hidden]))) {
  display: none;
}

.thread-row {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  column-gap: 0.75rem;
  padding: 0.6rem 0.9rem;
  overflow-wrap: anywhere;
}

.thread-row + .thread-row {
  border-top: 1px solid var(--line);
}

.thread-row__title {
  margin: 0;
  font-size: 1.05rem;
  line-height: 1.3;
}

.thread-row__count {
  grid-column: 2;
  grid-row: 1 / span 3;
  margin: 0;
  text-align: right;
  font-family: var(--ui-font);
  color: var(--ink-soft);
}

.thread-row__count-number {
  display: block;
  font-size: 1.05rem;
  font-weight: 600;
  color: var(--ink);
}

.thread-row__count-label {
  font-size: 0.75rem;
}

.thread-row__excerpt,
.thread-row__meta,
.thread-row > .event-block {
  grid-column: 1;
  margin: 0.15rem 0 0;
}

.thread-row__excerpt {
  overflow: hidden;
  white-space: nowrap;
  text-overflow: ellipsis;
  color: var(--ink-soft);
}

.thread-row__meta {
  font-size: 0.85rem;
}

/* A row with an attached image: the thumbnail fills a narrow first column as
   tall as the row; the image never adds height of its own. */
.thread-row--thumb {
  grid-template-columns: 4.5rem minmax(0, 1fr) auto;
}

.thread-row--thumb > .thread-row__title,
.thread-row--thumb > .thread-row__excerpt,
.thread-row--thumb > .thread-row__meta,
.thread-row--thumb > .event-block {
  grid-column: 2;
}

.thread-row--thumb > .thread-row__count {
  grid-column: 3;
}

.thread-row__thumb {
  grid-column: 1;
  grid-row: 1 / span 4;
  align-self: center;
  position: relative;
  display: block;
  aspect-ratio: 1;
  overflow: hidden;
  border: 1px solid var(--line);
  background: var(--panel);
}

/* Fill the square and crop the edges: a list thumbnail is for recognising the image. */
.thread-row__thumb img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.chip {
  display: inline-block;
  padding: 0 0.4rem;
  border: 1px solid var(--line);
  border-radius: 999px;
  font-family: var(--ui-font);
  font-size: 0.75rem;
  line-height: 1.5;
  vertical-align: 1px;
}

.chip--pending {
  border-color: var(--status-warning, var(--line));
  color: var(--status-warning, var(--ink-soft));
}

/* The Pending chip beside an author opens their summary
   (pending_user_summary.js); the chip keeps its own colours. */
.pending-chip {
  text-decoration: none;
}

/* Staged: post IDs are long unbroken strings; let them wrap on phones. */
.staged-item__id code {
  overflow-wrap: anywhere;
}

.chip--approved {
  border-color: var(--status-ok, var(--line));
  color: var(--status-ok, var(--ink));
}

/* Users and person pages: built from the board filter, Account's card and grouped rows, and thread rows;
   only page-specific layout lives here. */
/* A search field inside the board toolbar. Users filters the list already on the page, so its field is script-only;
   board search submits a native form and stays visible. */
.board-toolbar__search {
  flex: 1 1 12rem;
  min-width: 0;
  width: auto;
  margin: 0;
  padding: 0.45rem 0.7rem;
}
.board-toolbar > button {
  flex: 0 0 auto;
  width: auto;
  margin: 0;
}
@media (scripting: none) {
  .board-toolbar__search[data-users-search] {
    display: none;
  }
}
.thread-rows > .thread-row[hidden],
.account-group > .account-row[hidden],
.person-head > .starfield.banner:empty {
  display: none;
}
.person-head .account-name {
  margin: 0;
}
.person-head__action {
  margin: 0;
}
.person-head__action button {
  width: auto;
  min-height: 44px;
  margin: 0;
}
.person-page .account-key-fingerprint-value {
  flex: 0 0 auto;
  white-space: nowrap;
}
.person-identity .account-row__title {
  display: flex;
  flex-direction: column;
  min-width: 0;
}
.person-identity {
  align-items: flex-start;
  padding-top: 0.6rem;
  padding-bottom: 0.6rem;
}
.person-identity.account-row--link::after {
  align-self: center;
}
.person-identity__status {
  font-size: 0.85rem;
}
.person-identity__latest {
  display: -webkit-box;
  overflow: hidden;
  margin-top: 0.15rem;
  overflow-wrap: anywhere;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 2;
  line-clamp: 2;
}

.board-empty {
  padding: 2rem 1rem;
  text-align: center;
}

.board-empty h2 {
  margin: 0 0 0.4rem;
}

.board-empty p {
  margin: 0 0 1rem;
  color: var(--ink-soft);
}

/* Gallery: justified rows. Each tile's basis is its (clamped) aspect ratio
   times the row height, so rows fill the width and images keep their shape. */
.gallery-grid {
  --gallery-row: 12rem;
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem;
}

/* Keeps a short last row at row height instead of stretching it. */
.gallery-grid::after {
  content: "";
  flex: 1000 1 0;
}

.gallery-tile {
  display: flex;
  flex: var(--ratio) 1 calc(var(--ratio) * var(--gallery-row));
  flex-direction: column;
  min-width: 0;
  /* A row that wraps early may stretch, but not far past the row height. */
  max-width: calc(var(--ratio) * var(--gallery-row) * 1.6);
  overflow: hidden;
  border: 1px solid var(--line);
  background: var(--panel);
  color: inherit;
  text-decoration: none;
}

.gallery-tile:hover,
.gallery-tile:focus-visible {
  border-color: var(--ink-soft);
}

.gallery-tile img {
  display: block;
  width: 100%;
  height: auto;
  aspect-ratio: var(--ratio);
  object-fit: cover;
  background: var(--line);
}

.gallery-tile__caption {
  display: flex;
  flex-direction: column;
  padding: 0.3rem 0.5rem 0.4rem;
  line-height: 1.3;
}

.gallery-tile__title {
  overflow: hidden;
  font-weight: 600;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.gallery-tile__meta {
  color: var(--ink-soft);
  font-size: 0.85em;
}

@media (max-width: 40rem) {
  .gallery-grid {
    --gallery-row: 7rem;
    gap: 0.35rem;
  }
}

/* First-visit intro on the board: the head script marks a browser with a saved
   identity, or one that hid the intro, before paint. */
:root[data-visitor="known"] [data-visitor-intro] {
  display: none !important;
}

.visitor-intro {
  position: relative;
}

/* On the sentence, not the card: themes set their own card padding. */
.visitor-intro p {
  margin: 0 1.5rem 0 0;
}

/* Keep each link whole so "Agent prompt" never splits across lines. */
.visitor-intro p a {
  white-space: nowrap;
}

/* `:root` outranks themes' general button sizing. The invisible ::after gives
   the small button a 44px touch target without covering the sentence. */
:root .visitor-intro > button {
  position: absolute;
  top: 0.25rem;
  right: 0.25rem;
  width: 1.5rem;
  height: 1.5rem;
  margin: 0;
  padding: 0;
  line-height: 1;
}

.visitor-intro > button::after {
  content: "";
  position: absolute;
  inset: -0.625rem;
}

/* Member-only links (Messages, Invite) are in every viewer's HTML; the head
   script marks a browser remembered as approved before paint. */
:root:not([data-member="approved"]) [data-member-only] {
  display: none !important;
}

/* critical-css-end */

.post-card {
  position: relative;
  padding-bottom: 2.25rem;
  scroll-margin-top: 1rem;
}

.post-card:target {
  border-color: var(--active-line);
}

/* A list row or tile opened with ?with= is the URL's target. */
.thread-row:target,
.gallery-tile:target {
  outline: 2px solid var(--active-line);
  outline-offset: -2px;
  scroll-margin-top: 1rem;
}

.thread-root-card h1 {
  margin-bottom: 1rem;
}

.pending-reply-card {
  border-style: dashed;
}

.pending-thread-shell {
  border-style: dashed;
}

.pending-reply-card .body {
  white-space: pre-wrap;
}

.pending-thread-shell .body {
  white-space: pre-wrap;
}

.pending-reply-status {
  color: var(--ink-soft);
}

.pending-thread-status {
  color: var(--ink-soft);
}

.post-card-permalink {
  position: absolute;
  right: 0.9rem;
  bottom: 0.65rem;
  font-family: var(--ui-font);
  font-size: 0.95rem;
  line-height: 1;
  opacity: 0;
  transition: opacity 0.15s ease;
}

.post-card:focus-within .post-card-permalink {
  opacity: 1;
}

@media (hover: hover) and (pointer: fine) {
  .post-card:hover .post-card-permalink {
    opacity: 1;
  }
}

/* On touch screens a tap puts the whole card in :hover. If that revealed the
   permalink, iOS Safari would treat a tap on Like (or any link in the card) as
   a hover and fire it only on the second tap. So the reveal skips hovers that
   come from a link or button; tapping or scrolling elsewhere still shows it. */
@media (hover: none), (pointer: coarse), (pointer: none) {
  .post-card:hover:not(:has(a:hover, button:hover)) .post-card-permalink {
    opacity: 1;
  }
}

.board-subsection {
  margin-top: 1rem;
  padding-top: 0.9rem;
  border-top: 1px solid color-mix(in srgb, var(--line) 72%, transparent 28%);
}

.board-subsection-links {
  display: flex;
  flex-wrap: wrap;
  gap: 0.75rem;
  margin: 0.5rem 0 0;
}

/* Default only: :where() keeps theme .nav-link rules winning even though theme sheets load first. */
:where(:root:not([data-theme="chicago"])) .nav-link.is-active {
  color: var(--active-ink);
  background: var(--active-bg);
  border-color: var(--active-line);
  box-shadow:
    0 0 0 1px var(--active-ring),
    inset 0 -2px 0 color-mix(in srgb, var(--active-line) 68%, transparent 32%);
  font-weight: 600;
}

.feedback {
  padding: 0.75rem;
  border: 1px solid var(--line);
}

.feedback-ok {
  background: var(--feedback-ok-bg);
}

.feedback-error {
  background: var(--feedback-error-bg);
}

.meta {
  color: var(--ink-soft);
  font-size: 0.95rem;
}

.pinned-thread-marker {
  display: inline-block;
  margin-left: 0.4rem;
  border: 1px solid var(--line);
  padding: 0.12rem 0.35rem;
  vertical-align: middle;
  color: var(--ink-soft);
  background: var(--input-bg);
  font-family: var(--ui-font);
  font-size: 0.68rem;
  font-weight: 650;
  text-transform: uppercase;
}

.body {
  white-space: normal;
}

/* Posts their authors marked as Markdown. Colors come from the theme via currentColor. */
.post-markdown > :first-child { margin-top: 0; }
.post-markdown > :last-child { margin-bottom: 0; }
.post-markdown p { margin: 0 0 0.75em; }
.post-markdown h3, .post-markdown h4, .post-markdown h5, .post-markdown h6 {
  margin: 1em 0 0.4em;
  line-height: 1.25;
}
.post-markdown h3 { font-size: 1.15em; }
.post-markdown h4 { font-size: 1.05em; }
.post-markdown h5, .post-markdown h6 { font-size: 1em; }
.post-markdown ul, .post-markdown ol { margin: 0 0 0.75em; padding-left: 1.5em; }
.post-markdown li > p { margin: 0 0 0.25em; }
.post-markdown blockquote {
  margin: 0 0 0.75em;
  padding-left: 0.75em;
  border-left: 3px solid currentColor;
  opacity: 0.85;
}
.post-markdown blockquote p { margin: 0; }
.post-markdown code {
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  font-size: 0.92em;
}
.post-markdown pre {
  margin: 0 0 0.75em;
  padding: 0.5em 0.75em;
  overflow-x: auto;
  background: rgba(127, 127, 127, 0.12);
  white-space: pre;
}
.post-markdown figure { margin: 0 0 0.75em; }
.post-markdown figcaption { font-size: 0.85em; opacity: 0.8; }
.post-markdown hr { border: 0; border-top: 1px solid currentColor; opacity: 0.4; margin: 1em 0; }
.post-markdown .docs-table-scroll, .post-markdown .docs-list-scroll { overflow-x: auto; margin: 0 0 0.75em; -webkit-overflow-scrolling: touch; }
.post-markdown table { border-collapse: collapse; }
.post-markdown th, .post-markdown td { border: 1px solid rgba(127, 127, 127, 0.5); padding: 0.25em 0.5em; text-align: left; }
/* .card breaks text anywhere, which lets auto-layout table columns shrink to one letter.
   Cells wrap only between words, without hyphenation: hyphens let a column shrink to one
   syllable ("re-ports"), so a column of short labels lost its width to the longest column. */
.post-markdown th, .post-markdown td { overflow-wrap: break-word; word-break: normal; hyphens: manual; vertical-align: top; }
.post-markdown .zoom-table { margin: 0 0 0.75em; }
/* Smaller/Larger text-size buttons (ZoomButtons.php): Query viewer, zoom tables. Each place
   sets the group's display (both are phone-only), because site.css loads asynchronously and
   can arrive after page stylesheets such as sqlite.css. The [type] keeps these metrics ahead of header button rules
   whatever the load order. The Forte toolbar keeps its own toolbar button look. */
/* Quick repeated taps on Smaller/Larger must not trigger the browser's double-tap zoom.
   On every zoom button, including the Forte toolbar's, which isn't in a .zoom-buttons group. */
.zoom-button { touch-action: manipulation; }
.zoom-buttons { flex: 0 0 auto; gap: 0.25rem; }
.zoom-buttons button[type="button"] {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex: 0 0 auto;
  width: auto;
  min-width: 2.25rem;
  margin: 0;
  padding: 0.25rem 0.4rem;
}
/* Tables with their own text-size controls on phones (ZoomTable.php, table_zoom.js): post
   tables, Tools tables such as Visitor statistics, and the calendar (text mode, below).
   Fit mode: a table opens fitted to the screen and
   fills its width; the browser sizes the columns from their content. --table-min (set per
   table by ZoomTable) is the table's estimated narrowest width in em: each column's longest
   word plus cell padding. The fitted text size is the largest at which that fits, never above
   the page's own size, so a short two-column table keeps full-size text and only a really
   wide table gets small. Past the fitted size the table scrolls sideways. --table-zoom
   multiplies the fitted size; each kind of table has its own (--table-zoom-post,
   --table-zoom-tools), which table_zoom.js sets from the buttons and from pinching on the
   table and layout.php restores before paint. Actual size (data-table-size-<kind>="page" on
   <html>) puts that kind at the page's own text size. Pinching outside tables still zooms
   the page. Links and code in tables (URLs, paths) may break anywhere, so one long token
   doesn't make the whole table scroll; ZoomTable counts any word as at most 20 characters. */
.zoom-table-scroll { overflow-x: auto; -webkit-overflow-scrolling: touch; }
/* Cards break text anywhere, which lets table columns shrink to a letter wide; zoom table
   cells wrap only between words (and at hyphens), so a column is never narrower than one. */
.zoom-table :is(th, td) { overflow-wrap: break-word; word-break: normal; hyphens: manual; }
.zoom-table-buttons { display: none; }
.zoom-table--post { --table-zoom: var(--table-zoom-post, 1); }
.zoom-table--tools { --table-zoom: var(--table-zoom-tools, 1); }
.zoom-table--calendar { --table-zoom: var(--table-zoom-calendar, 1); }
@media (max-width: 639px) {
  .zoom-table-buttons { display: flex; justify-content: flex-end; margin-bottom: 0.25rem; }
  .zoom-table-scroll { container-type: inline-size; touch-action: pan-x pan-y; }
  .zoom-table table {
    -webkit-text-size-adjust: 100%;
    text-size-adjust: 100%;
    width: 100%;
  }
  .zoom-table--fit table {
    font-size: calc(1em * var(--table-zoom, 1));
    font-size: calc(min(1em, 100cqw / var(--table-min, 60)) * var(--table-zoom, 1));
  }
  .zoom-table--fit :is(td, th) :is(a, code) { overflow-wrap: anywhere; }
  :root[data-table-size-post="page"] .zoom-table--post table,
  :root[data-table-size-tools="page"] .zoom-table--tools table { font-size: 1em; }
  /* Text mode (the calendar): full width always. The table's own CSS decides which text
     scales with --table-zoom; Actual size sets --table-zoom to the table's
     --table-page-scale, a plain number, which table_zoom.js reads back. */
  .zoom-table--text .zoom-table-scroll { overflow-x: hidden; }
  :root[data-table-size-calendar="page"] .zoom-table--calendar table { --table-zoom: var(--table-page-scale, 1); }
}
.post-markdown .docs-align-center { text-align: center; }
.post-markdown .docs-align-right { text-align: right; }
.post-markdown .docs-task-item { list-style: none; margin-left: -1.25em; }
.post-markdown .docs-task-label { display: inline; font: inherit; color: inherit; }
.post-markdown .docs-task-label input {
  display: inline-block;
  width: auto;
  min-width: 0;
  min-height: 0;
  margin: 0 0.4em 0 0;
  vertical-align: middle;
}
.post-markdown .docs-list-source, .post-markdown .docs-table-source { white-space: pre-wrap; }

.button-row {
  display: flex;
  flex-wrap: wrap;
  gap: 0.75rem;
}

.button-row > * {
  flex: 1 1 12rem;
}

.button-row.button-row-natural > * {
  flex: 0 0 auto;
  width: auto;
}

.button-row.button-row-split {
  justify-content: space-between;
}

.button-row.button-row-split > *:last-child {
  margin-left: auto;
}

.quote-card-header-actions {
  display: inline-flex;
  flex-wrap: wrap;
  gap: 0.35rem;
  max-width: 100%;
  vertical-align: middle;
}

.quote-card-header-actions .thread-reaction-button {
  width: auto;
  margin-top: 0;
}

.quote-card-header-actions .thread-reaction-button.quote-card-vote-button[data-action] {
  padding: 0 0.25rem;
  line-height: inherit;
}

.quote-card-header-actions .quote-card-reaction-feedback {
  align-self: center;
  margin: 0;
  line-height: inherit;
}

.quote-card-reaction-feedback[data-kind="ok"] {
  color: var(--status-ok);
}

.quote-card-reaction-feedback[data-kind="error"] {
  color: var(--status-error);
}

.possibly-related {
  padding: 0.75rem;
}

.possibly-related-title {
  font-weight: 700;
  margin: 0 0 0.35rem;
}

.possibly-related ul {
  margin: 0;
  padding-left: 1.2rem;
}

.possibly-related li + li {
  margin-top: 0.35rem;
}

.key-material-gap {
  margin-top: 1rem;
}

[data-role="public-key-viewer"],
[data-role="private-key-viewer"] {
  margin-top: 0.45rem;
  padding: 0.75rem 0.8rem;
  border: 1px solid var(--line);
  background: var(--input-bg);
  overflow: auto;
  max-height: 140px;
  font-size: 0.75rem;
  line-height: 1.45;
}

[data-role="browser-key-status"][data-kind="error"],
[data-role="compose-identity-status"][data-kind="error"] {
  color: var(--status-error);
}

/* Retry beside a failed account creation, inline with its message. */
.compose-identity-retry,
.reaction-retry {
  display: inline-block;
  width: auto;
  min-height: 2.75rem;
  margin: 0 0 0 0.35rem;
  padding: 0 0.9rem;
}

[data-role="browser-key-status"][data-kind="ok"] {
  color: var(--status-ok);
}

.agent-authored-post {
  border-color: color-mix(in srgb, var(--status-ok) 45%, var(--line) 55%);
}

.agent-label {
  display: inline;
  color: var(--ink);
  font-family: var(--ui-font);
  font-size: 0.78rem;
  font-weight: 650;
  text-transform: uppercase;
}

@media (min-width: 640px) {
  .shell {
    padding: 1.5rem;
  }

  .card {
    padding: 1rem 1.1rem;
  }

}

/* `:root` outranks themes' general button styling so the invite's one action reads as a button. */
:root [data-action="redeem-invitation"] {
  display: inline-block;
  width: auto;
  margin-top: 0.85rem;
  padding: 0.7rem 1.4rem;
  border: 1px solid var(--ink);
  border-radius: 4px;
  background: var(--ink);
  color: var(--page-bg);
  font-weight: 700;
  box-shadow: 0 2px 0 var(--active-line);
}

:root [data-action="redeem-invitation"]:hover {
  background: var(--active-ink);
}

:root [data-action="redeem-invitation"]:active {
  transform: translateY(1px);
  box-shadow: 0 1px 0 var(--active-line);
}

:root [data-action="redeem-invitation"]:focus-visible {
  outline: 3px solid var(--active-ring);
  outline-offset: 2px;
}

:root [data-action="redeem-invitation"]:disabled {
  cursor: progress;
  opacity: 0.7;
}

[data-action="copy-invitation-link"] {
  flex: 0 0 auto;
  width: auto;
  align-self: flex-start;
}

.media-embed-card__iframe {
  display: block;
  width: 100%;
  aspect-ratio: 16 / 9;
  height: auto;
  border: 0;
}

.media-embed-card--inline-player {
  display: block;
  max-width: 100%;
}

.media-embed-card--inline-player > summary {
  cursor: pointer;
}

.media-embed-card--inline-player[open] > .media-embed-card__iframe {
  margin-top: 0.5rem;
}

.media-embed-card__source {
  display: block;
  overflow-wrap: anywhere;
}

.media-embed-card--portrait > .media-embed-card__iframe {
  max-width: 360px;
  aspect-ratio: 9 / 16;
}

.media-embed-card--spotify > .media-embed-card__iframe {
  height: 352px;
  aspect-ratio: auto;
}

.media-embed-card--preview {
  display: block;
  max-width: 100%;
  overflow-wrap: anywhere;
}

.media-embed-card__thumbnail {
  display: block;
  max-width: 100%;
  height: auto;
}

.media-embed-card--soundcloud > .media-embed-card__iframe { height: 166px; aspect-ratio: auto; }

.media-embed-card--soundcloud.media-embed-card--collection > .media-embed-card__iframe { height: 450px; }

.media-embed-card--bandcamp > .media-embed-card__iframe { height: 472px; aspect-ratio: auto; }
.media-embed-card__iframe[hidden] { display: none; }

.media-embed-card--bandcamp.media-embed-card--track > .media-embed-card__iframe { height: 120px; }
.account-key-history {
  overflow-wrap: anywhere;
}
.scripture-expansion { margin-block: 0.8rem; padding-block: 0.5rem; border-block-start: 1px solid var(--line); }
.scripture-expansion summary { cursor: pointer; font-family: var(--ui-font); }
.scripture-expansion summary:focus-visible { outline: 2px solid currentColor; outline-offset: 3px; }
.scripture-expansion .body { margin-block-start: 0.6rem; overflow-wrap: anywhere; }
.agent-reply-feedback { min-width: 0; max-width: 100%; overflow-wrap: anywhere; }

/* Busy and site-update pages (FrontController::renderWaitPage): one calm
   message near the optical center, with a slow bar so the page looks alive
   while it reloads itself. */
.wait-page .shell {
  display: flex;
  flex-direction: column;
  min-height: 100vh;
  min-height: 100svh;
}

.wait-page .main {
  display: flex;
  flex: 1;
  align-items: center;
  padding-bottom: 12vh;
}

.wait-page .stack {
  width: 100%;
  max-width: 32rem;
}

.wait-page h1 {
  margin: 0;
  font-size: clamp(2rem, 7vw, 2.75rem);
  line-height: 1.1;
}

.wait-page .stack > p {
  color: var(--ink-soft);
  font-size: 1.1rem;
  line-height: 1.5;
}

.wait-page__progress {
  position: relative;
  height: 3px;
  overflow: hidden;
  border-radius: 3px;
  background: var(--line);
}

.wait-page__progress::after {
  content: "";
  position: absolute;
  inset: 0 auto 0 0;
  width: 35%;
  border-radius: inherit;
  background: var(--active-line);
  animation: wait-page-progress 1.8s ease-in-out infinite;
}

@keyframes wait-page-progress {
  from { transform: translateX(-100%); }
  to { transform: translateX(290%); }
}

@media (prefers-reduced-motion: reduce) {
  .wait-page__progress::after {
    animation: wait-page-pulse 2.4s ease-in-out infinite alternate;
    width: 100%;
    opacity: 0.35;
  }

  @keyframes wait-page-pulse {
    to { opacity: 0.8; }
  }
}

/* Replies still on this device (Outbox), listed above a thread's reply composer; dashed so they never read as published. */
.outbox-unsent {
  display: grid;
  gap: 0.5rem;
  margin-block: 0.75rem;
}

.outbox-unsent__item {
  border-style: dashed;
}

/* Post records list (post page) and record page */
.post-records-table { width: 100%; border-collapse: collapse; font-size: 0.9em; }
.post-records-table th, .post-records-table td { text-align: left; padding: 0.25rem 0.5rem 0.25rem 0; vertical-align: top; overflow-wrap: anywhere; }
.post-record-retracted td { color: var(--muted); }
.record-fields { display: grid; grid-template-columns: max-content 1fr; gap: 0.15rem 1rem; margin: 0.5rem 0; }
.record-fields dt { font-weight: 600; }
.record-fields dd { margin: 0; overflow-wrap: anywhere; }
.record-body { white-space: pre-wrap; overflow-wrap: anywhere; }

/* Short phone screens (an iPhone SE with Safari's bars): slimmer More links,
   so the panel still fits without scrolling. */
@media (max-width: 639px) and (max-height: 520px) {
  [data-shell="app"] .account-menu__panel {
    padding-top: 0.6rem;
    padding-bottom: 0.8rem;
  }

  [data-shell="app"] .account-menu__more .nav-link,
  [data-shell="app"] .account-menu__links .nav-link {
    padding-top: 0.5rem;
    padding-bottom: 0.5rem;
  }
}

/* The pending author summary (pending_user_summary.js). */
.pending-user-dialog {
  /* Placed beside the clicked chip by pending_user_summary.js. */
  position: fixed;
  inset: auto;
  top: 0;
  left: 0;
  margin: 0;
  width: min(22rem, calc(100vw - 1rem));
  max-height: calc(100vh - 1rem);
  overflow: auto;
  color: var(--ink);
}

.pending-user-dialog::backdrop {
  background: rgb(0 0 0 / 0.15);
}

.pending-user-dialog__head {
  display: flex;
  align-items: center;
  gap: 0.5rem;
}

.pending-user-dialog__head .chip {
  flex: none;
  overflow-wrap: normal;
}

.pending-user-dialog__head h2 {
  margin: 0;
  overflow-wrap: anywhere;
}

.pending-user-dialog__head .pending-user-dialog__close {
  flex: none;
  width: 2.75rem;
  min-width: 0;
  height: 2.75rem;
  min-height: 0;
  margin: -0.5rem -0.5rem 0 auto;
  padding: 0;
  font-size: 1.4rem;
  line-height: 1;
}

.pending-user-dialog__key {
  overflow-wrap: anywhere;
}

.pending-user-dialog__recent {
  margin: 0 0 1rem;
  padding: 0;
  list-style: none;
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: 0.4rem;
}

.pending-user-dialog__recent li {
  display: flex;
  align-items: baseline;
  gap: 0.5rem;
}

.pending-user-dialog__recent a {
  flex: 1 1 auto;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.pending-user-dialog__recent .meta {
  flex: none;
}

.pending-user-dialog__actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.75rem;
}

.pending-user-dialog__actions button {
  width: auto;
  min-height: 44px;
  margin: 0;
}

.pending-user-dialog__actions [data-role="approve"] {
  background: var(--button-bg);
}
