/* The look of Are.na, made small for an app: Arial, regular weight, hierarchy by size and grey; white (or black) with
   navy buttons, 3px corners, their spacing (2 5 10 15 20 25 35 45 65). Each person keeps their colour as a name badge.
   Follows the system's light or dark. */
:root {
  --bg: #fff; --fg: rgba(0, 0, 0, .85); --fg2: rgba(0, 0, 0, .6); --fg3: #999; --fg4: #b2b2b2;
  --g1: #f7f7f7; --g2: #ededed; --g3: #dedede; --line: #e5e5e5;
  --brand: #00075f; --on-brand: #fff; --focus: #3d46c2; --mark: #fff3cf; --hair: .5px; --alert: #e15100; --green: #238020; --red: #e3164c;
  --tip-bg: #333; --tip-fg: #fff; --shadow: 0 6px 24px rgba(0, 0, 0, .12);
  --font: Arial, Helvetica, sans-serif;
  --xs: .78125rem; --sm: .9rem; --md: 1rem; --lg: 1.2rem; --xl: 1.5rem;
  --max: 580px; --gutter: 15px; --edge: max(var(--gutter), env(safe-area-inset-left, 0px));
  --c: var(--g3);
  /* Corners: Are.na's square-ish boxes with the faintest squircle (continuous corners where the browser draws them). */
  --r: 4px;
  color-scheme: light;
}
@media (prefers-color-scheme: dark) {
  :root {
    --bg: #000; --fg: rgba(255, 255, 255, .85); --fg2: rgba(255, 255, 255, .6); --fg3: #696969; --fg4: #4f4f4f;
    --g1: #1a1a1a; --g2: #222; --g3: #333; --line: #262626;
    --brand: #3d46c2; --on-brand: #fff; --focus: #5e6dee; --mark: #3b3115; --alert: #ff7a33; --green: #4caf50; --red: #ff285f;
    --tip-bg: #e5e5e5; --tip-fg: #000; --shadow: 0 6px 24px rgba(0, 0, 0, .6);
    color-scheme: dark;
  }
}
* { box-sizing: border-box; -webkit-tap-highlight-color: transparent; }
[hidden] { display: none !important; }
html, body { background: var(--bg); color: var(--fg); font: 400 var(--md)/1.45 var(--font); margin: 0; -webkit-text-size-adjust: 100%; }
a { color: inherit; text-decoration: none; }
button { font: inherit; color: inherit; background: none; border: 0; padding: 0; margin: 0; cursor: pointer; }
h1, h2 { font-weight: 400; }
.w { width: 100%; max-width: var(--max); margin: 0 auto; padding-left: max(var(--gutter), env(safe-area-inset-left)); padding-right: max(var(--gutter), env(safe-area-inset-right)); }
.mute { color: var(--fg2); }
.small { font-size: var(--xs); color: var(--fg3); }
.note { color: var(--alert); font-size: var(--sm); margin: 10px 0 0; }
.note.ok { color: var(--fg2); }
:focus-visible { outline: 2px solid var(--focus); outline-offset: 2px; border-radius: var(--r); }
input:focus-visible, textarea:focus-visible { outline: none; }
::selection { background: color-mix(in srgb, var(--focus) 25%, transparent); }

/* Icons: one stroke weight, the text's colour. */
.i { width: 16px; height: 16px; flex: none; display: block; fill: none; stroke: currentColor; stroke-width: 1.5; stroke-linecap: round; stroke-linejoin: round; }

/* The one arrow, after the words of anything that takes you somewhere. */
.i.after { display: inline-block; width: 14px; height: 14px; margin-left: 5px; vertical-align: -2px; }

/* Toasts (public/toast.js): small boxes dropped in at the top of any page. */
#toasts { position: fixed; z-index: 40; top: calc(10px + env(safe-area-inset-top, 0px)); left: var(--gutter); right: var(--gutter); display: grid; justify-items: center; gap: 5px; pointer-events: none; }
.toast { pointer-events: auto; display: flex; align-items: center; gap: 10px; max-width: min(100%, calc(var(--max) - 2 * var(--gutter))); min-height: 38px; padding: 0 12px; background: var(--bg); color: var(--fg); border: 1px solid var(--line); border-radius: var(--r); box-shadow: var(--shadow); font-size: var(--sm); animation: toast-in .18s cubic-bezier(.22, 1, .36, 1) both; }
.toast:has(.ib) { padding-right: 4px; }
.toast a { color: var(--focus); white-space: nowrap; }
.toast a:hover { text-decoration: underline; text-underline-offset: 3px; }
@keyframes toast-in { from { opacity: 0; translate: 0 -10px; } }
@media (prefers-reduced-motion: reduce) { .toast { animation-name: fade; } }

/* Tooltips: a word or two in a small dark box, after a moment, above whatever has data-tip. Fingers don't hover. */
[data-tip] { position: relative; }
@media (hover: hover) {
  [data-tip]:hover::after, [data-tip]:focus-visible::after {
    content: attr(data-tip); position: absolute; z-index: 20; bottom: calc(100% + 6px); left: 50%; translate: -50% 0;
    background: var(--tip-bg); color: var(--tip-fg); font-size: var(--xs); line-height: 1.35; padding: 4px 7px; border-radius: var(--r);
    white-space: pre-line; width: max-content; max-width: 260px; pointer-events: none; animation: tip .15s .35s both;
  }
  [data-tip-end]:hover::after { left: auto; right: 0; translate: 0 0; }
  [data-tip-start]:hover::after { left: 0; translate: 0 0; }
}
@keyframes tip { from { opacity: 0; } }

/* Buttons, as Are.na's: navy and full width for the one thing to do, grey for the other. */
.btn { display: flex; align-items: center; justify-content: center; gap: 8px; width: 100%; min-height: 45px; padding: 0 20px; border-radius: var(--r);
  background: var(--brand); color: var(--on-brand); font-size: var(--sm); text-align: center; transition: opacity .15s; }
.btn:hover { opacity: .92; }
.btn.secondary { background: var(--g1); color: var(--fg); }
.btn.secondary:hover { background: var(--g2); opacity: 1; }
.btn[aria-pressed="true"] { background: var(--g1); color: var(--fg); }
.btn[disabled] { opacity: .55; cursor: default; }
/* Busy: the button that was pressed turns into the wait, a plain ring where its label was. */
form[aria-busy] .btn[type="submit"], .btn[aria-busy] { position: relative; color: transparent; opacity: 1; pointer-events: none; }
form[aria-busy] .btn[type="submit"] > *, .btn[aria-busy] > * { visibility: hidden; }
form[aria-busy] .btn[type="submit"]::after, .btn[aria-busy]::after { content: ""; position: absolute; inset: 0; margin: auto; width: 18px; height: 18px; border: 2px solid color-mix(in srgb, var(--on-brand) 35%, transparent); border-top-color: var(--on-brand); border-radius: 50%; animation: spin .8s linear infinite; }
.btn.secondary[aria-busy]::after, form[aria-busy] .btn.secondary[type="submit"]::after { border-color: var(--g3); border-top-color: var(--fg2); }
.link { color: var(--fg2); text-decoration: underline; text-decoration-color: var(--g3); text-underline-offset: 3px; }
.link:hover { color: var(--fg); text-decoration-color: currentColor; }
code { font-family: ui-monospace, Menlo, monospace; font-size: .85em; color: var(--fg); word-break: break-all; cursor: copy; }

/* Fields: a grey box, 3px corners, a blue ring when focused. */
.box { display: flex; align-items: stretch; min-height: 45px; background: var(--g1); border: 1px solid var(--g1); border-radius: var(--r); transition: border-color .15s, background .15s; }
.box:focus-within { background: var(--bg); border-color: var(--focus); }
.box input { flex: 1; min-width: 0; padding: 0 12px; border: 0; background: transparent; color: var(--fg); font: inherit; font-size: var(--md); outline: 0; border-radius: var(--r); -webkit-appearance: none; appearance: none; }
.box input::placeholder { color: var(--fg3); }
.box[aria-invalid="true"] { border-color: var(--alert); }

/* The top bar: the brand mark and what the page picks between (All, You, groups), you on the right. */
.top { display: flex; align-items: center; gap: 2px; padding-top: max(8px, env(safe-area-inset-top)); padding-bottom: 6px; font-size: var(--sm); }
.top .brand { display: flex; align-items: center; flex-wrap: wrap; gap: 5px; padding: 6px 0; color: var(--fg2); }
.top .brand svg { width: 15px; height: 15px; flex: none; }
.top .tabs { display: flex; gap: 2px; min-width: 0; overflow-x: auto; scrollbar-width: none; }
.top .tabs::-webkit-scrollbar { display: none; }
.top .tabs a { flex: none; padding: 6px 10px; border-radius: var(--r); color: var(--fg2); white-space: nowrap; }
.top .tabs a:hover { color: var(--fg); background: var(--g1); }
.top .tabs a[aria-current="page"] { color: var(--fg); background: var(--g1); }
.top .right { margin-left: auto; flex: none; padding: 6px 0 6px 10px; color: var(--fg2); white-space: nowrap; }
.top .right:hover, .top .right[aria-current="page"] { color: var(--fg); }
/* Connect now, until Claude or ChatGPT is connected. */
#connect-banner { flex: none; padding-top: 2px; padding-bottom: 5px; }
.connect-banner { position: relative; display: flex; align-items: center; gap: 8px; min-height: 40px; padding-left: 10px; background: var(--g1); border-radius: var(--r); font-size: var(--sm); }
.connect-banner:hover { background: var(--g2); }
/* The whole bar is Connect now; the Claude logo and the x sit above it, each doing its own thing. */
.connect-banner .go::after { content: ""; position: absolute; inset: 0; }
.connect-banner svg:not(.i) { width: 16px; height: 16px; flex: none; }
.connect-banner .add { position: relative; z-index: 1; display: flex; align-items: center; align-self: stretch; padding: 0 6px; margin: 0 -6px 0 -4px; }
.connect-banner .ib { position: relative; z-index: 1; margin-left: auto; margin-right: 5px; }
.connect-banner .ib:hover { background: var(--g3); }

/* Pages that scroll: invite, profile, getting started. */
div.page { padding-top: 25px; padding-bottom: 65px; }
div.page h1 { font-size: var(--lg); line-height: 1.35; margin: 0 0 20px; }
div.page h2 { font-size: var(--md); margin: 35px 0 10px; }
div.page p { margin: 0 0 10px; }
div.page .step { margin: 20px 0; display: grid; gap: 10px; }
div.page blockquote { margin: 0 0 15px; padding: 12px 15px; background: var(--g1); border-radius: var(--r); white-space: pre-wrap; overflow-wrap: anywhere; }
/* An invite (pages.ts invitePage): one sentence in grey with what you're joining in black and its picture small
   beside it, then what they said as a message from them; the one thing to do sits at the foot, by the thumb. */
.login main:has(> .invited) { display: flex; flex-direction: column; min-height: 100dvh; padding-top: max(12vh, 45px); padding-bottom: max(20px, env(safe-area-inset-bottom)); }
.invited { flex: 1; display: flex; flex-direction: column; }
.invited .says-who { margin: 0; font-size: var(--xl); line-height: 1.35; color: var(--fg3); }
.invited .says-who b { font-weight: 400; color: var(--fg); }
.invited .says-who .nb { white-space: nowrap; }
.invited .pic { display: inline-block; width: 24px; height: 24px; margin-right: 2px; vertical-align: -3px; border-radius: var(--r); object-fit: cover; background: var(--g1); }
.invited .msg { margin-top: 25px; }
.invited .msg + .msg { margin-top: 12px; }
.invited .msg .by { margin: 0 0 3px 4px; font-size: var(--xs); color: var(--fg3); }
.invited .bub { display: inline-block; max-width: 100%; margin: 0; padding: 10px 14px; background: var(--g2); border-radius: 18px 18px 18px 4px; font-size: var(--lg); line-height: 1.3; white-space: pre-wrap; overflow-wrap: anywhere; }
.invited .bub .veiled { filter: blur(8px); user-select: none; pointer-events: none; }
.invited .foot { margin-top: auto; padding-top: 35px; display: grid; gap: 10px; }
.invited .foot p { margin: 0; }
.invited .foot .small { margin: 5px 0 0; }
.invited .tagline { display: flex; align-items: center; justify-content: center; flex-wrap: wrap; gap: 5px; font-size: var(--xs); color: var(--fg2); }
.invited .tagline svg { width: 15px; height: 15px; flex: none; }
.invited .connect { display: grid; gap: 10px; margin: 0; }
.connect:not(:has([data-app])) .until-connected { display: none; }
/* Something you can say: the arrow, then the sentence. */
.says { display: grid; gap: 6px; margin-bottom: 10px; }
.say { display: flex; align-items: flex-start; gap: 10px; padding: 11px 14px; border-radius: var(--r); background: var(--g1); font-size: var(--sm); line-height: 1.4; color: var(--fg); }
.say:hover { background: var(--g2); }
.say .i { margin-top: 2px; color: var(--fg3); }
div.page .try { color: var(--fg2); margin: 5px 0; }
div.page p.done { margin-top: 35px; }

/* Sign-in: one question, its field, one navy button; a narrow column a third of the way down. */
.login main { width: 100%; max-width: var(--max); margin: 0 auto; padding: max(14vh, 45px) var(--gutter) 45px; }
.login h1 { font-size: var(--lg); line-height: 1.35; margin: 0 0 5px; }
.login .lede { color: var(--fg2); font-size: var(--sm); margin: 0 0 20px; }
.login form { display: grid; gap: 10px; }
.sub { display: flex; flex-wrap: wrap; gap: 5px 20px; margin: 15px 0 0; font-size: var(--sm); }
.sub button, .sub a { color: var(--fg2); text-decoration: underline; text-decoration-color: var(--g3); text-underline-offset: 3px; padding: 5px 0; }
.sub button:hover, .sub a:hover { color: var(--fg); text-decoration-color: currentColor; }
.login .small { margin-top: 25px; line-height: 1.5; }
/* Just logged out: one tap puts you back. */
.login form.undo { display: flex; align-items: center; justify-content: space-between; gap: 10px; margin: 0 0 35px; padding: 5px 5px 5px 15px; border-radius: var(--r); background: var(--g1); font-size: var(--sm); }
.login form.undo p { margin: 0; }
.login form.undo .btn { width: auto; min-height: 40px; background: var(--bg); }
/* The code: big digits, spaced, one field. */
.box.code input { font-size: var(--xl); letter-spacing: .35em; padding-left: 15px; font-variant-numeric: tabular-nums; }
.box.code input::placeholder { letter-spacing: .35em; color: var(--fg4); }

/* The phone field: the country (flag, code) and the number, in one box. */
.phone { position: relative; }
.cc { flex: none; display: flex; align-items: center; gap: 5px; min-width: 106px; padding: 0 8px 0 12px; color: var(--fg); font-size: var(--md); font-variant-numeric: tabular-nums; white-space: nowrap; border-right: 1px solid var(--g3); border-radius: var(--r) 0 0 3px; }
.cc:hover, .cc[aria-expanded="true"] { background: var(--g2); }
.cc .chev { width: 12px; height: 12px; color: var(--fg3); margin-left: auto; }
.flag { font-family: "Apple Color Emoji", "Segoe UI Emoji", "Noto Color Emoji", sans-serif; font-size: 1.15em; line-height: 1; }
.cc-pop { position: absolute; z-index: 10; left: 0; right: 0; top: calc(100% + 5px); background: var(--bg); border: 1px solid var(--g3); border-radius: var(--r); box-shadow: var(--shadow); overflow: hidden; }
.cc-search { display: flex; align-items: center; gap: 8px; padding: 0 12px; border-bottom: 1px solid var(--line); color: var(--fg3); }
.cc-search input { flex: 1; min-width: 0; height: 44px; border: 0; background: transparent; color: var(--fg); font: inherit; font-size: var(--md); outline: 0; -webkit-appearance: none; appearance: none; }
.cc-search input::placeholder { color: var(--fg3); }
.cc-list { list-style: none; margin: 0; padding: 5px 0; max-height: min(38vh, 300px); overflow-y: auto; overscroll-behavior: contain; scrollbar-width: thin; }
.cc-list li { display: flex; gap: 10px; align-items: center; padding: 8px 12px; cursor: pointer; }
.cc-list li[aria-selected="true"] { background: var(--g1); }
.cc-list li.sep { height: 1px; padding: 0; margin: 5px 0; background: var(--line); cursor: default; }
.cc-name { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.cc-dial { color: var(--fg3); font-size: var(--sm); font-variant-numeric: tabular-nums; }
.cc-list li[data-current] .cc-dial::after { content: " ✓"; color: var(--focus); }
.cc-none { color: var(--fg3); cursor: default; }

/* The profile: the name in their colour and the handle under it, then rows that all start on the same edge. */
.who { margin: 10px 0 25px; }
.who-top { display: flex; align-items: center; justify-content: space-between; gap: 10px; }
.who-top .ib { margin-block: -5px; margin-right: -7px; }   /* the icon's stroke on the page's edge */
div.page .who h1 { margin: 0; font-size: var(--xl); line-height: 1.25; }
.handle { margin-top: 2px; color: var(--fg3); }
/* Your own name and handle: tap to change them, in place, in the same type. */
.who button { text-align: left; }
.who button.handle { margin-top: 2px; }
.who .note { margin: 8px 0 0; }
.who-edit { display: block; width: 100%; padding: 0; border: 0; border-bottom: 1px solid var(--focus); border-radius: 0; background: none; color: var(--fg); font: inherit; outline: 0; }
.who-edit.name { font-weight: 600; }
.who-edit.handle { margin-top: 2px; }
.follow { margin: 0 0 25px; }
.follow .small { margin: 8px 0 0; }
.rows { display: grid; gap: 10px; }
.label { color: var(--fg3); font-size: var(--xs); margin-bottom: 5px; }
.topics { margin-bottom: 35px; counter-reset: t; }
.topic { display: grid; grid-template-columns: 22px 1fr; text-align: left; padding: 3px 0; color: var(--fg); counter-increment: t; }
.topic::before { content: counter(t, lower-alpha) "."; color: var(--fg3); }
.topic:hover { color: var(--focus); }
/* A person's page is a head over their thoughts (the feed), and under the last of your own, a foot: small, one line. */
.page.head { padding-bottom: 0; }
.foot { display: flex; flex-wrap: wrap; gap: 5px 20px; padding-top: 35px; padding-bottom: 10px; color: var(--fg3); font-size: var(--sm); }
.foot a:hover, .foot button:hover { color: var(--fg); }

/* Add to Claude / Add to ChatGPT, each a grey button with its logo; a connected app is a quiet tick. */
.connect { display: grid; gap: 10px; margin: 0 0 25px; }
.app { display: flex; align-items: center; gap: 10px; min-height: 45px; padding: 0 15px; border-radius: var(--r); font-size: var(--sm); text-align: left; background: var(--g1); color: var(--fg); }
.app:hover { background: var(--g2); }
.app svg { flex: none; }
/* Every row's icon sits in the same 20px column, so every label starts on the same line. */
.app > .i { margin-inline: 2px; }
.connect .steps { list-style: none; margin: 5px 0 0; padding: 0; display: grid; gap: 2px; counter-reset: s; }
.connect .steps li { display: grid; grid-template-columns: 22px 1fr; align-items: baseline; counter-increment: s; }
.connect .steps li::before { content: counter(s, lower-alpha) "."; color: var(--fg3); }
.connect .steps li > :not(button) { grid-column: 2; }
.connect .steps li > span { padding: 4px 0; }
.connect .how { display: grid; gap: 8px; }
.connect .steps button { text-align: left; color: var(--fg); padding: 4px 0; transition: color .2s; }
.connect .steps button[aria-pressed="true"] { color: var(--fg3); text-decoration: line-through; }
.connect .steps li:has(button[aria-pressed="true"])::before { content: "✓"; color: var(--green); }
/* Always allow: an open box to tick in a grey row; tapped, the row grows to hold its steps. */
.allow { border-radius: var(--r); background: var(--g1); }
.todo { display: flex; align-items: center; gap: 10px; width: 100%; min-height: 45px; padding: 0 15px; font-size: var(--sm); text-align: left; }
.todo svg { flex: none; }
.tickbox { flex: none; margin: 0 1px 0 auto; display: grid; place-items: center; width: 18px; height: 18px; border: 1.5px solid var(--fg3); border-radius: var(--r); }
.tickbox .i { width: 18px; height: 18px; stroke-width: 2.4; color: var(--green); opacity: 0; transition: opacity .15s; }
/* Done is the tick alone: the box goes. */
.allow[data-done] .tickbox, .tickbox[data-on] { border: 0; }
.allow[data-done] .tickbox .i, .tickbox[data-on] .i { opacity: 1; }
/* A row being waited on: its box is the ring, whether or not it was ticked. */
.app[aria-busy] .tickbox, .app[aria-busy] .tickbox[data-on] { border: 2px solid var(--g3); border-top-color: var(--fg2); border-radius: 50%; animation: spin .8s linear infinite; }
.app[aria-busy] .tickbox .i, .app[aria-busy] .tickbox[data-on] .i { opacity: 0; }
.todo-more { display: grid; grid-template-rows: 0fr; transition: grid-template-rows .24s cubic-bezier(.22, 1, .36, 1); }
.todo-more > div { min-height: 0; overflow: hidden; visibility: hidden; transition: visibility .24s; }
.allow[data-open] .todo-more { grid-template-rows: 1fr; }
.allow[data-open] .todo-more > div { visibility: visible; }
/* Quotes that cycle on the sign-in page (sign_in_quotes.ts): stacked in one cell, so the page never changes height. */
.login main:has(> .quotes) { display: flex; flex-direction: column; min-height: 100dvh; padding-top: max(10vh, 45px); padding-bottom: max(20px, env(safe-area-inset-bottom)); }
.login main:has(> .quotes) > .small { margin-top: auto; padding-top: 25px; }
.quotes { display: grid; margin-bottom: 25px; }
/* One leaves, then the next arrives: two sentences never overlap. */
/* Something someone said, large, signed with their @handle (pages.ts said). Cycling on the sign-in page, one shows at a time. */
.quote { margin: 0; }
.quotes .quote { grid-area: 1 / 1; opacity: 0; translate: 0 8px; transition: opacity .3s ease, translate .3s ease; }
.quotes .quote[data-on] { opacity: 1; translate: 0 0; transition: opacity .5s ease .3s, translate .5s cubic-bezier(.22, 1, .36, 1) .3s; }
.quotes .quote[data-was] { translate: 0 -8px; }
.quote.by-first footer { margin-bottom: 8px; font-size: var(--sm); color: var(--fg2); }
/* What follows a subject and can't be read yet: a stand-in, blurred, wherever the quote is shown. */
.quote .veiled { filter: blur(10px); user-select: none; pointer-events: none; }
/* The invite that brought them, over a sign-in step: it sits where it sat on its own page. */
.login main:has(> .quote.by-first) { padding-top: 32px; }
.login main > .quote.by-first { margin-bottom: 20px; }
.quote.by-first p { margin-bottom: 14px; white-space: pre-wrap; overflow-wrap: anywhere; }
.quote p { margin: 0 0 8px; font-size: var(--xl); line-height: 1.25; }
.quote footer { font-size: var(--xs); }
@media (prefers-reduced-motion: reduce) { .quotes .quote { transition: none; } }
/* A sealed invite: nothing over it, and its two buttons at the foot of the screen, each with its app's mark. */
.login main:has(.sealed, .foot) { display: flex; flex-direction: column; min-height: 100dvh; padding-bottom: max(20px, env(safe-area-inset-bottom)); }
/* A page whose only step is a button or two (a sealed invite, a thought that isn't yours to read: .sealed, .foot).
   The message sits a little above the middle of the space over the buttons (two parts above it, three below), where
   the eye lands; the buttons stay at the foot, by the thumb. A tall one (a picture) just fills from the top. */
.letter:has(.sealed, .foot) { flex: 1; display: grid; grid-template-rows: 2fr auto 3fr auto; grid-template-columns: minmax(0, 1fr); }
.letter:has(.sealed, .foot) > .run.lead { grid-row: 2; margin: 0; }
.letter .sealed, .letter .foot { grid-row: 4; margin: 0; padding-top: 25px; }
.letter:has(.sealed, .foot) > .signed { grid-row: 5; margin-top: 14px; }
.spinner { width: 18px; height: 18px; border: 2px solid var(--g3); border-top-color: var(--fg2); border-radius: 50%; animation: spin .8s linear infinite; }
@keyframes spin { to { rotate: 360deg; } }
@media (prefers-reduced-motion: reduce) { .spinner { animation-duration: 2.4s; } }
.sr { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap; }
.letter .sealed .btn svg { width: 18px; height: 18px; flex: none; }
.letter .quote p { font-size: var(--xl); line-height: 1.25; }

.allow .steps { margin: 0; padding: 0 15px; }
.allow .steps li { grid-template-columns: 30px 1fr; }   /* the letters under the box, the words under its label */
.connect .allow p { margin: 5px 0 0; padding: 0 15px 12px 45px; font-size: var(--xs); }
.connect .allow a { color: var(--fg2); text-decoration: underline; font-size: var(--sm); justify-self: start; }
/* The connector link: in a box, the whole box copies it, a copy icon on the right that turns to a tick. */
.connect .address { margin: 5px 0 0; display: grid; gap: 5px; }
.connect .address .label { margin: 0; }
.copybox { display: flex; align-items: center; gap: 10px; width: 100%; min-height: 45px; padding: 0 12px 0 15px; border: 1px solid var(--g3); border-radius: var(--r); background: var(--bg); color: var(--fg); text-align: left; }
.copybox:hover { border-color: var(--fg3); }
.copybox .mono { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font: var(--sm) ui-monospace, SFMono-Regular, Menlo, monospace; }
.copybox .i { color: var(--fg2); }
.copybox .did, .copybox[data-done] .do { display: none; }
.copybox[data-done] .did { display: block; color: var(--green); }

/* The feed: the page never scrolls, only #s does; #app is sized to the visible viewport (feed.js). */
html.thread, body.thread { height: 100%; overflow: hidden; touch-action: manipulation; }
#app { position: fixed; left: 0; right: 0; top: 0; height: 100%; display: flex; flex-direction: column; }
#app > .top { flex: none; }
#s { flex: 1; overflow-y: auto; overscroll-behavior: contain; -webkit-overflow-scrolling: touch; padding-bottom: max(25px, env(safe-area-inset-bottom)); }
#log { padding-top: 5px; }

/* The box: one grey field; Send turns navy once there's something to send. */
.composer { flex: none; display: flex; align-items: flex-end; gap: 5px; padding-top: 5px; padding-bottom: 10px; }
.composer .field { flex: 1; min-width: 0; display: flex; align-items: flex-end; gap: 2px; background: var(--g1); border: 1px solid var(--g1); border-radius: var(--r); padding: 0 5px; transition: border-color .15s, background .15s; }
.composer .field:focus-within { background: var(--bg); border-color: var(--focus); }
.composer textarea { flex: 1; display: block; min-width: 0; height: 43px; max-height: 40vh; margin: 0; padding: 11px 5px; background: transparent; border: 0; outline: 0; resize: none; overflow-y: auto;
  font: inherit; font-size: var(--md); line-height: 1.3; color: var(--fg); -webkit-appearance: none; appearance: none; scrollbar-width: thin; }
.composer textarea::placeholder { color: var(--fg3); }
.composer .ib { height: 43px; }
#go { flex: none; height: 45px; padding: 0 15px; border-radius: var(--r); background: var(--g1); color: var(--fg3); font-size: var(--sm); transition: background .15s, color .15s; }
#go.on { background: var(--brand); color: var(--on-brand); }
.replying { flex: none; display: flex; gap: 8px; align-items: center; color: var(--fg2); font-size: var(--sm); padding-top: 5px; }
.replying .i { width: 14px; height: 14px; color: var(--fg3); }
.replying span { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.replying button { margin-left: auto; }
.drop #s { outline: 2px dashed var(--focus); outline-offset: -8px; }

/* An icon button: quiet grey, darker on hover, a 32px target (44px for fingers). */
.ib { flex: none; display: inline-flex; align-items: center; justify-content: center; gap: 3px; min-width: 30px; height: 30px; padding: 0 5px; border-radius: var(--r); color: var(--fg3); font-size: var(--xs); font-variant-numeric: tabular-nums; }
.ib:hover, .ib[data-open] { color: var(--fg); background: var(--g1); }
.ib.danger:hover { color: var(--alert); }
.ib[data-done] { color: var(--green); }

/* A thread: the first thought, then its replies, each level indented on a thin rule. */
/* A conversation; the line under it runs out past the text to the edge of the screen. */
.thread-block { margin-inline: calc(-1 * var(--edge)); padding: 15px var(--edge); border-bottom: var(--hair) solid var(--line); }
.thread-block:last-of-type { border-bottom: 0; }
.kids { margin-left: 4px; padding-left: 14px; border-left: var(--hair) solid var(--g3); }
/* Replies fold away: the line under a thought says how many and when the latest came, and opens them. */
.fold { display: inline-flex; align-items: center; gap: 5px; margin: 0 0 5px; padding: 2px 0; border: 0; background: none; color: var(--fg3); font: inherit; font-size: var(--xs); cursor: pointer; }
.fold:hover { color: var(--fg); }
.fold .i { width: 10px; height: 10px; transition: transform .15s; }
.node[data-folded] > .fold .i { transform: rotate(-90deg); }
.node[data-folded] > .kids { display: none; }
.kids .kids .kids .kids { margin-left: 0; padding-left: 0; border-left: 0; }
.post { position: relative; padding: 5px 0; overflow-wrap: anywhere; }
.post[data-rises] { animation: rise .5s cubic-bezier(.22, 1, .36, 1) both; }
/* The thought you opened by its link: a soft amber behind its words, like a marked passage. */
.post.focus > .body { background: var(--mark); box-shadow: -6px 0 0 var(--mark), 6px 0 0 var(--mark); border-radius: var(--r); }
/* The line above the words: name badge, when, who it's for, where it's filed; the quiet icons at the end. */
.by { display: flex; align-items: center; flex-wrap: wrap; gap: 3px 8px; min-height: 30px; font-size: var(--xs); color: var(--fg3); }
/* A name: semibold in the person's colour, darkened on white and lightened on black so every colour reads. */
/* A name: semibold in the person's colour, as Den's speakers wear theirs: as it is on black; on white, darkened just
   enough that yellow and lime still read. */
.badge { font-weight: 600; color: color-mix(in srgb, var(--c) 78%, #000); white-space: nowrap; }
@media (prefers-color-scheme: dark) { .badge { color: var(--c); } }
.by .when { margin-left: auto; color: var(--fg3); }
.by .invite + .when { margin-left: 0; }
.by .when:hover { color: var(--fg); }
/* "Justin to Ben": the gaps are a word space. */
.by .to { display: inline-flex; align-items: baseline; gap: 4px; margin-left: -4px; color: var(--fg2); }
.by .to .sep { color: var(--fg3); }
.by .to .comma { margin-left: -4px; color: var(--fg3); }
/* Someone not on Den yet: a name like any other, in grey. */
.by .not-on { font-weight: 600; color: var(--fg3); }
.by .invite { margin-left: auto; color: var(--focus); }
.by .invite:hover { text-decoration: underline; }
.by .filed { color: var(--fg2); }
/* Off the record: a small red label, 3px corners like every box here. */
.by .held, .by .private { display: inline-flex; align-items: center; gap: 3px; padding: 0 5px; border-radius: var(--r); background: var(--g2); color: var(--fg2); line-height: 18px; }
.by .held .i, .by .private .i { width: 11px; height: 11px; }
/* A thought's icons, under it once it's tapped; the first lines up with the words. */
.acts { display: none; align-items: center; gap: 4px; margin: 4px 0 0 -7px; }   /* the first icon's stroke on the words' edge */
.acts .ib { color: var(--fg2); }
.post[data-acts] > .acts { display: flex; animation: fade .12s both; }
/* With a mouse: on the top line, on hover. No width of their own, so the line never reflows; they sit over anything long. */
@media (hover: hover) {
  .by .acts { display: flex; width: 0; gap: 0; justify-content: flex-end; margin: 0 0 0 auto; opacity: 0; }
  .by .when, .by .invite { margin-left: 0; }
  .by .acts .ib { background: var(--bg); }
  .by .acts .ib:hover, .by .acts .ib[data-open] { background: var(--g1); }
  .post:hover > .by > .acts, .by .acts:has(:focus-visible, [data-open]) { opacity: 1; }
}
.body { white-space: pre-wrap; font-size: var(--md); margin: 0; -webkit-user-select: text; user-select: text; }
/* Cut to six lines until "See more" (public/web/clamp.js), unless that would only hide a line. */
.body[data-clamp]:not([data-short]) { display: -webkit-box; -webkit-line-clamp: var(--lines, 6); -webkit-box-orient: vertical; overflow: hidden; }
.body { overflow-wrap: anywhere; }
/* Under the words, on their left edge, only as wide as it reads (the magazine look's column would stretch and centre it). */
.more { display: block; width: fit-content; align-self: flex-start; color: var(--fg2); font-size: var(--sm); padding: 3px 0; }
.more:hover { color: var(--fg); }
.post textarea { display: block; width: 100%; padding: 8px 10px; border: 1px solid var(--focus); border-radius: var(--r); background: var(--bg); color: var(--fg); font: inherit; outline: 0; resize: none; }
.edit-bar { display: flex; gap: 10px; margin-top: 5px; }
.edit-bar .btn { width: auto; min-height: 32px; padding: 0 12px; }
.status { color: var(--fg2); font-size: var(--xs); margin-top: 3px; }
.status button { color: var(--fg); text-decoration: underline; }
.tell-claude { display: block; width: fit-content; }
.tell-claude:hover { color: var(--fg); }
.seen-list { display: grid; gap: 2px; margin: 3px 0 0; padding: 8px 10px; background: var(--g1); border-radius: var(--r); color: var(--fg2); font-size: var(--xs); }

/* What a thought holds, under its words, in order: pictures and players at their own shape, pages in a frame, the rest by name. */
.files { display: grid; gap: 8px; margin-top: 8px; justify-items: start; }
.media { display: block; max-width: min(100%, 520px); }
.media img, img.media { display: block; max-width: 100%; max-height: 70vh; width: auto; height: auto; border-radius: var(--r); }
video.media { width: 100%; max-height: 70vh; border-radius: var(--r); background: #000; }
audio.media { width: min(100%, 420px); height: 40px; }
iframe.page { width: min(100%, 520px); aspect-ratio: 1; max-height: 70vh; border: 0; border-radius: var(--r); background: var(--g1); }
/* Two or more things to look at: one shelf (public/web/shelf.js). One height; each tile as wide as its shape, between
   half the height and 92% of the row, so the next always peeks in. Edge to edge on a phone, hairline gaps, snapped to
   the middle. A shape too extreme to crop is shown whole on its tile. */
.shelf { --h: min(66vw, 352px); position: relative; justify-self: stretch; min-width: 0; }
.shelf .track { display: flex; gap: 2px; overflow-x: auto; overscroll-behavior-x: contain; scroll-snap-type: x mandatory; scrollbar-width: none; }
.shelf .track::-webkit-scrollbar { display: none; }
.shelf .tile { flex: none; height: var(--h); width: clamp(calc(var(--h) * .5), calc(var(--h) * var(--a, 1)), 92%); scroll-snap-align: center; overflow: hidden; border-radius: var(--r); background: var(--g1); }
.shelf .tile > .media, .shelf .tile > .media img, .shelf .tile > iframe { display: block; width: 100%; height: 100%; max-width: none; max-height: none; border-radius: 0; aspect-ratio: auto; }
.shelf .tile .media img, .shelf .tile > video.media { object-fit: cover; }
.shelf .tile[data-whole] .media img { object-fit: contain; }

/* The arrows are den-fiction's strip arrows (ui-kit.css ui-strip-arrow): a bare chevron on each edge the row can
   still travel to, white with a soft shadow so it reads on any picture; faint while the row is hovered, clear under the
   pointer, never there on a touch screen. */
.shelf .nav { position: absolute; z-index: 1; top: 50%; translate: 0 -50%; display: grid; place-items: center; width: 27px; min-width: 0; height: 27px; padding: 0; border-radius: 0; background: transparent; color: #fff; filter: drop-shadow(0 1px 3px rgb(0 0 0 / .58)); opacity: 0; transition: opacity .16s ease; }
.shelf .nav .i { width: 18px; height: 18px; }
.shelf .nav[hidden] { display: none; }
.shelf .nav.prev { left: 0; } .shelf .nav.prev .i { rotate: 90deg; }
.shelf .nav.next { right: 0; } .shelf .nav.next .i { rotate: -90deg; }
.shelf:hover .nav, .shelf .nav:focus-visible { opacity: .55; }
.shelf:hover .nav:hover { opacity: .95; background: transparent; color: #fff; }
@media not all and (hover: hover) and (pointer: fine) { .shelf .nav { display: none; } }
@media (prefers-reduced-motion: reduce) { .shelf .nav { transition: none; } }
/* One song or link card on its own: upright, and small, so it sits beside the words rather than filling the screen. */
iframe.page[data-upright] { width: min(100%, 300px); background: transparent; }
.file { display: inline-flex; align-items: center; gap: 5px; color: var(--fg2); font-size: var(--sm); }
.file:hover { color: var(--fg); }
.file .size { color: var(--fg3); }

#t { color: var(--fg2); font-size: var(--sm); }
#t:not(:empty) { padding: 8px 0 0; }
#t button { color: var(--fg); text-decoration: underline; }
.empty { color: var(--fg2); margin-top: 25px; }
.earlier { color: var(--fg3); font-size: var(--sm); padding: 15px 0 25px; }
.earlier button { color: var(--fg2); text-decoration: underline; }
.up { margin-top: 25px; display: grid; gap: 15px; }
.up input[type="file"] { color: var(--fg2); font: inherit; font-size: var(--sm); max-width: 100%; }

@keyframes rise { from { opacity: 0; translate: 0 8px; } }
@keyframes fade { from { opacity: 0; } }
@media (prefers-reduced-motion: reduce) { .post[data-rises] { animation-name: fade; } }

/* Fingers: the same look, with targets you can hit, the space taken from padding, not layout. */
@media (pointer: coarse) {
  .top .tabs a { padding: 10px 12px; }
  .top .right { padding-top: 10px; padding-bottom: 10px; }
  .ib { min-width: 40px; height: 40px; }
  .acts { margin-left: -12px; }
  .cc-list li { padding: 12px; }
  .topic { padding: 8px 0; }
  .sub button, .sub a { padding: 10px 0; }
}
/* Searching countries: the list has the focus, not the number. */
.box.phone:has(.cc-pop:focus-within) { background: var(--g1); border-color: var(--g1); }

/* What a sent link opens: the thought on top at every step, then one thing to do. */
.letter .next { margin-top: 36px; padding-top: 24px; border-top: 1px solid var(--g2); }
.letter .next h2 { margin: 0 0 6px; font-size: 19px; }
.login main:has(.letter) { padding-top: 32px; }
.letter .run { margin: 0 0 22px; }
.letter .run p { margin: 0 0 12px; font-size: 17px; line-height: 1.45; white-space: pre-wrap; overflow-wrap: anywhere; }
.letter .run p:last-child { margin-bottom: 0; }
.letter .run .who { margin: 0 0 6px; font-size: 14px; color: var(--fg3); }
.letter .run.mine { padding-left: 12px; border-left: 1px solid var(--g2); }
.letter .hook { margin: 0 0 14px; font-size: 24px; line-height: 1.25; font-weight: 600; letter-spacing: -0.01em; white-space: pre-wrap; overflow-wrap: anywhere; }
.letter .media { display: block; width: 100%; margin: 0 0 14px; }
.letter .veiled { filter: blur(10px); user-select: none; pointer-events: none; }
/* Locked, the picture is a fixed band and shrinks while typing, so the thought, the blur and the field all stay on screen above the keyboard. */
.letter .frame { overflow: hidden; margin: 0 0 14px; height: min(26vh, 240px); background: var(--g1); transition: height .2s ease; }
.letter:has(.gate input:focus) .frame { height: 84px; }
.letter .frame .media { margin: 0; width: 100%; height: 100%; object-fit: cover; filter: blur(26px); transform: scale(1.25); }
.letter .frames { display: flex; gap: 2px; margin: 0 0 14px; }
.letter .frames .frame { flex: 1; min-width: 0; margin: 0; }
/* What can't be seen yet, a few lines of it however much there is, fading out so the field under it stays on screen. */
.letter .veil { max-height: 8.2em; overflow: hidden; margin: 0 0 4px; padding: 6px 10px 0; margin-inline: -10px; -webkit-mask-image: linear-gradient(#000 72%, transparent); mask-image: linear-gradient(#000 72%, transparent); transition: max-height .2s ease; }
.letter:has(.gate input:focus) .veil { max-height: 4.4em; }
.letter .veil .held { display: block; width: fit-content; max-width: 100%; padding: 9px 12px; background: var(--g3); border-radius: var(--r); white-space: nowrap; overflow: hidden; }
.letter div.gate > p { margin: 0 0 14px; }
.letter .reveal { position: relative; overflow: hidden; margin: 0 0 14px; background: var(--g1); }
.letter .reveal img { position: absolute; inset: 0; width: 100%; height: 100%; margin: 0; object-fit: cover; }
.letter .reveal .smear { filter: blur(26px); transform: scale(1.25); }
.letter .reveal .media { opacity: 0; filter: blur(24px); transition: opacity .25s ease, filter .8s cubic-bezier(.22, 1, .36, 1); }
.letter .reveal.in .media { opacity: 1; filter: blur(0); }
.letter .gate .small { margin-top: 12px; }
.letter .sent { margin: 0 0 14px; }
.letter .signed { margin-top: 28px; }
.letter .signed a { color: var(--fg3); }
/* The same box as the feed's composer. */
.letter .reply { display: flex; align-items: flex-end; gap: 2px; background: var(--g1); border: 1px solid var(--g1); border-radius: var(--r); padding: 0 10px; }
.letter .reply:focus-within { background: var(--bg); border-color: var(--focus); }
.letter .reply textarea { flex: 1; min-width: 0; display: block; margin: 0; padding: 11px 0; font: inherit; font-size: 17px; line-height: 1.4; border: 0; outline: 0; background: transparent; color: inherit; resize: none; field-sizing: content; max-height: 40vh; }
.letter .reply textarea::placeholder { color: var(--fg3); }
.letter .reply button { flex: none; padding: 11px 0 11px 10px; font: inherit; font-size: 15px; background: none; border: 0; color: inherit; cursor: pointer; }
.letter .assistant { margin-top: 28px; }
.letter .assistant p { margin: 0 0 10px; }
.letter .latest { margin-top: 32px; }
.letter .latest h2 { margin: 0 0 10px; font-size: 14px; font-weight: 400; color: var(--fg3); }
.letter .latest a { display: block; padding: 12px 0; border-top: 1px solid var(--g1); color: inherit; text-decoration: none; }
.letter .latest span { display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 4; overflow: hidden; font-size: 16px; line-height: 1.4; white-space: pre-wrap; overflow-wrap: anywhere; }
.claim { margin: 0 0 22px; }
.claim p { margin: 0 0 10px; }

/* The magazine look (feed.js `mag`, ?look=magazine): the same feed set like a magazine. No rules between thoughts,
   only space; a picture leads its thought edge to edge. Words stay one size, as everywhere. */
.mag .thread-block { border-bottom: 0; padding: 25px var(--edge); }
.mag .thread-block > .node > .post { display: flex; flex-direction: column; }
.mag .thread-block > .node > .post > .acts { order: 2; }
.mag .thread-block > .node > .post[data-pic] > .files { order: -1; justify-items: stretch; margin: 0 calc(-1 * var(--edge)) 10px; }
.mag .thread-block > .node > .post[data-pic] > .files > .media, .mag .thread-block > .node > .post[data-pic] > .files > .media img { width: 100%; max-width: none; max-height: none; border-radius: 0; }
.mag .badge[data-handle] { cursor: pointer; }
/* A run of one person's thoughts as one entry: the first three, each greyer than the last. */
.burst { display: block; width: 100%; padding: 25px 0; border: 0; background: none; color: var(--fg); font: inherit; text-align: left; cursor: pointer; }
.burst .by span:last-child { color: var(--fg3); }
.burst .line { display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; margin-top: 8px; }
.burst .line:nth-of-type(3) { color: var(--fg2); }
.burst .line:nth-of-type(4) { color: var(--fg3); }
.burst .rest { display: block; margin-top: 10px; font-size: var(--xs); color: var(--fg3); }
/* Someone's page, pulled up over the feed as a phone's sheet is. */
.sheet-dim { position: fixed; inset: 0; z-index: 40; background: rgba(0, 0, 0, .28); opacity: 0; transition: opacity .3s ease; }
.sheet-dim[data-open] { opacity: 1; }
.sheet { position: fixed; left: 0; right: 0; bottom: 0; z-index: 41; display: flex; flex-direction: column; width: 100%; max-width: 640px; height: min(92dvh, 760px); margin-inline: auto; overflow: hidden; background: var(--bg); border-radius: 12px 12px 0 0; box-shadow: 0 -8px 40px rgba(0, 0, 0, .12); transform: translateY(100%); transition: transform .42s cubic-bezier(.32, .72, 0, 1); }
.sheet[data-open] { transform: none; }
.sheet .grab { flex: none; width: 36px; height: 5px; margin: 6px auto 0; border-radius: 3px; background: var(--g3); }
.sheet-done { flex: none; align-self: flex-end; min-height: 44px; padding: 0 var(--edge); border: 0; background: none; color: var(--fg2); font: inherit; font-size: var(--sm); cursor: pointer; }
.sheet iframe { flex: 1; width: 100%; border: 0; opacity: 0; transition: opacity .2s ease; }
.sheet iframe[data-ready] { opacity: 1; }
.framed .top, .framed .connect-banner { display: none; }
@media (prefers-reduced-motion: reduce) { .sheet, .sheet-dim { transition: none; } }

/* Search (public/web/search.js): the magnifier on the top bar's right; tapped, the tabs slide away left and the field
   slides in from the right over the same line. */
.top { position: relative; }
.top .search-open { flex: none; display: grid; place-items: center; width: 30px; height: 30px; margin-left: auto; color: var(--fg2); border-radius: var(--r); }
.top .search-open:hover { color: var(--fg); background: var(--g1); }
.top .search-open + .right { margin-left: 0; padding-left: 4px; }
.top .tabs, .top .search-open, .top .right { transition: transform .28s cubic-bezier(.2, .8, .2, 1), opacity .2s ease; }
.top .search { position: absolute; inset: auto var(--edge) 6px; display: flex; align-items: center; gap: 5px; height: 35px; padding: 0 0 0 10px;
  background: var(--g1); border-radius: var(--r); transform: translateX(24px); opacity: 0; pointer-events: none;
  transition: transform .28s cubic-bezier(.2, .8, .2, 1), opacity .2s ease; }
.top .search .glass { flex: none; color: var(--fg3); width: 17px; height: 17px; }
.top .search input { flex: 1; min-width: 0; height: 100%; border: 0; background: none; color: var(--fg); font: inherit; font-size: var(--md); outline: 0; -webkit-appearance: none; }
.top .search input::-webkit-search-cancel-button { display: none; }
.top[data-searching] .search { transform: none; opacity: 1; pointer-events: auto; }
.top[data-searching] .tabs, .top[data-searching] .search-open, .top[data-searching] .right { transform: translateX(-24px); opacity: 0; pointer-events: none; }
.searching #f, .searching #replying, .searching #connect-banner { display: none; }
.results .found { color: var(--fg3); font-size: var(--xs); margin: 5px 0 10px; }
@media (prefers-reduced-motion: reduce) { .top .search, .top .tabs, .top .search-open, .top .right { transition: none; } }

/* The rail on your own page (public/web/rail.js): your thoughts by who can read them, set like the tabs along the top:
   words in grey, the one you're on in a grey box, how many beside each in the lightest grey. */
.rail { display: flex; gap: 2px; margin: 20px 0 0; overflow-x: auto; scrollbar-width: none; }
.rail::-webkit-scrollbar { display: none; }
.rail button { flex: none; display: inline-flex; align-items: baseline; gap: 5px; padding: 6px 10px; border-radius: var(--r); color: var(--fg2); font-size: var(--sm); white-space: nowrap; }
.rail button:hover { color: var(--fg); background: var(--g1); }
.rail button[aria-selected="true"] { color: var(--fg); background: var(--g1); }
.rail .n { color: var(--fg3); font-size: var(--xs); font-variant-numeric: tabular-nums; }
.rail-who { margin: 5px 0 10px; color: var(--fg3); font-size: var(--xs); }

/* A thread's line (feed.js threadEl): who added how many, to what, when; its first thought; the newest replies first. */
.summary { display: flex; align-items: baseline; gap: 5px; width: 100%; margin: 0 0 10px; color: var(--fg2); font-size: var(--sm); text-align: left; }
.summary:hover .what { color: var(--fg); }
.summary .what { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.summary .sep, .summary time { flex: none; color: var(--fg3); }
.answers { display: inline-flex; align-items: center; gap: 5px; max-width: 100%; color: var(--fg3); font-size: var(--xs); overflow: hidden; white-space: nowrap; text-overflow: ellipsis; }
.answers:hover { color: var(--fg2); }
