/* Dizcourze — greyscale, line icons only: black/white, 1px borders, 0.5rem radius.
   The front color (black, or white in dark mode) marks what is active or sendable;
   grey marks what is not sendable yet. Motion throughout. */

:root {
  --front: #000;
  --back: #fff;
  --border: #ddd;
  --err: #9e9e9e;   /* not sendable / invalid */
  --out: var(--front);
  --muted: #6b6b6b;
  --soft: #f5f5f5;
  --overlay: rgba(0, 0, 0, .5);
  --shadow: rgba(0, 0, 0, .14);
  --radius: .5rem;
  --line: .0625rem;
  --col: 33.75rem;
  --spring: cubic-bezier(.34, 1.56, .64, 1);
  --out-ease: cubic-bezier(.2, .8, .2, 1);
  --dir: 1;
  color-scheme: light;
}
:root[dir="rtl"] { --dir: -1; }
:root[data-theme="dark"] {
  --front: #fff; --back: #000; --border: #aaa; --err: #5e5e5e; --muted: #9a9a9a; --soft: #111;
  --overlay: rgba(0, 0, 0, .7); --shadow: rgba(0, 0, 0, .6); color-scheme: dark;
}
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    --front: #fff; --back: #000; --border: #aaa; --err: #5e5e5e; --muted: #9a9a9a; --soft: #111;
    --overlay: rgba(0, 0, 0, .7); --shadow: rgba(0, 0, 0, .6); color-scheme: dark;
  }
}

/* ---------------------------------------------------------------- base */
*, *::before, *::after { box-sizing: border-box; }
* { -ms-overflow-style: none; scrollbar-width: none; -webkit-user-select: none; user-select: none; }
*::-webkit-scrollbar { display: none; }
html {
  font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Ubuntu, "Helvetica Neue", Helvetica, sans-serif;
  font-size: 1rem;
  line-height: 1.5;
  overscroll-behavior: none;
  -webkit-text-size-adjust: 100%;
  -webkit-tap-highlight-color: transparent;
}
body {
  margin: 0;
  min-height: 100dvh;
  overscroll-behavior: none;
  background: var(--back);
  color: var(--front);
  transition: background-color .3s, color .3s;
}
/* a sheet or the lightbox is open: the page is pinned where it was (ui.js lockPage), so nothing can scroll it */
body.locked { position: fixed; inset-inline: 0; top: var(--lock-y, 0px); overflow: hidden; }
a { color: inherit; }
button { font: inherit; color: inherit; }
[hidden] { display: none !important; }
.sr-only { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }
:focus-visible { outline: .125rem solid var(--front); outline-offset: .125rem; }
input, textarea {
  font: inherit;
  line-height: 1.5;
  color: var(--front);
  caret-color: var(--front);
  background: var(--back);
  border: var(--line) solid var(--border);
  border-radius: var(--radius);
  padding: .5rem .75rem;
  -webkit-user-select: text;
  user-select: text;
  transition: border-color .25s, box-shadow .25s, background-color .3s;
}
input:focus-visible, textarea:focus-visible { outline: 0; border-color: var(--front); }
input.is-err, textarea.is-err { border-color: var(--err); }
input[type="search"]::-webkit-search-cancel-button { -webkit-appearance: none; }
::placeholder { color: var(--muted); opacity: 1; }

/* ---------------------------------------------------------------- icons (stroke only) */
.icon {
  width: 1rem; height: 1rem; flex: none;
  fill: none; stroke: currentColor; stroke-width: 2; stroke-linecap: round; stroke-linejoin: round;
  transition: transform .25s var(--spring), color .25s;
}
.swap-in { animation: swap-in .34s var(--spring); }
:root[dir="rtl"] .flip-rtl { transform: scaleX(-1); }
@keyframes swap-in { from { opacity: 0; transform: scale(.3) rotate(-35deg); } }
.check path { stroke-dasharray: 1; stroke-dashoffset: 1; animation: draw .45s .05s var(--out-ease) forwards; }
@keyframes draw { to { stroke-dashoffset: 0; } }
.spinner {
  display: inline-block; flex: none;
  width: .75rem; height: .75rem;
  border: .125rem solid var(--border);
  border-left-color: var(--front);
  border-radius: 50%;
  animation: spin .9s linear infinite;
}
@keyframes spin { to { transform: rotate(360deg); } }

/* ---------------------------------------------------------------- buttons (s / m / l like v1) */
.s-btn, .m-btn, .l-btn {
  position: relative;
  overflow: hidden;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: .375rem;
  color: var(--front);
  background: var(--back);
  border: var(--line) solid var(--border);
  border-radius: var(--radius);
  cursor: pointer;
  text-decoration: none;
  touch-action: manipulation;
  transition: transform .24s var(--spring), border-color .25s, background-color .25s, color .25s, opacity .2s;
}
.s-btn { width: 2.625rem; height: 2.625rem; flex: none; padding: 0; }
.m-btn { flex: 1 1 0; min-width: 0; height: 2.625rem; padding: 0 .5rem; font-variant-numeric: tabular-nums; }
.l-btn { width: 100%; min-height: 2.625rem; padding: .5rem .75rem; justify-content: flex-start; text-align: start; }
.l-btn .end { margin-inline-start: auto; color: var(--muted); display: inline-flex; align-items: center; gap: .375rem; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.l-btn.selected { border-color: var(--front); font-weight: 600; }
.l-btn.selected .end { color: var(--front); }
.l-btn.two { align-items: center; }
.l-btn .lines { display: grid; min-width: 0; }
.l-btn .lines small, .l-btn .sub { color: var(--muted); font-size: .8125rem; }
.l-btn .sub { margin-inline-start: .25rem; }
.l-btn .code {
  flex: none; display: inline-grid; place-items: center; min-width: 2rem; height: 1.375rem; padding: 0 .25rem;
  border: var(--line) solid var(--border); border-radius: .25rem; font-size: .75rem; font-weight: 600;
  letter-spacing: .02em; font-variant-numeric: tabular-nums;
}
.l-btn .code .icon { width: .875rem; height: .875rem; }
/* grey = not sendable yet (empty search, empty post, over the limit) */
.s-btn.is-err, .m-btn.is-err, .l-btn.is-err { border-color: var(--err); color: var(--err); }
.s-btn.is-ok { border-color: var(--front); background: var(--front); color: var(--back); }
.s-btn[disabled], .m-btn[disabled], .l-btn[disabled] { cursor: default; opacity: .55; }
@media (hover: hover) {
  .s-btn:not([disabled]):hover { transform: scale(1.1); }
  .m-btn:not([disabled]):hover { transform: scale(1.05); }
  .l-btn:not([disabled]):hover { transform: scale(1.025); }
  .s-btn:not([disabled]):hover, .m-btn:not([disabled]):hover, .l-btn:not([disabled]):hover { background: var(--soft); }
  .s-btn:not(.is-err):not([disabled]):hover, .m-btn:not([disabled]):hover { border-color: var(--front); }
}
.s-btn:not([disabled]):active { transform: scale(.9); }
.m-btn:not([disabled]):active { transform: scale(.95); }
.l-btn:not([disabled]):active { transform: scale(.975); }
.ripple {
  position: absolute; border-radius: 50%; pointer-events: none;
  background: currentColor; opacity: .16; transform: scale(0);
  animation: ripple .6s var(--out-ease) forwards;
}
@keyframes ripple { to { transform: scale(1); opacity: 0; } }
.shake { animation: shake .42s; }
@keyframes shake { 20%, 60% { translate: -.25rem 0; } 40%, 80% { translate: .25rem 0; } }
.pop { animation: pop .45s var(--spring); }
@keyframes pop { 40% { transform: scale(1.18); } }

/* toggle switch (outlined) */
.switch {
  position: relative; flex: none; width: 2.5rem; height: 1.5rem; border-radius: 1rem;
  border: var(--line) solid var(--border); background: var(--back); transition: background-color .25s, border-color .25s;
}
.switch::after {
  content: ""; position: absolute; top: .1875rem; inset-inline-start: .1875rem; width: 1rem; height: 1rem;
  border-radius: 50%; border: var(--line) solid var(--muted); background: var(--back);
  transition: transform .3s var(--spring), background-color .25s, border-color .25s;
}
.switch.on { border-color: var(--front); background: var(--front); }
.switch.on::after { background: var(--back); border-color: var(--back); transform: translateX(calc(1rem * var(--dir))); }

/* ---------------------------------------------------------------- splash: the line logo draws itself, then
   shrinks and moves into the top-left button (app.js). Stroke only, never filled. */
#splash {
  position: fixed; inset: 0; z-index: 100;
  display: grid; place-items: center;
  background: var(--back);
  transition: opacity .5s var(--out-ease), visibility 0s .5s;
}
.logo-line { fill: none; stroke: var(--front); stroke-width: 1.6; stroke-linecap: round; stroke-linejoin: round; }
#splash svg { width: 4.5rem; height: 4.5rem; overflow: visible; }
#splash path { stroke-dasharray: 1; stroke-dashoffset: 1; animation: draw 1s .1s var(--out-ease) forwards; }
.quick #splash path { animation-duration: .35s; animation-delay: 0s; }
.booted #splash { opacity: 0; visibility: hidden; pointer-events: none; }
body:not(.booted) #top { opacity: 0; transform: translateY(-.75rem); }
#top { transition: opacity .45s .1s var(--out-ease), transform .55s .1s var(--spring), background-color .3s; }
body:not(.booted) .enter { animation-play-state: paused; }

/* ---------------------------------------------------------------- layout: one column, centered */
#shell {
  display: grid;
  grid-template-columns: minmax(0, var(--col));
  justify-content: center;
  align-items: start;
}
#col { min-width: 0; min-height: 100dvh; display: flex; flex-direction: column; }
@media (min-width: 34rem) { #col { border-inline: var(--line) solid var(--border); } }
#top {
  position: sticky; top: 0; z-index: 30;
  display: flex; align-items: center; gap: .5rem;
  padding: .5rem;
  padding-top: max(.5rem, env(safe-area-inset-top));
  background: var(--back);
  border-bottom: var(--line) solid var(--border);
}
@supports (backdrop-filter: blur(1px)) {
  #top { background: color-mix(in srgb, var(--back) 86%, transparent); backdrop-filter: saturate(1.5) blur(12px); }
}
#search-form { flex: 1; display: flex; gap: .5rem; min-width: 0; }
#search { flex: 1; min-width: 0; height: 2.625rem; }
#home-btn { overflow: visible; }
/* connection dot: outlined ring when not live, solid with a ring pulse when live */
#home-btn .live-dot {
  position: absolute; top: .3125rem; inset-inline-end: .3125rem;
  width: .4375rem; height: .4375rem; border-radius: 50%;
  border: var(--line) solid var(--muted); background: var(--back);
  box-shadow: 0 0 0 .125rem var(--back); transition: background-color .3s, border-color .3s;
}
#home-btn .live-dot.on { background: var(--front); border-color: var(--front); }
#home-btn .live-dot.on::after {
  content: ""; position: absolute; inset: -.0625rem; border-radius: 50%; border: var(--line) solid var(--front);
  animation: ping 2.2s var(--out-ease) infinite;
}
#home-btn .live-dot.off { border-color: var(--err); border-style: dashed; }
@keyframes ping { 70%, 100% { transform: scale(2.6); opacity: 0; } }
#views { flex: 1; position: relative; }
.view { padding-bottom: env(safe-area-inset-bottom); }
.has-dock .view { padding-bottom: 0; }
.view.enter-fwd { animation: view-in .32s var(--out-ease) both; }
.view.enter-back { animation: view-in-back .32s var(--out-ease) both; }
@keyframes view-in { from { opacity: 0; transform: translateX(calc(1.25rem * var(--dir))); } }
@keyframes view-in-back { from { opacity: 0; transform: translateX(calc(-1.25rem * var(--dir))); } }

/* View Transitions API (Chromium / Safari 18+) */
@supports (view-transition-name: none) {
  #top { view-transition-name: top; }
  #dock { view-transition-name: dock; }
  html.vt-nav::view-transition-old(root) { animation: vt-out .2s var(--out-ease) both; }
  html.vt-nav::view-transition-new(root) { animation: vt-in .32s var(--out-ease) both; }
  html.vt-nav.nav-back::view-transition-old(root) { animation-name: vt-out-back; }
  html.vt-nav.nav-back::view-transition-new(root) { animation-name: vt-in-back; }
  html.vt-theme::view-transition-old(root), html.vt-theme::view-transition-new(root) { animation: none; mix-blend-mode: normal; }
  html.vt-theme::view-transition-group(*) { animation-duration: 0s; }
}
@keyframes vt-out { to { opacity: 0; transform: translateX(calc(-1.5rem * var(--dir))); } }
@keyframes vt-in { from { opacity: 0; transform: translateX(calc(1.5rem * var(--dir))); } }
@keyframes vt-out-back { to { opacity: 0; transform: translateX(calc(1.5rem * var(--dir))); } }
@keyframes vt-in-back { from { opacity: 0; transform: translateX(calc(-1.5rem * var(--dir))); } }

/* ---------------------------------------------------------------- announcement + new posts pill */
#announce {
  display: flex; align-items: center; gap: .5rem;
  padding: .5rem .75rem; border-bottom: var(--line) solid var(--border);
  font-weight: 600; animation: drop-in .45s var(--spring);
}
#announce span { flex: 1; overflow-wrap: anywhere; }
#announce .s-btn { width: 2rem; height: 2rem; }
@keyframes drop-in { from { opacity: 0; transform: translateY(-.5rem); } }
#new-pill {
  position: fixed; z-index: 35; inset-inline-start: 50%;
  top: calc(max(.5rem, env(safe-area-inset-top)) + 3.25rem);
  translate: calc(-50% * var(--dir)) 0;
  display: inline-flex; align-items: center; gap: .375rem;
  padding: .375rem .875rem; border-radius: 2rem;
  border: var(--line) solid var(--front); background: var(--front); color: var(--back);
  font-weight: 600; cursor: pointer; box-shadow: 0 .5rem 1.5rem var(--shadow);
  transform: translateY(-1.5rem) scale(.9); opacity: 0; pointer-events: none;
  transition: transform .45s var(--spring), opacity .25s;
}
#new-pill.show { transform: none; opacity: 1; pointer-events: auto; }
body.net-on #new-pill { top: calc(max(.5rem, env(safe-area-inset-top)) + 5.75rem); }

/* connection status: offline / reconnecting / back online */
#net {
  position: fixed; z-index: 36; inset-inline-start: 50%;
  top: calc(max(.5rem, env(safe-area-inset-top)) + 3.25rem);
  translate: calc(-50% * var(--dir)) 0;
  display: inline-flex; align-items: center; gap: .5rem; max-width: calc(100vw - 2rem);
  padding: .375rem .875rem; border-radius: 2rem;
  border: var(--line) solid var(--border); background: var(--back); color: var(--muted);
  font-size: .875rem; white-space: nowrap; box-shadow: 0 .5rem 1.5rem var(--shadow);
  transform: translateY(-1.5rem) scale(.9); opacity: 0; pointer-events: none;
  transition: transform .45s var(--spring), opacity .25s, color .25s, border-color .25s;
}
#net.show { transform: none; opacity: 1; }
#net.offline { border-style: dashed; }
#net.back { color: var(--front); border-color: var(--front); }
#net span { overflow: hidden; text-overflow: ellipsis; }
@media (hover: hover) { #new-pill.show:hover { transform: scale(1.05); } }

/* ---------------------------------------------------------------- posts (same card everywhere) */
.post {
  display: block;
  padding: .625rem .75rem .5rem;
  border-bottom: var(--line) solid var(--border);
  cursor: pointer;
  transition: background-color .25s;
}
@media (hover: hover) { .post:hover { background: var(--soft); } }
.post.main { cursor: default; }
@media (hover: hover) { .post.main:hover { background: none; } }
.post.enter { animation: post-in .5s var(--out-ease) both; animation-delay: calc(var(--i, 0) * 45ms); }
@keyframes post-in { from { opacity: 0; transform: translateY(.625rem); } }
.fresh-wrap { display: grid; grid-template-rows: 0fr; transition: grid-template-rows .5s var(--out-ease); }
.fresh-wrap.open { grid-template-rows: 1fr; }
.fresh-wrap > .post { overflow: hidden; min-height: 0; }
.post.fresh { animation: flash 2.4s ease-out; }
@keyframes flash { from { background: color-mix(in srgb, var(--front) 8%, transparent); } }
.post.gone { animation: gone .45s var(--out-ease) forwards; overflow: hidden; }
@keyframes gone { to { opacity: 0; transform: scale(.97); max-height: 0; padding-block: 0; border-width: 0; } }
.info { display: flex; align-items: center; gap: .5rem; height: 2.625rem; min-width: 0; }
.ava {
  width: 2.625rem; height: 2.625rem; flex: none; border-radius: 50%;
  display: grid; place-items: center;
  border: var(--line) solid var(--border); color: var(--front); background: var(--back);
  transition: transform .3s var(--spring), border-color .25s;
}
.ava.brand { border-color: var(--front); }
.ava .icon { width: 1.125rem; height: 1.125rem; }
@media (hover: hover) { .post:hover .ava { transform: rotate(-8deg) scale(1.05); border-color: var(--front); } }
.who { display: flex; align-items: baseline; gap: .375rem; min-width: 0; flex: 1; white-space: nowrap; }
.name { font-weight: 600; overflow: hidden; text-overflow: ellipsis; }
.meta { color: var(--muted); overflow: hidden; text-overflow: ellipsis; font-size: .9375rem; }
.meta .loc { font-size: .75rem; font-weight: 600; letter-spacing: .03em; }
.text {
  padding: .375rem 0 .5rem;
  white-space: pre-wrap; overflow-wrap: anywhere;
  -webkit-user-select: text; user-select: text;
}
.text a { color: var(--front); text-decoration: underline; text-decoration-color: var(--border); text-underline-offset: .2em; transition: text-decoration-color .2s; }
.text a:hover { text-decoration-color: currentColor; }
/* long posts: about ten lines, fading out, until "Show more" (or a tap on the text) opens them up */
.text.clamp { max-height: calc(15em + .875rem); overflow: hidden; }
.text.clamped {
  -webkit-mask-image: linear-gradient(#000 calc(100% - 4.5em), transparent calc(100% - .5rem));
  mask-image: linear-gradient(#000 calc(100% - 4.5em), transparent calc(100% - .5rem));
}
.show-more {
  display: inline-flex; align-items: center; gap: .25rem; margin: -.375rem 0 .5rem; padding: .125rem 0;
  border: 0; background: none; color: var(--front); font: inherit; font-size: .9375rem; font-weight: 600; cursor: pointer;
  animation: fade-up .3s var(--out-ease);
}
.show-more .icon { width: 1rem; height: 1rem; transition: transform .25s var(--spring); }
@media (hover: hover) { .show-more:hover .icon { transform: translateY(.1875rem); } }
.show-more:active .icon { transform: translateY(.1875rem) scale(.9); }
@keyframes fade-up { from { opacity: 0; transform: translateY(.25rem); } }
.actions { display: flex; gap: .5rem; }
/* act: an outlined zap; once acted the button inverts (it counts for 24 hours) */
.m-btn.act.on { background: var(--front); border-color: var(--front); color: var(--back); }
@media (hover: hover) { .m-btn.act.on:hover { background: var(--front); } }
.m-btn.act.burst .icon { animation: zap .5s var(--spring); }
@keyframes zap { 0% { transform: scale(.6) rotate(-12deg); } 50% { transform: scale(1.35) rotate(8deg); } }
.m-btn.act.burst::after {
  content: ""; position: absolute; inset: .3rem; border-radius: var(--radius);
  border: var(--line) solid var(--back); animation: ring-out .55s var(--out-ease) forwards; pointer-events: none;
}
@keyframes ring-out { from { opacity: 1; transform: scale(.6); } to { opacity: 0; transform: scale(1.15); } }
.count { display: inline-grid; overflow: hidden; height: 1.5em; }
.count > span { grid-area: 1 / 1; transition: transform .38s var(--spring), opacity .3s; }
.count > span.old { transform: translateY(-110%); opacity: 0; }
.count > span.new { animation: roll-in .38s var(--spring); }
@keyframes roll-in { from { transform: translateY(110%); opacity: 0; } }
.removed-note { padding: 1rem .75rem; color: var(--muted); text-align: center; }

/* media (user images keep their colors) */
.media {
  position: relative; overflow: hidden;
  margin: 0 0 .5rem;
  border-radius: var(--radius);
  border: var(--line) solid var(--border);
  background: var(--soft);
  aspect-ratio: var(--ar, 4 / 3);
  max-height: 32rem;
  width: 100%;
  cursor: zoom-in;
}
.media .lqip {
  position: absolute; inset: -8%;
  background-size: cover; background-position: center;
  filter: blur(14px); transform: scale(1.06);
  transition: opacity .6s;
}
.media img {
  position: relative; display: block; width: 100%; height: 100%;
  object-fit: cover; opacity: 0; transform: scale(1.03);
  transition: opacity .5s var(--out-ease), transform .7s var(--out-ease);
  -webkit-user-drag: none;
}
.media.loaded img { opacity: 1; transform: none; }
.media.loaded .lqip { opacity: 0; }
.media .tap {
  position: absolute; inset-inline-start: 50%; top: 50%; translate: calc(-50% * var(--dir)) -50%;
  display: inline-flex; align-items: center; gap: .375rem;
  padding: .375rem .75rem; border-radius: 2rem;
  background: rgba(0, 0, 0, .55); color: #fff; font-size: .875rem; border: var(--line) solid rgba(255, 255, 255, .4); cursor: pointer;
  backdrop-filter: blur(6px);
}

/* skeletons */
.skel { padding: .75rem; border-bottom: var(--line) solid var(--border); }
.skel .row { display: flex; gap: .5rem; align-items: center; }
.skel .b {
  border-radius: .375rem; height: .8125rem; margin: .5rem 0;
  background: linear-gradient(90deg, var(--soft) 25%, color-mix(in srgb, var(--border) 45%, var(--soft)) 50%, var(--soft) 75%);
  background-size: 300% 100%;
  animation: shimmer 1.3s ease-in-out infinite;
}
.skel .c { width: 2.625rem; height: 2.625rem; border-radius: 50%; margin: 0; flex: none; }
@keyframes shimmer { from { background-position: 100% 0; } to { background-position: 0 0; } }
.sentinel { display: grid; place-items: center; min-height: 3.5rem; color: var(--muted); font-size: .9375rem; }
.empty { padding: 2.5rem 1rem; text-align: center; color: var(--muted); animation: post-in .5s var(--out-ease); }
.empty .icon { width: 2rem; height: 2rem; margin-bottom: .5rem; color: var(--border); }

/* ---------------------------------------------------------------- compose dock (sticky at the bottom of the column) */
#dock {
  position: sticky; bottom: 0; z-index: 25;
  padding: .5rem;
  padding-bottom: max(.5rem, env(safe-area-inset-bottom));
  background: var(--back);
  border-top: var(--line) solid var(--border);
}
@supports (backdrop-filter: blur(1px)) {
  #dock { background: color-mix(in srgb, var(--back) 86%, transparent); backdrop-filter: saturate(1.5) blur(12px); }
}
#dock.rise { animation: rise .5s var(--spring); }
@keyframes rise { from { transform: translateY(100%); opacity: 0; } }
body:not(.booted) #dock { opacity: 0; transform: translateY(.75rem); }
#dock { transition: opacity .45s .15s var(--out-ease), transform .55s .15s var(--spring), background-color .3s; }
.dock-in { display: flex; gap: .5rem; align-items: center; }
.dock-btn {
  flex: 1; min-width: 0; height: 2.625rem;
  display: flex; align-items: center; gap: .5rem;
  padding: 0 .75rem 0 .25rem;
  border: var(--line) solid var(--border); border-radius: var(--radius); background: var(--back);
  color: var(--muted); cursor: text; text-align: start;
  transition: border-color .25s, transform .24s var(--spring), background-color .25s;
}
.dock-btn .ava { width: 2rem; height: 2rem; background: none; border: 0; }
.dock-btn .ava .icon { width: .9375rem; height: .9375rem; }
.dock-btn .ph { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.dock-btn.has-draft { color: var(--front); }
@media (hover: hover) { .dock-btn:hover { border-color: var(--front); background: var(--soft); } }
.dock-btn:active { transform: scale(.985); }

/* ---------------------------------------------------------------- composer (inside the sheet) */
.composer { position: relative; padding: .25rem .25rem .25rem; }
.composer .editor {
  display: block; width: 100%;
  margin: .375rem 0 .5rem; padding: 0;
  border: 0; border-radius: 0; background: transparent;
  resize: none; min-height: 4.5rem; max-height: 45vh; overflow-y: auto; overscroll-behavior: contain;
  field-sizing: content;
}
.composer .bar { display: flex; align-items: center; gap: .5rem; }
.composer .grow { flex: 1; }
.composer.drop { outline: .125rem dashed var(--front); outline-offset: -.375rem; border-radius: var(--radius); }
.ring { width: 1.625rem; height: 1.625rem; transform: rotate(-90deg); opacity: 0; transition: opacity .25s, transform .3s var(--spring); }
.ring.show { opacity: 1; }
.ring.warn { transform: rotate(-90deg) scale(1.15); }
.ring circle { fill: none; stroke-width: 2.5; }
.ring .bg { stroke: var(--border); }
.ring .fg { stroke: var(--front); stroke-linecap: round; transition: stroke-dashoffset .25s var(--out-ease), stroke .25s; }
.ring.over .fg { stroke: var(--err); stroke-dasharray: 2 3 !important; }
.left { font-size: .8125rem; color: var(--muted); min-width: 1.5rem; text-align: end; font-variant-numeric: tabular-nums; }
.left.over { color: var(--err); text-decoration: line-through; }
.progress {
  position: absolute; inset-inline: 0; bottom: -.0625rem; height: .125rem;
  background: var(--front); transform-origin: left; transform: scaleX(0); opacity: 0;
  transition: transform .25s var(--out-ease), opacity .3s;
}
:root[dir="rtl"] .progress { transform-origin: right; }
.progress.on { opacity: 1; }
.preview { position: relative; margin-bottom: .5rem; animation: post-in .35s var(--out-ease); }
.preview img { display: block; width: 100%; max-height: 22rem; object-fit: contain; border-radius: var(--radius); border: var(--line) solid var(--border); background: var(--soft); }
.preview .s-btn { position: absolute; top: .5rem; inset-inline-end: .5rem; width: 2rem; height: 2rem; background: rgba(0, 0, 0, .55) !important; color: #fff; border-color: rgba(255, 255, 255, .4); }
.preview .size { position: absolute; bottom: .5rem; inset-inline-start: .5rem; font-size: .75rem; padding: 0 .5rem; border-radius: 1rem; background: rgba(0, 0, 0, .55); color: #fff; }
.reply-ctx {
  display: flex; align-items: center; gap: .375rem; min-width: 0;
  margin: 0 .25rem .25rem; padding: .375rem .625rem;
  border: var(--line) dashed var(--border); border-radius: var(--radius);
  color: var(--muted); font-size: .875rem;
}
.reply-ctx .icon { width: .875rem; height: .875rem; }
.reply-ctx .quote { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; color: var(--front); }

.notice { display: flex; align-items: center; gap: .375rem; padding: .5rem .75rem; color: var(--muted); font-size: .875rem; border-bottom: var(--line) solid var(--border); }
.notice .icon { width: .875rem; height: .875rem; }

/* more page */
.stack { display: grid; gap: .5rem; padding: .75rem; }
.loc-search { position: sticky; top: 0; z-index: 2; width: 100%; margin-bottom: .5rem; }

/* ---------------------------------------------------------------- modal / sheet */
.backdrop {
  position: fixed; inset: 0; z-index: 60;
  display: grid; place-items: center; padding: .5rem;
  background: var(--overlay);
  opacity: 0; transition: opacity .25s;
}
.backdrop.open { opacity: 1; }
.modal {
  width: 100%; max-width: 32.75rem; max-height: calc(100dvh - 1rem); overflow: auto;
  overscroll-behavior: contain; /* scrolling past either end never moves the page behind */
  background: var(--back); color: var(--front);
  border: var(--line) solid var(--border); border-radius: var(--radius);
  padding: .5rem;
  opacity: 0; transform: scale(.94) translateY(.5rem);
  transition: transform .36s var(--spring), opacity .22s;
}
/* The composer sheet: the head stays, the body scrolls, and a skirt in the sheet's colour hangs below it so
   no gap shows under the sheet while it springs up, is dragged, or rides an on-screen keyboard. The skirt is
   anchored to the sheet's own box (position: relative + top: 100%), so it moves with every transform of it;
   the sheet itself no longer clips (overflow: visible), only its body scrolls. */
.modal.compose { position: relative; display: flex; flex-direction: column; overflow: visible; }
.modal.compose > .modal-head { flex: none; }
.modal.compose > .modal-body { flex: 1 1 auto; min-height: 0; overflow-y: auto; overscroll-behavior: contain; }
.modal.compose::after {
  content: ""; position: absolute; top: calc(100% - var(--line)); height: 100vh; pointer-events: none; /* overlap: no seam */
  left: calc(-1 * var(--line)); right: calc(-1 * var(--line));
  background: var(--back); border-inline: var(--line) solid var(--border);
}
.modal.tall { height: min(40rem, calc(100dvh - 1rem)); }
.backdrop.open .modal { opacity: 1; transform: none; }
.backdrop.closing .modal { transition-timing-function: var(--out-ease); transition-duration: .22s; }
.modal-head { display: flex; align-items: center; gap: .5rem; touch-action: none; }
.modal-title { flex: 1; font-weight: 700; padding-inline-start: .25rem; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.modal-body { padding-top: .5rem; }
.modal-body .q { margin: 0 0 .5rem; color: var(--muted); padding-inline: .25rem; display: none; }
.options { display: grid; gap: .5rem; }
.options.sep { margin-top: .75rem; padding-top: .75rem; border-top: var(--line) solid var(--border); }
.grab { display: none; }
@media (max-width: 33.75rem) {
  .backdrop { place-items: end stretch; padding: 0; }
  .modal {
    max-width: none; max-height: 88dvh; border-radius: 1rem 1rem 0 0; border-bottom: 0;
    padding-bottom: calc(.75rem + env(safe-area-inset-bottom));
    transform: translateY(100%); opacity: 1;
    transition: transform .42s var(--spring);
  }
  .modal.tall { height: 88dvh; }
  .backdrop.closing .modal { transition-duration: .28s; }
  .grab { display: block; position: absolute; left: 50%; top: .3125rem; width: 2.25rem; height: .25rem; margin-left: -1.125rem; border-radius: 1rem; background: var(--border); }
  .modal-head { position: relative; padding-top: .5rem; }
}
/* the composer sheet rises from the bottom of the column on every screen size */
.backdrop.dock-sheet { place-items: end center; padding: 0; }
.backdrop.dock-sheet .modal {
  max-width: var(--col); max-height: min(88dvh, 40rem);
  border-radius: 1rem 1rem 0 0; border-bottom: 0;
  padding-bottom: calc(.5rem + env(safe-area-inset-bottom));
  opacity: 1; transform: translateY(100%);
  transition: transform .42s var(--spring);
}
.backdrop.dock-sheet.open .modal { transform: none; }
.backdrop.dock-sheet.closing .modal { transform: translateY(100%); transition-duration: .28s; transition-timing-function: var(--out-ease); }
.backdrop.dock-sheet .grab { display: block; position: absolute; left: 50%; top: .3125rem; width: 2.25rem; height: .25rem; margin-left: -1.125rem; border-radius: 1rem; background: var(--border); }
.backdrop.dock-sheet .modal-head { position: relative; padding-top: .5rem; }
/* An on-screen keyboard that covers the page instead of shrinking it (iOS Safari, in-app browsers;
   ui.js trackKeyboard): sheets fill only the visible area above it, and the text box leaves room for the
   send bar. No safe-area padding there: the keyboard is below. */
:root.kb-open .backdrop { top: var(--vv-top, 0px); bottom: auto; height: var(--vv-h, 100%); }
:root.kb-open .modal, :root.kb-open .backdrop.dock-sheet .modal {
  max-height: min(40rem, calc(var(--vv-h, 100dvh) - .5rem)); padding-bottom: .5rem;
}
:root.kb-open .modal.tall { height: calc(var(--vv-h, 100dvh) - .5rem); }
:root.kb-open .composer .editor { max-height: max(3rem, calc(var(--vv-h, 100dvh) - 11rem)); }
:root.kb-open #toasts { bottom: calc(var(--kb, 0px) + .75rem); }

/* lightbox */
#lightbox {
  position: fixed; inset: 0; z-index: 80;
  display: grid; place-items: center;
  background: rgba(0, 0, 0, .92);
  opacity: 0; transition: opacity .3s;
  cursor: zoom-out; touch-action: pinch-zoom;
}
#lightbox.open { opacity: 1; }
#lightbox img { max-width: 100vw; max-height: 100dvh; object-fit: contain; -webkit-user-drag: none; }
#lightbox .s-btn { position: fixed; top: max(.75rem, env(safe-area-inset-top)); inset-inline-end: .75rem; background: rgba(0, 0, 0, .5); color: #fff; border-color: rgba(255, 255, 255, .3); }

/* toast */
#toasts {
  position: fixed; z-index: 90; inset-inline: 0; bottom: calc(1rem + env(safe-area-inset-bottom));
  display: grid; justify-items: center; gap: .5rem; pointer-events: none; padding: 0 1rem;
  transition: bottom .3s var(--out-ease);
}
.has-dock #toasts { bottom: calc(4.5rem + env(safe-area-inset-bottom)); }
.toast {
  display: inline-flex; align-items: center; gap: .5rem; max-width: 100%;
  padding: .5rem .875rem; border-radius: var(--radius);
  border: var(--line) solid var(--front); background: var(--back); color: var(--front);
  box-shadow: 0 .5rem 2rem var(--shadow);
  opacity: 0; transform: translateY(.75rem) scale(.96);
  transition: transform .4s var(--spring), opacity .25s;
}
.toast.show { opacity: 1; transform: none; }
.toast.err { border-color: var(--err); border-style: dashed; }
.toast.err .icon { color: var(--muted); }

/* ---------------------------------------------------------------- motion preferences */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: .01ms !important; animation-iteration-count: 1 !important;
    animation-delay: 0s !important; transition-duration: .01ms !important; scroll-behavior: auto !important;
  }
}
