:root, .auto, .water { --bg: #19222f; --card: #202b3b; --text: #eef0f5; --muted: #a7b0c2; --border: #2f3b4f; --field: #3a4862; --link: #a9c9ef; --hover: var(--hot); --accent: #b9a7e8; --on: #1a1430; --logo: #9fcf8f; --hot: #eaa3c2; --onhot: #2a0f1c; --danger: #ff6b61; --head: "Young Serif", Georgia, serif, "Emoji backup"; --bw: 1px; --dash: solid; color-scheme: dark; }
.light { --bg: #f3f5fa; --card: #fff; --text: #1c2433; --muted: #5d6779; --border: #d8deea; --field: #c3cbdb; --link: #2f63a3; --hover: #b03f78; --accent: #7a63c4; --on: #fff; --logo: #4a8a3c; --hot: #c2558a; --onhot: #fff; --danger: #c4261d; color-scheme: light; }
.lily { --bg: #0f2221; --card: #13302d; --text: #e8f1e4; --muted: #9bb5ad; --border: #24433f; --field: #2f5752; --link: #8fd3c7; --hover: var(--hot); --accent: #6fbf8f; --logo: #6fbf8f; --on: #0e1f1a; --hot: #e98fb0; --onhot: #2a0f1c; --head: Fraunces, Georgia, serif, "Emoji backup"; }
.koi { --bg: #1c1733; --card: #241e42; --text: #f4eefc; --muted: #b5abd6; --border: #3d3466; --field: #4a3f7a; --link: #4fd6cf; --hover: var(--hot); --accent: #ff9a5c; --logo: #ff9a5c; --on: #24102a; --hot: #ff6fae; --onhot: #2b0717; --like: #ff9a5c; --head: Righteous, sans-serif, "Emoji backup"; --body: Nunito, ui-rounded, system-ui, sans-serif, "Emoji backup"; --bw: 2px; --dash: dashed; --shadow: 3px 3px 0 #4fd6cf; }
.pumpkin { --bg: #1a1220; --card: #241a2c; --text: #f6ede4; --muted: #b9a8b8; --border: #3d2c47; --field: #4a3656; --link: #ffb36b; --hover: var(--hot); --accent: #ff7a1a; --on: #1d0c02; --logo: #ff8c2b; --hot: #c9a0ff; --onhot: #1f0d33; }
/* The drop card's tokens (studio design, 2026-10-30; coponder.md, Reactions): each palette's own, made from its colors, Pumpkin Patch's set by hand from the mockup. --mine is
   yours, a chip, a tile or a quick one you gave: the palette's pink, as a lit choice always was (owner), Koi's orange, Pumpkin Patch's orange. Group hues mark the picker's groups only, never chips */
:where(:root) { --card-hover: color-mix(in srgb, var(--card), #fff 3%); --raise: color-mix(in srgb, var(--card), var(--text) 7%); --raise2: color-mix(in srgb, var(--card), var(--text) 13%); --lip: color-mix(in srgb, var(--bg), #000 40%);
  --pop: color-mix(in srgb, var(--card), var(--text) 3%); --pop-line: color-mix(in srgb, var(--border), var(--text) 10%); --mine: var(--like, var(--hot)); --mine-bg: color-mix(in srgb, var(--mine) 24%, var(--card));
  --mine-lip: color-mix(in srgb, var(--mine) 50%, #000); --mine-text: var(--mine); --g-feel: #ff8fb8; --g-agree: #7cc8ff; --g-credit: #8fdc8f; --g-dis: #ab9cf2;
  --t-reply: #7cc8ff; --t-repost: #8fdc8f; --t-react: #ff9a5c; --scrim: rgb(10 6 14 / .62); }
.light { --card-hover: #f7f8fc; --raise: #eef1f7; --raise2: #e2e7f1; --lip: #c9d0de; --pop: #fff; --pop-line: #d3d9e6; --mine-bg: #fbe6f0; --mine-lip: #d9a3bf; --mine-text: #9c2f63; --g-feel: #b8326a; --g-agree: #1f64a8; --g-credit: #2f7a34; --g-dis: #5b45b8; --t-reply: #2f7fd0; --t-repost: #3c9a44; --t-react: #e0742a; --scrim: rgb(20 24 40 / .45); }
.pumpkin { --card-hover: #291e32; --raise: #33263f; --raise2: #3f2f4c; --lip: #150e1b; --pop: #2c2135; --pop-line: #4a3858; --mine: #ff7a1a; --mine-bg: #4b2915; --mine-lip: #8a3a07; --mine-text: #ffb36b; }
.g-feel { --hue: var(--g-feel); } .g-agree { --hue: var(--g-agree); } .g-credit { --hue: var(--g-credit); } .g-dis { --hue: var(--g-dis); } .g-you { --hue: var(--mine); }
/* Pumpkin Patch: a glow at the top of the window, which the sticky header and a desk's held tabs show their own slice of (its drops' 🕸️ went, 2026-10-30, studio design: the season is in the logo) */
.pumpkin body, .pumpkin header, .pumpkin main.desk.held > .tabbar { background: radial-gradient(120% 60% at 50% 0%, #2b1733, #1a1220 70%) fixed 0 0 / 100% 100vh no-repeat var(--bg); }
/* The emoji backup (owner, 2026-10-15): Microsoft's Fluent Emoji for the emoji from 2020 on,
   which Windows 10's emoji font lacks. Computers only: phones keep their own. Cut and written
   by a script (never edited by hand), see the admin wiki's Emoji backup. */
@media not all and (pointer: coarse) {
@font-face { font-family: "Emoji backup"; src: url(/emoji-site.woff2?v=6131641c) format("woff2") tech(color-COLRv1); unicode-range: U+1FAB7, U+1FAC2, U+1FAE7; }
@font-face { font-family: "Emoji backup"; src: url(/emoji-new.woff2?v=03869170) format("woff2") tech(color-COLRv1); unicode-range: U+1F3FB-1F3FF, U+1F6D6-1F6D7, U+1F6DC-1F6DF, U+1F6FB-1F6FC, U+1F7F0, U+1F90C, U+1F972, U+1F977-1F979, U+1F9A3-1F9A4, U+1F9AB-1F9AD, U+1F9CB-1F9CC, U+1FA74-1FA77, U+1FA7B-1FA7C, U+1FA83-1FA88, U+1FA96-1FAB6, U+1FAB8-1FABD, U+1FABF-1FAC1, U+1FAC3-1FAC5, U+1FACE-1FADB, U+1FAE0-1FAE6, U+1FAE8, U+1FAF0-1FAF8; }
} /* end of the emoji backup */
/* Name styles (coponder.md, Accounts, Name styles): a font, an effect, a color and a second color for a
   display name. A font file loads only when a name on the page uses it. */
@font-face { font-family: "Name pixel"; src: url(/font-pixel.woff2?v=9ee47c03) format("woff2"); font-display: swap; }
@font-face { font-family: "Name comic"; src: url(/font-comic.woff2?v=04f54ff4) format("woff2"); font-display: swap; size-adjust: 125%; } /* all capitals: level with the others */
@font-face { font-family: "Name bubble"; src: url(/font-bubble.woff2?v=f5289afc) format("woff2"); font-display: swap; }
@font-face { font-family: "Name script"; src: url(/font-script.woff2?v=99ec044a) format("woff2"); font-display: swap; }
@font-face { font-family: "Name hand"; src: url(/font-hand.woff2?v=252063af) format("woff2"); font-display: swap; }
@font-face { font-family: "Name gothic"; src: url(/font-gothic.woff2?v=e817800b) format("woff2"); font-display: swap; font-weight: 100 900; size-adjust: 115%; }
:is(.nf-pixel, .nf-comic, .nf-bubble, .nf-script, .nf-hand, .nf-gothic) { font-weight: normal; font-size-adjust: none; }
.nf-pixel { font-family: "Name pixel", var(--body, var(--head)); }
.nf-comic { font-family: "Name comic", var(--body, var(--head)); }
.nf-bubble { font-family: "Name bubble", var(--body, var(--head)); }
.nf-script { font-family: "Name script", var(--body, var(--head)); }
.nf-hand { font-family: "Name hand", var(--body, var(--head)); }
.nf-gothic { font-family: "Name gothic", var(--body, var(--head)); font-weight: bold; }
/* one shade for the dark palettes and the always dark picture viewer, a darker one for light */
:root, .lightbox { --rose: #ff8fb8; --ember: #ff9a5c; --gold: #ffd166; --leaf: #8fdc8f; --sky: #7cc8ff; --violet: #c4a5ff; }
.light { --rose: #c2185b; --ember: #b84a00; --gold: #8a6100; --leaf: #2e7d32; --sky: #1565c0; --violet: #6a3fc4; }
:root, .lightbox { --k-fandom: #8ab4ff; --k-character: #95dd95; --k-species: #f58a5b; --k-meta: #f2cf86; --k-lore: #8fd3cb; } /* the creation tag categories' colors, e621's: sky blue, green, orange-red, gold, teal; the 🏷️ panel's dark stage keeps these on every palette */
.light { --k-fandom: #1f5fbf; --k-character: #2e7d32; --k-species: #c2410c; --k-meta: #8a6100; --k-lore: #00796b; } /* darker, to read on a light page (the /tags sidebar) */
.nc-rose, .spoiler:focus .nc-rose { color: var(--rose); }
.nc-ember, .spoiler:focus .nc-ember { color: var(--ember); }
.nc-gold, .spoiler:focus .nc-gold { color: var(--gold); }
.nc-leaf, .spoiler:focus .nc-leaf { color: var(--leaf); }
.nc-sky, .spoiler:focus .nc-sky { color: var(--sky); }
.nc-violet, .spoiler:focus .nc-violet { color: var(--violet); }
/* the second color, the glow's, the pop's shadow's and the rainbow's: picked to go with the name's color, unless you pick one (n2-).
   Always a color, never currentColor: Chromium doesn't blend a color-mix of currentColor between keyframes, so the glow would jump */
:is(.ne-glow, .ne-pop, .ne-rainbow) { --n2: var(--hot); }
.nc-rose { --n2: var(--violet); }
.nc-ember { --n2: var(--rose); }
.nc-gold { --n2: var(--ember); }
.nc-leaf { --n2: var(--sky); }
.nc-sky { --n2: var(--violet); }
.nc-violet { --n2: var(--rose); }
.n2-rose { --n2: var(--rose); }
.n2-ember { --n2: var(--ember); }
.n2-gold { --n2: var(--gold); }
.n2-leaf { --n2: var(--leaf); }
.n2-sky { --n2: var(--sky); }
.n2-violet { --n2: var(--violet); }
.ne-glow { filter: drop-shadow(0 0 .03em var(--n2)) drop-shadow(0 0 .08em color-mix(in srgb, var(--n2) 55%, transparent)); } /* a bright edge close to the letters, not a haze. A filter, not a text-shadow: it breathes without a layout each frame, and each drop-shadow shadows the one before, so two do what three text-shadows did */
.light .ne-glow:not(.lightbox *) { filter: drop-shadow(0 0 .02em var(--n2)) drop-shadow(0 0 .05em var(--n2)) drop-shadow(0 0 .1em color-mix(in srgb, var(--n2) 55%, transparent)); } /* on white, more of the color close to the letters, never wider than the dark glow; the viewer stays dark */
.light .lightbox { --hot: #eaa3c2; --hover: var(--hot); } /* the always dark viewer: a plain name's second color, and a hovered link, Water Lilies' pink */
.ne-pop { text-shadow: .07em .07em 0 var(--n2); }
.light .ne-pop:not(.lightbox *) { text-shadow: .07em .07em 0 color-mix(in srgb, var(--n2) 55%, transparent); } /* the light palette's colors are as dark as each other: a lighter shadow stays apart from the letters */
.ne-rainbow { background: linear-gradient(90deg, currentColor, var(--n2), currentColor) 0 0 / 200% 100%; -webkit-background-clip: text; background-clip: text; -webkit-text-fill-color: transparent; }
:is(.ne-wave, .ne-pop, .ne-shake) i { display: inline-block; font-style: inherit; }
:is(.ne-wave, .ne-pop, .ne-shake) [aria-hidden] > span { display: inline-block; } /* a word goes to the next line whole, and breaks only if it is longer than a line. Not a flex box: its letters would each copy as a line */
:is(.ne-wave, .ne-pop, .ne-shake) .sr { -webkit-user-select: none; user-select: none; } /* a selection is the letters you see, highlighted, and a copy takes them once */
:is(.profile h1, .ns .prev) .ne-wave { line-height: 1.8; } /* a big name that wraps: room for one line's wave to pass the next's */
/* wherever the name shows, unless the device asks for less motion */
@media (prefers-reduced-motion: no-preference) {
  .ne-glow { animation: glow 1.6s ease-in-out infinite alternate; }
  .light .ne-glow:not(.lightbox *) { animation-name: glow-light; }
  .ne-rainbow { animation: slide 4s linear infinite; }
  .ne-hover { display: inline-block; max-width: 100%; animation: hover 1.4s ease-in-out infinite; } /* a box, to move */
  /* RuneScape's wave: 12 letters a wave, each letter a twelfth of the way on (k0 to k11, its place along the name) */
  .ne-wave i { animation: wave .315s ease-in-out infinite alternate; }
  .ne-wave .k1 { animation-delay: -.0525s; }
  .ne-wave .k2 { animation-delay: -.105s; }
  .ne-wave .k3 { animation-delay: -.1575s; }
  .ne-wave .k4 { animation-delay: -.21s; }
  .ne-wave .k5 { animation-delay: -.2625s; }
  .ne-wave .k6 { animation-delay: -.315s; }
  .ne-wave .k7 { animation-delay: -.3675s; }
  .ne-wave .k8 { animation-delay: -.42s; }
  .ne-wave .k9 { animation-delay: -.4725s; }
  .ne-wave .k10 { animation-delay: -.525s; }
  .ne-wave .k11 { animation-delay: -.5775s; }
  /* popcorn: each letter jumps in its turn, a fifth of a second apart, in no order you can follow */
  .ne-pop i { animation: pop 2.4s ease-out infinite; }
  .ne-pop .k1 { animation-delay: -1.4s; }
  .ne-pop .k2 { animation-delay: -.6s; }
  .ne-pop .k3 { animation-delay: -2s; }
  .ne-pop .k4 { animation-delay: -1s; }
  .ne-pop .k5 { animation-delay: -.2s; }
  .ne-pop .k6 { animation-delay: -1.6s; }
  .ne-pop .k7 { animation-delay: -.8s; }
  .ne-pop .k8 { animation-delay: -2.2s; }
  .ne-pop .k9 { animation-delay: -.4s; }
  .ne-pop .k10 { animation-delay: -1.8s; }
  .ne-pop .k11 { animation-delay: -1.2s; }
}
@keyframes glow { to { filter: drop-shadow(0 0 .04em var(--n2)) drop-shadow(0 0 .14em color-mix(in srgb, var(--n2) 60%, transparent)); } }
@keyframes glow-light { to { filter: drop-shadow(0 0 .03em var(--n2)) drop-shadow(0 0 .07em var(--n2)) drop-shadow(0 0 .14em color-mix(in srgb, var(--n2) 60%, transparent)); } }
@keyframes slide { to { background-position: -200% 0; } }
@keyframes hover { 50% { transform: translateY(-.18em); } }
@keyframes wave { from { transform: translateY(-.35em); } to { transform: translateY(.35em); } }
@keyframes pop { 0%, 9%, 100% { transform: none; } 3% { transform: translateY(-.28em) scale(1.18); } 6% { transform: translateY(.03em) scale(.96); } }
/* Words in a drop (coponder.md, Your words, your style) take the names' colors, glow and wave, and shake, RuneScape's:
   each letter shivers up and down, a little ahead of the one before, settling over 1.12 seconds of every 3 (wiki/Research/Name styles.md) */
@media (prefers-reduced-motion: no-preference) {
  .ne-shake i { animation: shake 3s ease-in-out infinite; }
  .ne-shake .k1 { animation-delay: -.0133s; }
  .ne-shake .k2 { animation-delay: -.0267s; }
  .ne-shake .k3 { animation-delay: -.04s; }
  .ne-shake .k4 { animation-delay: -.0533s; }
  .ne-shake .k5 { animation-delay: -.0667s; }
  .ne-shake .k6 { animation-delay: -.08s; }
  .ne-shake .k7 { animation-delay: -.0933s; }
  .ne-shake .k8 { animation-delay: -.1067s; }
  .ne-shake .k9 { animation-delay: -.12s; }
  .ne-shake .k10 { animation-delay: -.1333s; }
  .ne-shake .k11 { animation-delay: -.1467s; }
}
.body :is(.ne-wave, .ne-shake) { line-height: 1.9; } /* a line of moving words has room for them to pass the lines around it */
.light :is(.body, .styles, .cm-content) .ne-glow:not(.lightbox *) { filter: drop-shadow(0 0 .05em var(--n2)) drop-shadow(0 0 .12em color-mix(in srgb, var(--n2) 60%, transparent)); } /* words are thinner than a name: on white, the name's three layers smudged them. Two, at full strength, so WebKit, whose drop-shadows are fainter, shows it too */
.body del i { text-decoration: line-through; } /* a letter box takes no line from the <del> around it */
.body mark [class*="nc-"] { color: inherit; } /* a highlight keeps its dark words: a color on its yellow would barely read */
:is(.body, .styles, .cm-content) .ne-glow, .light :is(.body, .styles, .cm-content) .ne-glow { animation: none; } /* words glow standing: breathing, each glow restyles the page every frame, 0.6 s of every 5 for a feed of 50, and scrolling 1.4 times slower; standing, nothing */
@keyframes shake { 0%, 37.33%, 100% { transform: none; } 1.05% { transform: translateY(.44em); } 3.14% { transform: translateY(-.41em); } 5.24% { transform: translateY(.39em); } 7.33% { transform: translateY(-.36em); } 9.42% { transform: translateY(.34em); } 11.52% { transform: translateY(-.31em); } 13.61% { transform: translateY(.29em); } 15.71% { transform: translateY(-.26em); } 17.8% { transform: translateY(.24em); } 19.9% { transform: translateY(-.21em); } 21.99% { transform: translateY(.18em); } 24.09% { transform: translateY(-.16em); } 26.18% { transform: translateY(.13em); } 28.27% { transform: translateY(-.11em); } 30.37% { transform: translateY(.08em); } 32.46% { transform: translateY(-.06em); } 34.56% { transform: translateY(.03em); } 36.65% { transform: translateY(-.01em); } }
* { box-sizing: border-box; }
body { margin: 0 auto; max-width: 600px; padding: 0 12px; background: var(--bg); color: var(--text); font: 16px/1.45 var(--body, var(--head)); font-size-adjust: .51; overflow-wrap: anywhere; }
a { color: var(--link); text-decoration: none; }
:root { --tint: color-mix(in srgb, currentColor 18%, transparent); } /* the soft tint behind a hovered emoji or styled name, in its own color: currentColor stays a word until the element that uses it */
@media (hover: hover) { /* only where a pointer hovers: a phone keeps :hover on whatever was tapped last, so nothing stays pink, tinted or underlined there */
  :is(a, button, summary):not(.primary, .on, [aria-pressed="true"], .dots > *):hover, a:hover > time { color: var(--hover); } /* hovered, a button turns the palette's pink and never underlines (owner), as a primary one does; a lit one keeps its colors on its highlight, a swatch its own, and a card's time turns with its link */
  :is(.side .contents a, .tree a.muted, .trees .x > button, .lightbox .say a + a, a.cover.emoji, .reader .foot > :is(.prev, .next), section.page0 > .next, .runhead a.rt):hover { color: var(--hover); } /* links whose own color outweighs that rule, or matches it later in the sheet: they turn the pink too */
  .pondrow .meta a:hover, :is(.profile, .pondrow) .rp.joined > summary:hover { color: var(--hover); } /* muted ones: a row's "by @ana" and a member's ✓ Joined */
  .tree > summary:hover > span { color: var(--hover); } /* a tree's folded title: hovering anywhere on its line turns its words the pink with its arrow */
  .actions :is(a, button, summary):hover > .ic, .by a:hover > .ic { border-radius: 50%; background: var(--tint); box-shadow: 0 0 0 .3em var(--tint); } /* an emoji has no color to change: a soft round tint behind it, in its button's color (owner) */
  a:hover :is([class^="nc-"], [class*=" nc-"]):not(.body *) { border-radius: 999px; box-shadow: inset 0 0 0 99em var(--tint), 0 0 0 .2em var(--tint); } /* a name in its owner's color keeps it: a soft tint of it instead (coordinator). A shadow, not a background, which a 🌈 name's letters are. Not a drop's colored words, whose link underlines */
  a:hover .ne-glow:is([class^="nc-"], [class*=" nc-"]):not(.body *) { box-shadow: 0 0 0 .2em var(--tint); } /* a glow's filter glows whatever its name paints, so a filled tint went a heavy pill: a ring alone */
  a:hover .np { box-shadow: 0 0 0 .2em var(--tint); } /* a name picture, trimmed to its letters, takes a ring in the link's pink: rounding it would cut their corners */
  .top > a:has(> .ic):hover::after { content: ""; position: absolute; z-index: -1; top: 50%; left: 50%; width: 1.5em; height: 1.5em; translate: -50% -50%; border-radius: 50%; background: var(--tint); } /* 🔍 and 🔔: their emoji has no box of its own (display: contents), and theirs is wider than tall, so the circle is drawn under them */
  .body a:hover { text-decoration: underline; } /* in a drop's words, a link's color alone barely sets it apart */
}
header, .top, header nav { display: flex; align-items: center; gap: 8px; white-space: nowrap; }
header { gap: 6px; flex-wrap: wrap; position: sticky; top: 0; z-index: 3; background: var(--bg); } /* above an open menu (2), which scrolls under it */
header nav { margin: 0 0 0 auto; gap: 4px; }
html { scroll-padding: max(120px, 7em) 0 80px; } /* a heading or drop jumped to lands below the header, room that grows with big text (em: a minimum font size raises it) */
html:where(:has(.donate:not([hidden]))) { scroll-padding-top: max(160px, 7em); } /* and below the 🐟 donate bubble while it shows; :where, so the lightbox's 0 still wins */
@media (pointer: fine) and (min-width: 600px) { html { scrollbar-gutter: stable; } } /* a mouse's screen keeps the scrollbar's room, so a page that starts to scroll as a box opens (🎣, Formatting, ✨) never slides its column 6px from under the pointer. Not on a phone, where scrollbars take no room and the strip would show beside the bottom bar */
.top { margin-left: auto; gap: 12px; }
.me, article, .actions { position: relative; } /* a ⋯, 🔁 or 🌊 menu opens at its place in the post or row and wraps at its edge, never off a narrow screen */
.me summary, .more summary, .rp summary { list-style: none; cursor: pointer; }
.more { display: block; } /* ⋯ sits at the right end of the row (article > .actions > .end), its menu opening under it */
.me li, .more li { padding: 2px 4px; }
.more summary { padding: 0 8px; color: var(--muted); font-size: 1.2em; line-height: 1; }
.me ul { right: 0; }
.more ul { right: 0; font-size: .9em; } /* it ends under the ⋯ */
.off summary { width: fit-content; padding: 0; color: var(--link); font-size: 1em; cursor: pointer; } /* 👥 Take my name off and an admin's Remove a moderator: a small menu, in ⋯, under a placeholder or under a pond's Moderators line */
.off form { margin: 4px 0 0 1.5em; }
:not(li) > .off { font-size: .9em; } /* under a placeholder, the size of its muted line */
.quote.ask { border-color: var(--accent); } /* the yes-or-no box above a drop you're asked to be credited on */
.me .avatar { width: 35px; height: 35px; margin: 0; font-size: 19px; }
.me .dot { position: absolute; top: 0; right: 0; width: 11px; height: 11px; border-radius: 50%; background: var(--hot); box-shadow: 0 0 0 2px var(--bg); } /* reports wait in the menu: 🔔 owns the header's number */
.me summary { display: flex; } /* the picture is the whole summary, so the dot sits on its corner even with big text */
.top > a { font-size: 1.45em; line-height: 1; }
.tabs a { padding: 5px 14px; border-radius: 999px; }
.tabs.scroll { flex-wrap: nowrap; overflow-x: auto; overscroll-behavior-x: contain; scrollbar-width: none; } /* a profile's six tabs on one line, which scrolls sideways where they can't fit (big text, a zoomed phone), as X's and Bluesky's do */
.tabs.scroll a { flex: none; }
/* the four places fit beside the logo as on the phone bar: icon over name, the pill on the icon */
header nav a, .places a { display: flex; flex-direction: column; align-items: center; font-size: .8em; line-height: 1.25; }
header nav .ic, .places .ic { font-size: 1.55em; padding: 4px 12px; border-radius: 999px; }
header nav .on, .places .on { color: var(--text); }
header nav .on .ic, .places .on .ic, .tabs .on, .addto .on, .saying .on { background: var(--accent); color: var(--on); box-shadow: var(--shadow); }
.top > a { position: relative; }
.top > .t { font-size: 1em; }
.top .unread { position: absolute; border-radius: 999px; top: -3px; right: -9px; min-width: 19px; height: 19px; padding: 0 5px; font: bold 11.5px/19px system-ui, sans-serif; text-align: center; box-shadow: 0 0 0 3px var(--bg); font-variant-numeric: tabular-nums; } /* the alerts' red number, its ring cut out of the header (studio design, 2026-10-30) */
.top .unread, .me .dot { background: #dc2626; color: #fff; } /* something waits: one red on every palette (owner, 2026-10-24), white on it 4.8:1, and it on every palette's page 3.3:1 or more */
.top .quiet { position: absolute; top: 1px; right: -2px; width: 8px; height: 8px; border-radius: 50%; background: var(--accent); box-shadow: 0 0 0 2px var(--bg); } /* only quiet alerts are new (a reaction, a repost, a follow): a dot, no number */
.top > .bell[aria-expanded="true"]::after { content: ""; position: absolute; z-index: -1; top: 50%; left: 50%; width: 1.5em; height: 1.5em; translate: -50% -50%; border-radius: 50%; background: var(--tint); } /* lit while its panel is open, as when hovered */
/* Alerts (coponder.md, Notifications: the panel and its lines), the studio's design: the list on /notifications, and the same list in a panel
   under 🔔 on a computer (static/bell.js). Its colors come from the palette's own, mixed, so every palette gets them */
.alerts, #alerts-panel, .al-toasts { --pop: color-mix(in srgb, var(--card), var(--text) 4%); --pop-line: color-mix(in srgb, var(--border), var(--text) 10%); --raise: color-mix(in srgb, var(--card), var(--text) 9%); --raise2: color-mix(in srgb, var(--card), var(--text) 14%); }
.alerts { font-size: 15px; }
.al-head { display: flex; flex-wrap: wrap; align-items: center; gap: 10px; padding: 14px 16px 0; border-bottom: var(--bw) solid var(--pop-line); }
.al-head h1 { margin: 0 auto 0 0; font-size: 1.3em; }
.al-head .back { display: none; text-decoration: none; font: 22px/1 system-ui, sans-serif; color: var(--text); }
.al-head .markall button { color: var(--link); text-decoration: underline; font-size: 14px; padding: 0; }
.al-head .markall button:hover { color: var(--hover); }
.switch { display: inline-flex; align-items: center; gap: 7px; font-size: 13.5px; color: var(--muted); text-decoration: none; white-space: nowrap; }
.switch i { width: 30px; height: 18px; border-radius: 999px; background: var(--field); position: relative; flex: none; }
.switch i::after { content: ""; position: absolute; left: 2px; top: 2px; width: 14px; height: 14px; border-radius: 50%; background: var(--text); transition: translate .15s; }
.switch.on i { background: var(--accent); }
.switch.on i::after { translate: 12px 0; background: var(--on); }
.filters { order: 1; flex: 1 0 100%; display: flex; flex-wrap: wrap; gap: 6px; padding: 0 0 10px; } /* on a computer, under Alerts, Unread only and Mark all read */
.fp { height: 28px; padding: 0 11px; border-radius: 999px; background: var(--raise); color: var(--muted); font-size: 13px; display: inline-flex; align-items: center; gap: 5px; white-space: nowrap; text-decoration: none; }
.fp.on { background: var(--text); color: var(--bg); font-weight: bold; }
.fp .k { background: #dc2626; color: #fff; font: bold 10.5px/16px system-ui, sans-serif; min-width: 16px; padding: 0 4px; border-radius: 999px; text-align: center; }
.al-list { list-style: none; margin: 0; padding: 0; position: relative; }
.al-list .sec-h { font-size: 12px; font-weight: bold; letter-spacing: .07em; text-transform: uppercase; color: var(--muted); padding: 14px 16px 6px; }
.al-list .none { padding: 16px; }
.al { display: grid; grid-template-columns: 40px 1fr auto; gap: 12px; padding: 11px 16px 12px; position: relative; font-size: 14.5px; line-height: 1.4; }
.al + .al { border-top: var(--bw) solid var(--pop-line); }
.al.unread { background: color-mix(in srgb, var(--accent) 7%, transparent); }
.al.unread::before { content: ""; position: absolute; left: 0; top: 0; bottom: 0; width: 3px; background: var(--accent); }
.al p { margin: 0; }
.al .lead { position: relative; width: 40px; height: 40px; }
.al .lead .avatar { width: 40px; height: 40px; margin: 0; }
.al .tc { display: grid; place-items: center; width: 40px; height: 40px; border-radius: 50%; background: var(--raise); font-size: 19px; }
.al .typ { position: absolute; left: 25px; top: 25px; width: 19px; height: 19px; border-radius: 50%; display: grid; place-items: center; font-size: 10.5px; background: var(--raise); box-shadow: 0 0 0 2px var(--bg); }
.al .who, .al-toast .who { color: var(--text); font-weight: bold; text-decoration: none; }
.al .d { font-weight: bold; text-decoration: none; }
.al .quote { display: block; margin: 6px 0 8px; padding: 8px 11px; border-radius: 9px; background: color-mix(in srgb, var(--bg) 70%, transparent); border: var(--bw) solid var(--border); color: var(--text); text-decoration: none; white-space: pre-line; }
.al .quote:hover { border-color: var(--pop-line); }
.al .when { display: flex; flex-direction: column; align-items: flex-end; gap: 6px; } /* not .side: that is the drop page's column beside it on a wide screen */
.al time { font-size: 12.5px; color: var(--muted); white-space: nowrap; }
.al .mark button { width: 22px; height: 22px; border-radius: 50%; display: grid; place-items: center; padding: 0; }
.al .mark button::after { content: ""; width: 9px; height: 9px; border-radius: 50%; background: var(--accent); }
.al .mark button:hover { background: var(--raise); }
.al .thumb { width: 44px; height: 44px; border-radius: 7px; object-fit: cover; border: var(--bw) solid var(--border); }
.al .faces { display: flex; flex-wrap: wrap; gap: 8px; margin-bottom: 6px; }
.al .faces a { position: relative; }
.al .faces .avatar { width: 30px; height: 30px; margin: 0; font-size: 15px; }
.al .eb { position: absolute; right: -5px; bottom: -4px; width: 16px; height: 16px; display: grid; place-items: center; border-radius: 50%; font-size: 11px; line-height: 1; background: var(--bg); box-shadow: 0 0 0 2px var(--bg); }
.al .mix { font-size: 13.5px; color: var(--muted); margin-top: 3px; font-variant-numeric: tabular-nums; }
.al .acts { display: flex; gap: 6px; align-items: center; flex-wrap: wrap; margin-top: 6px; }
.al .reply { flex: 1; min-width: 150px; margin: 0; }
.al .reply input { width: 100%; height: 32px; border-radius: 999px; padding: 0 12px; font-size: 13.5px; margin: 0; }
.al .mini { height: 32px; padding: 0 10px; border-radius: 999px; background: var(--raise); display: inline-flex; align-items: center; gap: 5px; font-size: 13.5px; color: var(--muted); text-decoration: none; white-space: nowrap; }
.al .done { font-size: 13.5px; }
.al .ppl { list-style: none; padding: 0; margin: 8px 0 0; display: flex; flex-direction: column; gap: 6px; }
.al .ppl li { display: flex; align-items: center; gap: 9px; }
.al .ppl li > a { display: flex; align-items: center; gap: 9px; color: var(--text); text-decoration: none; }
.al .ppl li > a:hover { color: var(--hover); }
.al .ppl .avatar { width: 26px; height: 26px; margin: 0; font-size: 13px; }
.al .ppl form { margin: 0 0 0 auto; }
.al .ppl .btn, .al .ppl .done { margin-left: auto; height: 30px; padding: 0 14px; border-radius: 999px; font-size: 13px; font-weight: bold; display: inline-flex; align-items: center; }
.al .ppl .pri { background: var(--accent); color: var(--on); }
.al .ppl .done { color: var(--muted); box-shadow: inset 0 0 0 1.5px var(--pop-line); font-weight: normal; }
.alerts .pager { padding: 0 16px; }
.al-foot { display: none; }
.newpill { position: sticky; top: 8px; z-index: 3; margin: 8px auto -38px; width: max-content; display: flex; align-items: center; gap: 8px; padding: 5px 13px 5px 6px; border-radius: 999px; background: var(--accent); color: var(--on); font-weight: bold; font-size: 13.5px; box-shadow: 0 6px 16px rgba(0, 0, 0, .45); }
.newpill .avatar { width: 22px; height: 22px; margin: 0 -4px 0 0; font-size: 11px; box-shadow: 0 0 0 2px var(--accent); }
/* the panel: under 🔔, its right edge on the page column's, over the page; Escape or a tap outside closes it (the browser's popover) */
#alerts-panel { position: fixed; inset: 64px max(12px, calc(50% - 300px)) auto auto; width: min(452px, calc(100vw - 24px)); max-height: calc(100vh - 76px); margin: 0; padding: 0; overflow: hidden; color: var(--text); background: var(--pop); border: var(--bw) solid var(--pop-line); border-radius: 14px; box-shadow: 0 16px 40px rgba(0, 0, 0, .55), 0 2px 6px rgba(0, 0, 0, .3); }
#alerts-panel:popover-open { display: flex; flex-direction: column; }
#alerts-panel .alerts { display: flex; flex-direction: column; min-height: 0; flex: 1; }
#alerts-panel .al-list { overflow: auto; flex: 1; }
#alerts-panel .al-foot { display: flex; justify-content: flex-end; margin: 0; padding: 10px 16px; border-top: var(--bw) solid var(--pop-line); font-size: 14px; }
#alerts-panel .al-foot a { text-decoration: none; }
#alerts-panel .al .typ, #alerts-panel .al .eb { box-shadow: 0 0 0 2px var(--pop); }
@media (max-width: 599px) { /* a phone: the full page, with ←, the filters scrolling sideways in one line, Unread only and Mark all read on their own line */
  main:has(> .alerts) { padding: 0; }
  .alerts .al-head { padding: 6px 4px 0; row-gap: 4px; }
  .alerts .al-head .back { display: grid; place-items: center; width: 40px; height: 40px; min-height: 0; margin: 0; padding: 0; } /* not the page-wide .back, a Back link above a title */
  .alerts .al-head h1 { flex: 1 0 60%; }
  .alerts .filters { order: 0; flex-wrap: nowrap; overflow-x: auto; scrollbar-width: none; margin: 0 -16px; padding: 4px 16px 6px; } /* a phone: under Alerts, Unread only and Mark all read under them */
  .alerts .switch, .alerts .markall { padding: 0 8px 12px; }
  .alerts .markall { margin-left: auto; }
  .alerts .al { padding: 12px 2px; }
  .alerts .al.unread { margin: 0 -12px; padding-inline: 14px; }
}
/* toasts: alerts said to you, as they come, in a stack at the bottom left (static/bell.js) */
.al-toasts { position: fixed; left: 20px; bottom: 20px; z-index: 60; display: grid; }
.al-toast { grid-area: 1 / 1; align-self: end; width: min(356px, calc(100vw - 40px)); display: grid; grid-template-columns: 36px 1fr auto; gap: 11px; align-items: center; padding: 12px 12px 12px 14px; background: var(--pop); border: var(--bw) solid var(--pop-line); border-radius: 12px; box-shadow: 0 10px 30px rgba(0, 0, 0, .5); font-size: 14px; overflow: hidden; position: relative; transition: translate .2s, scale .2s, opacity .2s; }
.al-toast::before { content: ""; position: absolute; left: 0; top: 0; bottom: 0; width: 4px; background: var(--accent); }
.al-toast .avatar, .al-toast .tc { width: 36px; height: 36px; margin: 0; }
.al-toast .tc { display: grid; place-items: center; border-radius: 50%; font-size: 18px; background: var(--raise); }
.al-toast p { margin: 0; }
.al-toast .muted { font-size: 13px; display: -webkit-box; -webkit-line-clamp: 1; -webkit-box-orient: vertical; overflow: hidden; }
.al-toast .xn { display: inline-block; margin-left: 4px; padding: 0 6px; border-radius: 999px; background: var(--raise2); font: bold 11.5px/18px system-ui, sans-serif; }
.al-toast .open { height: 32px; padding: 0 14px; border-radius: 999px; font-size: 14px; font-weight: bold; background: var(--raise2); color: var(--text); text-decoration: none; display: inline-flex; align-items: center; }
.al-toast:nth-last-child(2) { translate: 0 -10px; scale: .94; opacity: .55; }
.al-toast:nth-last-child(n+3) { translate: 0 -20px; scale: .88; opacity: .3; }
@media (max-width: 599px) { .al-toasts { left: 10px; right: 10px; bottom: 76px; } .al-toast { width: auto; } } /* over the bar of places, not under it */
@media (prefers-reduced-motion: reduce) { .switch i::after, .al-toast { transition: none; } }
.me ul, .more ul, .rp ul { position: absolute; z-index: 2; list-style: none; background: var(--bg); } /* 2: above the reading bar (1) that follows a drop's menus */
.me ul button, .more ul button, .rp ul button { text-align: left; } /* an item that wraps lines up like the links */
.site { font: 1000 2em/1 var(--head); color: var(--logo); margin-top: -.2em; }
.site .bubble { font-size: 0.45em; vertical-align: 1.5em; margin-left: -1em; }
.site .fish { font-size: .8em; vertical-align: .1em; margin-left: -.3em; }
/* The 🐟 (🎃) says Donate to CoPonder today! (owner, 2026-10-28): a bubble the menu helper shows until its ✕. It and its tail float from
   the sticky header, so they hang from its foot, over the page, never over the header's buttons, even wrapped to two rows. The bubble
   starts at the column's left edge, so it never runs off a narrow screen. The tail, drawn by the 🐟, has no left of its own: it starts
   where the 🐟 ends, and moves back to its middle */
.donate { position: absolute; z-index: 1; top: calc(100% + 9px); left: 0; display: flex; align-items: center; box-sizing: border-box; padding: 4px 2px 4px 14px; font-size: .9em; white-space: normal; background: var(--card); border: 2px solid var(--accent); border-radius: 16px; box-shadow: var(--shadow, 0 4px 14px #0006); } /* 1: under the picture's menu (2) */
.donate[hidden] { display: none; }
header:has(> .donate:not([hidden])) .fish::after { content: ""; position: absolute; z-index: 2; top: calc(100% + 3px); width: 12px; height: 12px; translate: calc(-50% - .68em); rotate: 45deg; background: var(--card); border: solid var(--accent); border-width: 2px 0 0 2px; pointer-events: none; } /* over the bubble's line, joining them */
.donate a { font-weight: bold; }
.donate button { display: grid; place-items: center; flex: none; width: 32px; height: 32px; margin-left: 4px; color: var(--muted); }
.actions .on { color: var(--like, var(--hot)); font-weight: bold; }
form { margin: 0; }
.actions form { display: inline; }
button { font: inherit; color: var(--link); background: none; border: 0; padding: 0; cursor: pointer; }
.primary { background: var(--accent); color: var(--on); border-radius: 999px; padding: 8px 22px; font-weight: bold; box-shadow: var(--shadow); }
h1, :where(.body:not(.doc)) h2 { font: 700 1.75em var(--head); } /* a drop's # is an h2 (one h1 a page), with the h1's look; :where keeps it as light as h1, so .body's sizes win */
.title { font: 700 1.25em/1.25 var(--head); margin: 6px 0 4px; }
.site, h1, :where(.body:not(.doc)) h2, .title { font-size-adjust: .5; font-synthesis: none; }
h2 { font-size: 1.1em; }
h3 { font-size: 1em; } /* a page section's part, under its h2 (/privacy's classes) */
.title a { color: var(--text); }
label { display: block; margin-bottom: 2px; font-weight: bold; }
.form p, .compose p, .drafts { margin: 8px 0; }
input, textarea, select { font: inherit; width: 100%; padding: 8px 10px; color: var(--text); background: var(--card); border: var(--bw) solid var(--field); border-radius: 10px; }
textarea { min-height: 5em; resize: vertical; }
.compose textarea { field-sizing: content; } /* the box where you write a drop grows with its words, without JavaScript; where a browser can't, the handle still drags it */
header, .compose, .form, .profile, .report { padding: 12px 0; border-bottom: var(--bw) var(--dash) var(--border); }
.report time { white-space: nowrap; } /* a date never leaves its year on the next line */
.report > p:first-child { margin-top: 0; } /* the box's padding is gap enough under the line above it */
.counts { overflow-x: auto; } /* with big text the table scrolls, not the page */
.counts table { width: 100%; margin: 8px 0; border-collapse: collapse; overflow-wrap: normal; font-variant-numeric: tabular-nums lining-nums; } /* whole words in the headings; numbers that line up */
.counts th, .counts td { padding: 4px 3px; border-bottom: var(--bw) solid var(--border); text-align: right; }
.counts th { font-size: .75em; } .counts th[scope="row"] { text-align: left; } /* small headings, so the table fits a 360 pixel phone */
article { padding: 2px 16px 14px; margin: 12px 0; font-size: 1.125em; background: var(--card); border: var(--bw) solid var(--border); border-radius: 14px; } /* a folder card is a box like a drop's */
.meta, .muted, time, .footnotes, .share:focus * { color: var(--muted); font-size: .9em; }
.author { font-weight: bold; color: var(--text); }
.by { padding-left: 48px; font-size: .85em; }
.by .author { font-size: 1.11em; }
.by .muted, .by time, .by .share:focus * { font-size: 1em; }
.by .avatar { margin-left: -48px; }
.body { margin: 4px 0; }
.saytap { display: inline; margin: 0; padding: 4px 6px; border-radius: 999px; font-weight: normal; cursor: pointer; } /* a reply's 💭 by its author's name (owner, 2026-10-28): a tap opens its So you're saying… line, no script (post.html) */
.saytap:has(:checked) { background: var(--accent); color: var(--on); } /* open: lit, as a bar's tab is */
.saytap:has(:focus-visible) { outline: auto; }
.saytap .ok { margin-left: 1px; font-weight: bold; color: var(--like, var(--hot)); } /* the drop's author said ✓ That's it */
.saytap:has(:checked) .ok { color: inherit; }
article > .saying { display: none; } /* the line waits behind its 💭; a preview of your own reply shows it */
article:has(> .by .saytap :checked) > .saying { display: block; }
.saying { margin: 6px 0 14px; color: var(--muted); font-size: .9em; } /* the lesser of the two, a clear gap before the words */
.saying form { display: inline; }
.saying :is(button, .got) { font-weight: bold; white-space: nowrap; }
.saying button { padding: 2px 10px; border: 1px solid var(--border); border-radius: 999px; }
.saying .on { border-color: var(--accent); } /* said: lit, as a picked tab is */
.saying .got { color: var(--like, var(--hot)); }
.sayfield { position: relative; } /* the 💭 line of a reply box and a reply's edit form: its 💭 stays at its left, filled or not, since no label says what it is */
.sayfield::before { content: "💭"; position: absolute; left: 10px; top: 50%; transform: translateY(-50%); pointer-events: none; }
.sayfield input { padding-left: 2.5em; }
.field > .sayfield { margin: 0; padding: 8px 16px 0; } /* a reply box's line, at the top of the box, when its 💭 in the bar is lit (owner, 2026-10-28) */
.field > .sayfield::before { left: 16px; top: calc(50% + 4px); font-size: .9em; }
.field > .sayfield input { padding: 6px 0 6px 1.7em; border: 0; border-bottom: 1px dashed var(--border); border-radius: 0; background: none; font-size: .9em; outline: none; } /* the box shows its focus */
.compose:not(:has(.tg.say :checked)) .field > .sayfield { display: none; } /* closed, it keeps its words, and they're sent */
.compose:has(.sayfield input:not(:placeholder-shown)) .tools .tg.say:not(:has(:checked))::after { content: ""; position: absolute; top: 8px; right: 8px; width: 7px; height: 7px; border-radius: 50%; background: var(--accent); } /* a dot: the closed line holds words */
.quote, .me ul, .more ul, .rp ul, .preview { border: 1px solid var(--border); border-radius: 8px; padding: 8px; margin: 8px 0; }
.actions, .tabs, .places, .composebar, .drafts { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; }
.places { justify-content: space-around; } /* 🪷 Ponds's tabs, as the bar of places, across the column on every screen */
.find p { position: relative; margin: 14px 0; } /* 🪷 Ponds's search box: rounded, its 🔍 inside the right end */
.find input { padding-left: 16px; padding-right: 2.8em; border-radius: 999px; }
.find button { position: absolute; right: 4px; top: 50%; transform: translateY(-50%); width: 2.3em; height: 2.3em; border-radius: 999px; }
.find button:hover { background: var(--accent); }
.actions { gap: 4px 16px; }
.actions { font-size: .9em; }
.hearted { position: relative; display: inline-block; line-height: 0; vertical-align: middle; }
.hearted .avatar { width: 20px; height: 20px; margin: 0; font-size: 11px; }
.hearted .heart { position: absolute; right: -5px; bottom: -3px; font-size: 11px; line-height: 1; }
.rp summary { color: var(--link); }
.rp ul { margin-left: -13px; } /* -13px: the ul border, padding and li padding, so the items' 🔁 sits under the summary's */
.rp form, .rp li a, .rp li button { display: block; }
.rp li { padding: 0 4px; }
/* The drop card (studio design, 2026-10-30; coponder.md, The row and Reactions). On a computer, pointed at, it lifts a shade */
article[id^="p"] { transition: background-color .15s; }
@media (hover: hover) and (pointer: fine) { article[id^="p"]:hover { background: var(--card-hover); } }
/* The row: 💬 Reply, 🔁 Repost, 🙂 React together at the left, ✏️ and ⋯ at the right end; the vote arrows in the middle; each 48 pixels tall, its emoji in line with the card's words (-10px), one line always */
article > .actions { flex-wrap: nowrap; gap: 0; margin: 8px -10px -8px; padding-top: 4px; border-top: var(--bw) solid var(--border); font-size: .85em; }
article > .actions > :is(a, span), article > .actions > details > summary { display: inline-flex; align-items: center; gap: 7px; min-height: 48px; padding: 0 9px; border-radius: 999px; color: var(--muted); white-space: nowrap; }
article > .actions > span.muted { white-space: normal; }
article > .actions .ic { display: grid; place-items: center; flex: none; width: 24px; height: 24px; font-size: 20px; line-height: 1; }
article > .actions .c { color: var(--text); font-variant-numeric: tabular-nums; }
article > .actions .on .c, article > .actions .on.c { color: var(--mine-text); }
article > .actions > .num { min-height: 48px; display: inline-flex; align-items: center; margin-left: -8px; padding: 0 8px 0 2px; color: var(--text); font-weight: bold; font-variant-numeric: tabular-nums; } /* on a drop's own page 🔁's count, its own link to who did it (Counts open their lists) */
article > .actions > .num.on { color: var(--mine-text); }
article > .actions > .end { display: flex; margin-left: auto; }
article > .actions > .end > a, article > .actions > .end summary { display: grid; place-items: center; width: 44px; height: 48px; padding: 0; border-radius: 999px; color: var(--muted); font-size: 1.3em; line-height: 1; }
article > .actions > .end summary { font: bold 1.45em/1 system-ui, sans-serif; letter-spacing: 1px; }
article > .actions .reply { --tint: color-mix(in srgb, var(--t-reply) 22%, transparent); }
article > .actions .repost { --tint: color-mix(in srgb, var(--t-repost) 22%, transparent); }
article > .actions .react { --tint: color-mix(in srgb, var(--t-react) 22%, transparent); }
@media (hover: hover) {
  article > .actions > .end > a:hover, article > .actions > .end summary:hover { color: var(--hover); background: var(--raise); }
  article > .actions :is(a, summary):hover > .ic { box-shadow: 0 0 0 6px var(--tint); }
}
/* ⬆️ score ⬇️ alone in the middle of the row, halfway between 🙂 and ✏️ ⋯ (owner, 2026-10-31; coponder.md, Votes): two 44 pixel buttons, the score in bold laid over their empty sides (taps go through it to them). Pointed at, an arrow gets the row's round tint, green for ⬆️ and red for ⬇️, and your vote keeps it, stronger; the score is green above 0, red below. On your own drop the score stands alone; a visitor's arrows are faded text */
article > .actions > .arrows { display: inline-flex; align-items: center; gap: 0; min-height: 48px; margin: 0 auto; padding: 0; }
article > .actions > .arrows ~ .end { margin-left: 0; }
article > .actions > .arrows > :is(button, .ic) { display: grid; place-items: center; width: 44px; height: 48px; padding: 0; color: var(--muted); }
article > .actions > .arrows .ic { border-radius: 999px; }
article > .actions > .arrows > .ic { opacity: .6; }
article > .actions > .arrows > .up { --tint: color-mix(in srgb, var(--g-credit) 22%, transparent); --voted: color-mix(in srgb, var(--g-credit) 40%, transparent); }
article > .actions > .arrows > .down { --tint: color-mix(in srgb, var(--danger) 22%, transparent); --voted: color-mix(in srgb, var(--danger) 40%, transparent); }
article > .actions > .arrows > .on > .ic { background: var(--voted); box-shadow: 0 0 0 4px var(--voted); }
article > .actions > .arrows .score { position: relative; min-width: 1.2em; margin: 0 -4px; text-align: center; color: var(--text); font: bold 17px/1 system-ui, sans-serif; font-variant-numeric: tabular-nums; pointer-events: none; }
article > .actions > .arrows > .score:only-child { margin: 0; padding: 0 9px; }
article > .actions > .arrows > .pos { color: var(--g-credit); }
article > .actions > .arrows > .neg { color: var(--danger); }
article > .actions > .arrows > button:is(.busy, :active) { translate: 0 1px; }
@media (hover: hover) {
  article > .actions > .arrows > button:not(.on):hover > .ic { box-shadow: 0 0 0 4px var(--tint); }
}
@media (max-width: 30em) { article > .actions :is(.reply, .repost) .w { display: none; } } /* narrow, or big text: Reply and Repost go to their emoji */
/* A drop's ⋯ and 🔁 menus (owner, 2026-10-31: their items at least as large as the row's buttons): each item a 48 pixel tall line across the menu, its words 17px and its emoji, its first letter, 20px, the row's, without the page's font-size-adjust (which shrinks emoji in WebKit, see below). A nested fold's summary (👥 Take my name off) is a line like the rest, not the ⋯ square, and the button inside it (Yes, take it off), which starts with a word, keeps its first letter plain */
article > .actions :is(.more, .rp) ul { min-width: 13em; padding: 6px; font-size: 17px; }
article > .actions :is(.more, .rp) li { padding: 0; }
article > .actions :is(.more, .rp) li :is(a, button, summary) { display: block; width: 100%; min-height: 48px; height: auto; padding: 12px; border-radius: 8px; font: inherit; line-height: 24px; letter-spacing: normal; text-align: left; }
article > .actions :is(.more, .rp) :is(li > a, li > form > button, li > details > summary)::first-letter { font-size: 20px; font-size-adjust: none; }
article > .actions :is(.more, .rp) li.muted { padding: 8px 12px; }
article > .actions :is(.more, .rp) li .off form { margin: 0 0 0 1.5em; }
@media (hover: hover) { article > .actions :is(.more, .rp) li :is(a, button, summary):hover { background: var(--raise); } }
/* The drop card's emoji keep their own size: body's font-size-adjust (.51) scales the emoji font by its x-height, which shrinks emoji to about half in WebKit, Safari's engine, and grows them a little in Chromium */
:is(.reacts .e, .reacts .fly, article > .actions .ic, .hoverbar :is(button, a), .picker .pk-set button > span, .picker .pk-say > span:first-child, .whocard .l > span, .rx-tabs .e, .person .badge, .tray button, .lpmenu button > span:last-child, .askwhy > span:first-child, .tip) { font-size-adjust: none; }
/* The line of reactions: keys in the list's order, a little more room where a group starts. Yours: the mine fill, a ring and its count in the mine color */
.reacts { display: flex; flex-wrap: wrap; align-items: center; column-gap: 6px; margin: 10px 0 0; font-size: .82em; }
.reacts > :is(button, a) { display: inline-flex; align-items: center; min-height: 44px; color: var(--text); -webkit-user-select: none; user-select: none; -webkit-touch-callout: none; } /* a 44px tall tap area round a 32px key; held down, it opens who gave it (row.js), not a selection */
.reacts > .gs { margin-left: 8px; }
.reacts .k { position: relative; display: inline-flex; align-items: center; gap: 6px; height: 32px; padding: 0 11px 0 8px; border-radius: 999px; background: var(--raise); box-shadow: 0 2px 0 var(--lip); white-space: nowrap; transition: translate .08s, box-shadow .08s, background-color .12s; }
.reacts .e { font-size: 18px; line-height: 1; }
.reacts .n { position: relative; display: inline-block; color: var(--text); font-weight: bold; font-variant-numeric: tabular-nums; }
.reacts > .on .k { background: var(--mine-bg); box-shadow: 0 2px 0 var(--mine-lip), inset 0 0 0 2px var(--mine); }
.reacts > .on .n { color: var(--mine-text); }
@media (hover: hover) { .reacts > :is(button, a):not(.on):hover .k { background: var(--raise2); box-shadow: 0 2px 0 var(--lip), 0 0 0 1.5px color-mix(in srgb, var(--mine) 45%, transparent); } .reacts > :is(button, a):hover { color: var(--text); } }
.reacts > :is(.busy, :active) .k { translate: 0 2px; box-shadow: none; } /* pressed, it sinks and stays down until the server answers (row.js) */
.reacts > .on:is(.busy, :active) .k { box-shadow: inset 0 0 0 2px var(--mine); }
.reacts > .busy { cursor: progress; }
/* the who line under the chips: faces, two names, See who */
.wholine { display: flex; align-items: center; gap: 0 8px; margin: 6px 0 0; font-size: .78em; color: var(--muted); white-space: nowrap; }
.wholine .t { min-width: 0; overflow: hidden; text-overflow: ellipsis; } /* one line: the names give way, never See who */
.wholine a { flex: none; }
.wholine .faces { display: flex; flex: none; }
.wholine .avatar { width: 22px; height: 22px; margin: 0; font-size: 11px; box-shadow: 0 0 0 2px var(--card); }
.wholine .avatar + .avatar { margin-left: -6px; }
.wholine b { color: var(--text); }
.wholine a { position: relative; z-index: 1; text-decoration: underline; text-decoration-thickness: 1px; text-underline-offset: 3px; }
@media (max-width: 30em) { .wholine .w { display: none; } } /* narrow: no "reacted", no "n privately" (Who reacted says it) */
/* the pill a drop shows inside its top right while pointed at, as Discord's (The pill): only where a fine pointer hovers, after 120ms, hidden by visibility so nothing moves; the lines at the card's top leave it room */
.hoverbar { display: none; }
@media (hover: hover) and (pointer: fine) {
  .hoverbar { position: absolute; z-index: 3; top: 12px; right: 12px; display: flex; align-items: center; gap: 1px; padding: 3px; font-size: 1rem; background: var(--pop); border: 1px solid var(--pop-line); border-radius: 10px; box-shadow: 0 2px 6px rgb(0 0 0 / .25); visibility: hidden; opacity: 0; transition: opacity .1s, visibility 0s .1s, box-shadow .15s; }
  article:is(:hover, :focus-within, :has(details[open])) > .hoverbar { visibility: visible; opacity: 1; transition: opacity .1s .12s, visibility 0s .12s, box-shadow .15s; }
  .hoverbar:hover { box-shadow: 0 6px 18px rgb(0 0 0 / .45); }
  article:has(> .hoverbar) > :is(.by, .meta) { padding-right: 252px; }
}
.hoverbar :is(button, a) { position: relative; display: grid; place-items: center; width: 34px; height: 32px; padding: 0; border-radius: 7px; font-size: 19px; line-height: 1; color: var(--muted); }
.hoverbar :is(button, a):hover { background: var(--raise2); color: var(--muted); }
.hoverbar :is(button, a):active { translate: 0 1px; }
.hoverbar .ic { font-size: inherit; }
.hoverbar :is(.w, .c) { display: none; }
.hoverbar .quick { display: flex; gap: 1px; margin-right: 3px; padding-right: 3px; border-right: 1px solid var(--pop-line); }
.hoverbar .on::after { content: ""; position: absolute; inset: 3px; border-radius: 6px; box-shadow: inset 0 0 0 1.5px var(--mine); }
.hoverbar [data-open="more"] { font: bold 17px/1 system-ui, sans-serif; }
.tip { position: fixed; z-index: 40; padding: 6px 10px; translate: -50% -100%; font-size: 13px; line-height: 1.3; white-space: nowrap; color: #fff; background: #0f0a13; border-radius: 7px; box-shadow: 0 4px 12px rgb(0 0 0 / .4); pointer-events: none; }
.tip::after { content: ""; position: absolute; left: 50%; bottom: -5px; width: 10px; height: 10px; translate: -50%; rotate: 45deg; background: inherit; }
.tip em { font-size: 12px; font-style: normal; color: var(--hue); }
.tip[hidden] { display: none; }
/* 🙂's picker (Picking), after Discord's: Find and ✕, what a press does, then Your usual and the four groups, each its name in its hue and its tiles, all at once; the strip for the tile pointed at.
   Over the row's 🙂, or under it with no room (.down, row.js); under the pill's, set there by row.js. Its classes start pk-: .tiles, .strip and .find are taken */
.react > .picker { position: absolute; z-index: 4; right: 0; bottom: 100%; width: min(520px, calc(100vw - 24px)); margin: 6px 0; overflow: hidden; text-align: left; font-size: 1rem; color: var(--text); background: var(--pop); border: 1px solid var(--pop-line); border-radius: 14px; box-shadow: 0 16px 40px rgb(0 0 0 / .55), 0 2px 6px rgb(0 0 0 / .3); }
.react > .picker.down { top: 100%; bottom: auto; }
.picker [hidden] { display: none !important; } /* what Find leaves out */
.picker .pk-top { display: flex; align-items: center; gap: 8px; padding: 12px 12px 6px; }
.picker .pk-find { flex: 1; width: auto; height: 36px; margin: 0; padding: 0 10px; font-size: .9em; border-radius: 8px; }
.picker .pk-x { display: grid; place-items: center; flex: none; width: 32px; height: 32px; border-radius: 50%; color: var(--muted); font: 18px/1 system-ui, sans-serif; }
.picker .pk-title { display: none; }
.picker .pk-sub { margin: 0; padding: 0 14px 8px; font-size: .8em; color: var(--muted); }
.picker :is(.pk-touch, .pk-choose), .picker.choosing :is(.pk-fine, .pk-touch, .g-you) { display: none; }
.picker.choosing .pk-choose { display: inline; }
.picker .pk-choose button { padding: 2px 10px; margin-left: 4px; border-radius: 999px; font-weight: bold; color: var(--text); background: var(--raise2); }
.picker .pk-choose .pk-save, .picker .pk-choose .pk-save:hover { color: var(--on); background: var(--accent); }
.picker kbd { padding: 1px 5px; font: 11px system-ui, sans-serif; border: 1px solid var(--pop-line); border-radius: 4px; }
.picker .pk-body { display: grid; gap: 8px; padding: 4px 12px 10px 0; }
.picker .pk-g { display: grid; grid-template-columns: 100px 1fr; align-items: start; padding-left: 11px; border-left: 3px solid transparent; }
.picker .pk-g:hover { border-left-color: var(--hue); }
.gl { display: flex; align-items: center; gap: 7px; padding-top: 10px; font-size: .8em; font-weight: bold; line-height: 1.2; color: var(--hue); }
.gl::before { content: ""; flex: none; width: 8px; height: 8px; border-radius: 50%; background: var(--hue); }
.picker .pk-set { display: grid; grid-template-columns: repeat(5, minmax(0, 72px)); gap: 6px; }
.picker .pk-set button { display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 4px; height: 64px; padding: 0 2px; font-size: 11.5px; line-height: 1.1; text-align: center; color: var(--muted); background: var(--raise); border-radius: 10px; box-shadow: inset 0 -2px 0 color-mix(in srgb, var(--hue) 55%, transparent); transition: scale .12s, background-color .12s; }
.picker .pk-set button > span { font-size: 25px; line-height: 1; }
.picker .pk-set button > small { font-size: inherit; }
.picker .pk-set button:focus-visible, .picker .pk-set button.held { background: var(--raise2); }
@media (hover: hover) {
  .picker .pk-set button:hover { color: var(--hover); background: var(--raise2); scale: 1.06; }
  .picker .pk-choose button:hover { color: var(--hover); }
}
.picker .pk-set button:active { translate: 0 1px; }
.picker .pk-set .on, .picker.choosing .pk-set .picked { color: var(--mine-text); background: var(--mine-bg); box-shadow: inset 0 0 0 2px var(--mine); }
.picker.choosing .pk-set .on:not(.picked) { color: var(--muted); background: var(--raise); box-shadow: inset 0 -2px 0 color-mix(in srgb, var(--hue) 55%, transparent); } /* choosing, only the three picked light */
.picker .pk-set .pk-pick3 { background: none; border: 1.5px dashed var(--pop-line); box-shadow: none; }
.picker .pk-pick3 > span { font: 20px/1 system-ui, sans-serif; }
.picker .pk-say { display: flex; align-items: center; gap: 14px; min-height: 76px; margin: 0; padding: 12px 16px; background: color-mix(in srgb, var(--pop), #000 10%); border-top: 1px solid var(--pop-line); }
.picker .pk-say > span:first-child { font-size: 38px; line-height: 1; }
.picker .pk-say em { margin-left: 6px; font-size: 11px; font-style: normal; font-weight: bold; letter-spacing: .05em; text-transform: uppercase; color: var(--hue); }
.picker .pk-say small { display: block; margin-top: 3px; font-size: .85em; color: var(--muted); }
@media (max-width: 599px) { /* a sheet from the bottom over the dimmed page: the drop's name for a title, no Find, so no keyboard comes up */
  .react > .picker { position: fixed; top: auto; left: 0; right: 0; bottom: 0; width: auto; max-height: 88vh; overflow-y: auto; overscroll-behavior: contain; margin: 0; padding: 0 14px calc(18px + env(safe-area-inset-bottom)); border-width: 1px 0 0; border-radius: 18px 18px 0 0; box-shadow: 0 -12px 40px rgb(0 0 0 / .5); }
  .picker::before { content: ""; display: block; width: 40px; height: 5px; margin: 8px auto 10px; border-radius: 3px; background: var(--pop-line); } /* its grab handle */
  .picker .pk-top { display: none; }
  .picker .pk-title { display: block; margin: 0; overflow: hidden; font: bold 1.15em/1.3 var(--head); text-overflow: ellipsis; white-space: nowrap; }
  .picker .pk-sub { padding: 3px 0 10px; font-size: .85em; }
  .picker .pk-fine { display: none; }
  .picker:not(.choosing) .pk-touch { display: inline; }
  .picker .pk-body { display: block; padding: 0; }
  .picker .pk-g { display: block; padding: 0; border: 0; }
  .picker .gl { padding: 4px 0 8px; font-size: .95em; }
  .picker .pk-set { grid-template-columns: repeat(5, minmax(0, 1fr)); margin-bottom: 10px; }
  .picker .pk-set button { height: 70px; }
  .picker .pk-set button > span { font-size: 27px; }
  .picker .pk-say { min-height: 0; padding: 10px 12px; border: 1px solid var(--pop-line); border-radius: 12px; }
  .picker .pk-say > span:first-child { font-size: 30px; }
  .react[open]::after { content: ""; position: fixed; inset: 0; z-index: 3; pointer-events: none; background: var(--scrim); } /* the page dims behind the sheet; a tap on it still closes it (menus.js) */
}
/* the who card, pointing at a chip on a computer (row.js): the reaction big, its group and meaning; who gave it, you first; a bridge over the gap to the chip */
.whocard { position: fixed; z-index: 6; display: grid; grid-template-columns: 140px 1fr; width: min(380px, calc(100vw - 16px)); font-size: 1rem; color: var(--text); background: var(--pop); border: 1px solid var(--pop-line); border-radius: 14px; box-shadow: 0 16px 40px rgb(0 0 0 / .55), 0 2px 6px rgb(0 0 0 / .3); }
.whocard::before { content: ""; position: absolute; left: 0; right: 0; top: 100%; height: 16px; } /* the bridge */
.whocard.below::before { top: auto; bottom: 100%; }
.whocard::after { content: ""; position: absolute; left: var(--ax, 40px); bottom: -7px; width: 12px; height: 12px; rotate: 45deg; background: var(--pop); border: solid var(--pop-line); border-width: 0 1px 1px 0; }
.whocard.below::after { bottom: auto; top: -7px; border-width: 1px 0 0 1px; }
.whocard .l { padding: 16px 14px; text-align: center; border-right: 1px solid var(--pop-line); }
.whocard .l > span { display: block; font-size: 44px; line-height: 1.1; }
.whocard .l b { display: block; margin-top: 6px; }
.whocard .l .gl { justify-content: center; padding-top: 6px; font-size: 11px; }
.whocard .l small { display: block; margin-top: 8px; font-size: 12.5px; line-height: 1.35; color: var(--muted); }
.whocard ul { margin: 0; padding: 10px 6px 4px; list-style: none; }
.whocard li { display: flex; align-items: center; gap: 9px; padding: 5px 8px; font-size: 14.5px; border-radius: 8px; }
.whocard li .avatar { width: 26px; height: 26px; margin: 0; font-size: 13px; }
.whocard li.you { color: var(--mine-text); background: var(--mine-bg); }
.whocard li small { color: var(--muted); }
.whocard .foot { grid-column: 2; padding: 6px 14px 12px; font-size: 14px; }
/* Who reacted (coponder.md, Reactions, Reactions), as Discord's window: a rail of All and each reaction, one row a person; on a computer in a panel over the drop (row.js) */
.rxback { display: block; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; } /* ← the drop's first line */
.rx-sum { margin: -8px 0 12px; color: var(--muted); }
.rx { display: grid; grid-template-columns: 190px minmax(0, 1fr); align-items: start; }
.rx-tabs { display: flex; flex-direction: column; gap: 2px; padding: 8px 8px 8px 0; border-right: var(--bw) solid var(--border); }
.rx-tabs a { position: relative; display: flex; align-items: center; gap: 8px; min-height: 40px; padding: 7px 10px 7px 12px; font-size: .9em; color: var(--text); white-space: nowrap; border-radius: 8px; }
.rx-tabs a::before { content: ""; position: absolute; left: 0; top: 9px; bottom: 9px; width: 3px; border-radius: 3px; background: var(--hue, transparent); }
.rx-tabs .e { font-size: 18px; }
.rx-tabs b { margin-left: auto; color: var(--muted); font-variant-numeric: tabular-nums; }
.rx-tabs a:hover { color: var(--text); background: var(--raise); }
.rx-tabs .on, .rx-tabs .on:hover { background: var(--raise2); }
.rx-who { padding: 4px 0 4px 10px; min-width: 0; }
.people { margin: 0; padding: 0; list-style: none; }
.people > li { padding: 10px 8px; }
.people > li + li { border-top: 1px solid var(--border); }
.person { display: grid; grid-template-columns: 36px minmax(0, 1fr) auto; align-items: start; gap: 12px; }
.person.you { background: var(--mine-bg); border-radius: 10px; }
.person.you + li { border-top-color: transparent; }
.person .rface { position: relative; display: block; width: 36px; height: 36px; }
.person .rface .avatar { width: 36px; height: 36px; margin: 0; }
.person .badge { position: absolute; right: -5px; bottom: -4px; display: grid; place-items: center; width: 19px; height: 19px; font-size: 12px; line-height: 1; background: var(--pop); border-radius: 50%; box-shadow: 0 0 0 2px var(--pop); }
.person .author { font-weight: bold; color: var(--text); }
.person .gave { margin-top: 2px; font-size: .9em; }
.person .ctx { margin-top: 4px; font-size: .9em; color: var(--muted); }
.person .ctx q { font-style: italic; color: var(--text); }
.person form { margin: 0; }
.person .fb { height: 32px; padding: 0 14px; font-size: .9em; font-weight: bold; white-space: nowrap; color: var(--text); background: var(--raise2); border-radius: 999px; box-shadow: none; }
.person .fb.primary { color: var(--on); background: var(--accent); }
.person .fb.done { font-weight: normal; color: var(--muted); background: none; box-shadow: inset 0 0 0 1.5px var(--pop-line); }
.rxpanel { width: min(660px, calc(100vw - 24px)); height: min(560px, calc(100vh - 48px)); padding: 0; overflow: hidden; color: var(--text); background: var(--pop); border: 1px solid var(--pop-line); border-radius: 14px; box-shadow: 0 16px 40px rgb(0 0 0 / .55); pointer-events: auto; } /* auto: an open ⋯ has just taken the page's taps away (menus.js) */
.rxpanel::backdrop { background: var(--scrim); }
.rxpanel > div { position: relative; display: flex; flex-direction: column; height: 100%; }
.rxpanel .rxhead { display: flex; flex-wrap: wrap; align-items: baseline; column-gap: 10px; padding: 14px 56px 14px 16px; border-bottom: 1px solid var(--pop-line); }
.rxpanel h1 { margin: 0; font-size: 1.15em; }
.rxpanel .rx-sum { margin: 0; font-size: .9em; }
.rxpanel .rxback { flex-basis: 100%; min-height: 0; margin: 2px 0 0; font-size: .9em; color: var(--muted); }
.rxpanel .x { position: absolute; top: 6px; right: 6px; width: 44px; height: 44px; padding: 0; color: var(--muted); border-radius: 50%; font: 18px/1 system-ui, sans-serif; }
.rxpanel .x:hover { background: var(--raise); }
.rxpanel .rx { flex: 1; min-height: 0; align-items: stretch; }
.rxpanel :is(.rx-tabs, .rx-who) { overflow-y: auto; overscroll-behavior: contain; scrollbar-width: thin; scrollbar-color: var(--pop-line) transparent; }
.rxpanel .rx-tabs { padding-left: 8px; background: color-mix(in srgb, var(--pop), #000 10%); border-right-color: var(--pop-line); }
.rxpanel .rx-who { padding-right: 8px; }
.rxpanel .people > li + li { border-top-color: var(--pop-line); }
@media (max-width: 599px) { /* a sheet from 120 pixels under the top; the rail a row of pills, only with 10 or more */
  .rx { display: block; }
  .rx-tabs { display: none; flex-direction: row; gap: 6px; overflow-x: auto; scrollbar-width: none; padding: 0 0 10px; border: 0; border-bottom: var(--bw) solid var(--border); }
  .rx-tabs.many { display: flex; }
  .rx-tabs a { flex: none; min-height: 36px; padding: 0 12px; background: var(--raise); border-radius: 999px; }
  .rx-tabs a::before, .rx-tabs .w { display: none; }
  .rx-tabs b { margin: 0; color: inherit; font-weight: normal; }
  .rx-tabs .on, .rx-tabs .on:hover { color: var(--bg); background: var(--text); font-weight: bold; }
  .rx-who { padding: 0; }
  .rxpanel { width: 100%; max-width: 100%; height: calc(100% - 120px); max-height: none; margin: auto 0 0; border-width: 1px 0 0; border-radius: 18px 18px 0 0; }
  .rxpanel > div::before { content: ""; display: block; flex: none; width: 40px; height: 5px; margin: 8px auto 0; border-radius: 3px; background: var(--pop-line); }
  .rxpanel .rxhead { padding: 8px 56px 10px 14px; border: 0; }
  .rxpanel .rx-tabs { margin: 0 14px; background: none; }
  .rxpanel .rx-who { padding: 0 8px; }
}
/* a phone's long press (Long press): the drop lifts over the dimmed page, the tray over it, what you can do under it */
.lp { position: fixed; inset: 0; z-index: 7; background: var(--scrim); }
article.lifted { z-index: 8; scale: 1.02; box-shadow: 0 18px 50px rgb(0 0 0 / .6); transition: scale .15s; }
article.pressing { -webkit-touch-callout: none; -webkit-user-select: none; user-select: none; }
.tray { position: fixed; z-index: 9; display: flex; align-items: center; gap: 2px; padding: 6px; background: var(--pop); border: 1px solid var(--pop-line); border-radius: 999px; box-shadow: 0 10px 30px rgb(0 0 0 / .55); }
.tray button { display: grid; place-items: center; width: 48px; height: 48px; padding: 0; font-size: 29px; line-height: 1; border-radius: 50%; }
.tray .on { background: var(--mine-bg); box-shadow: inset 0 0 0 2px var(--mine); }
.tray .plus { width: 50px; font: bold 15px system-ui, sans-serif; color: var(--text); background: var(--raise2); }
.lpmenu { position: fixed; z-index: 9; width: 250px; margin: 0; padding: 0; overflow: hidden; list-style: none; background: var(--pop); border: 1px solid var(--pop-line); border-radius: 14px; box-shadow: 0 10px 30px rgb(0 0 0 / .55); }
.lpmenu button { display: flex; justify-content: space-between; align-items: center; width: 100%; min-height: 44px; padding: 10px 16px; font-size: 1.05em; text-align: left; color: var(--text); }
.lpmenu li + li { border-top: 1px solid var(--pop-line); }
.lpmenu li.sep { border-top: 6px solid color-mix(in srgb, var(--pop), #000 30%); }
.lpmenu .red { color: var(--danger); }
/* motion, after your own press only (Motion): the count rolls, a ring spreads, the emoji floats up; nothing under reduced motion */
.reacts .n.roll { overflow: hidden; height: 1.3em; line-height: 1.3em; vertical-align: middle; }
.reacts .n.roll > i { display: block; font-style: normal; animation: .2s ease-out both; }
.reacts .n.roll > i + i { position: absolute; inset: 0; }
.reacts .n.up > i:first-child { animation-name: rollin; } .reacts .n.up > i + i { animation-name: rollout; }
.reacts .n.down > i:first-child { animation-name: rollin-down; } .reacts .n.down > i + i { animation-name: rollout-down; }
@keyframes rollin { from { translate: 0 100%; } } /* up: the new number comes in from below, the old leaves at the top */
@keyframes rollout { to { translate: 0 -100%; opacity: 0; } }
@keyframes rollin-down { from { translate: 0 -100%; } } /* down: the other way */
@keyframes rollout-down { to { translate: 0 100%; opacity: 0; } }
.reacts .k.plip::after { content: ""; position: absolute; inset: -1px; border-radius: 999px; box-shadow: 0 0 0 2px var(--mine); animation: plip .35s ease-out forwards; pointer-events: none; }
@keyframes plip { from { opacity: .9; } to { opacity: 0; scale: 1.4; } }
.reacts .fly { position: absolute; left: 8px; top: 7px; font-size: 18px; line-height: 1; pointer-events: none; opacity: 0; animation: fly .4s .25s ease-out; }
@keyframes fly { from { opacity: 1; } to { opacity: 0; translate: 0 -24px; } }
@media (prefers-reduced-motion: reduce) {
  article[id^="p"], .reacts .k, .hoverbar, .picker .pk-set button, article.lifted { transition: none !important; }
  .reacts > :is(.busy, :active) .k, .picker .pk-set button:is(:hover, :focus-visible, :active), article.lifted { translate: none; scale: none; }
  .reacts .n.roll > i, .reacts .k.plip::after, .reacts .fly { animation: none; display: none; }
  .reacts .n.roll > i:first-child { display: block; }
}
/* the Discredit nudge at the bottom left (Motion): say why, or undo */
.askwhy { position: fixed; z-index: 8; left: 20px; bottom: 20px; display: grid; grid-template-columns: auto minmax(0, 1fr) auto; align-items: center; gap: 11px; width: min(356px, calc(100vw - 40px)); padding: 12px 12px 12px 16px; overflow: hidden; font-size: .9em; color: var(--text); background: var(--pop); border: 1px solid var(--pop-line); border-radius: 12px; box-shadow: 0 10px 30px rgb(0 0 0 / .5); }
.askwhy::before { content: ""; position: absolute; left: 0; top: 0; bottom: 0; width: 4px; background: var(--g-dis); }
.askwhy[hidden] { display: none; }
.askwhy > span:first-child { font-size: 26px; line-height: 1; }
.askwhy > span + span { display: flex; gap: 6px; }
.askwhy button { height: 32px; padding: 0 12px; font-weight: bold; color: var(--text); background: var(--raise2); border-radius: 999px; }
.askwhy button + button { background: none; box-shadow: inset 0 0 0 1.5px var(--pop-line); }
@media (max-width: 599px) { .askwhy { left: 10px; right: 10px; bottom: 90px; width: auto; } } /* above the bar of places */
.thread, .thread ul { list-style: none; margin: 0; padding: 0; }
.thread ul { padding-left: 12px; border-left: 2px solid var(--border); }
.focus { font-size: 1.1em; }
.titlebar { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 12px; }
.titlebar .primary, .titlebar .inside { flex: none; } /* ＋ New pond and a pond's ＋ New folder or ＋ New pond stay one line beside a long name, which wraps */
.titlebar h1 { flex: 1 1 6em; max-width: 100%; overflow-wrap: break-word; } /* whole words (body's anywhere let the pill squeeze it to a letter a line); with less than 6em beside the pill, the pill goes under it */
.titlebar .inside { padding: 4px 12px; border: var(--bw) solid var(--field); border-radius: 999px; font-size: .9em; } /* a chip, not the page's biggest button: a pond inside is a later move */
.tabs, .places, .users li { padding: 8px 0; border-bottom: var(--bw) var(--dash) var(--border); }
.profile .head { display: flex; gap: 16px; align-items: flex-start; }
.profile .head .avatar { flex: none; margin: 0; }
.profile h1 { margin: 4px 0 0; }
.trail { margin: 4px 0 0; } /* "in My Book" above a pond inside it: the way back out, close to its name */
.profile .head p { margin: 2px 0 8px; }
.pnote { margin: 12px 0 0; padding: 8px 12px; border: var(--bw) dashed var(--border); border-radius: 10px; } /* your private note on someone: dashed, like a private drop */
details.pnote:not([open]) { padding: 0; border: 0; }
.pnote p { margin: 0 0 4px; }
.pnote .said { white-space: pre-line; overflow-wrap: anywhere; }
.pnote:has(details[open]) .said { display: none; } /* editing: the text is in the box, not twice */
.pnote textarea { field-sizing: content; margin: 4px 0 8px; } /* grows with the note, as the box where you write a drop does */
.profile > div.meta { margin: 1em 0; } /* a pond's moderators and bans: a div, since their buttons are forms */
.users { list-style: none; padding: 0; }
#people li { display: flex; align-items: center; gap: 12px; } /* Ocean's People: Follow on the right of each row, never under the name */
#people li > div { flex: 1; min-width: 0; }
#people .line { margin: 2px 0 0; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; } /* their newest drop, one line, cut with … on a phone */
.excerpt { white-space: pre-line; } /* a notification's drop words: a heading, a list's items and paragraphs keep their own lines */
.error, .removed { color: var(--danger); font-weight: bold; font-style: normal; }
.pager { padding: 12px 0; }
footer { padding: 24px 0; color: var(--muted); }
.device { margin: 12px 0; padding: 0 16px; background: var(--card); border: var(--bw) solid var(--border); border-radius: 14px; } /* 📲 Get the app: a box a device, the visitor's open */
.device > summary { padding: 12px 0; font-weight: bold; cursor: pointer; }
.device ol { margin: 0 0 12px; padding-left: 1.4em; }
.device li { margin: 6px 0; }
.inapp { display: none; }
@media (display-mode: standalone), (display-mode: fullscreen) { .getapp { display: none; } .inapp { display: block; } } /* inside the installed app: iOS calls a standalone app fullscreen */
.avatar { width: 40px; height: 40px; border-radius: 50%; vertical-align: middle; margin-right: 8px; object-fit: cover; }
.avatar.big { width: 96px; height: 96px; }
.face .new { image-orientation: none; } /* the picture just picked, before Save, drawn as the server keeps its pixels: without the camera's turn */
.avatar.none { display: inline-flex; align-items: center; justify-content: center; background: var(--border); font-size: 22px; }
.avatar.big.none { font-size: 52px; }
.images { display: grid; grid-template-columns: 1fr 1fr; gap: 4px; margin: 8px 0; } /* a picture across the column: its sizes in templates/post.html is the column's width (body and article padding), so change both */
.images.n1 { grid-template-columns: 1fr; }
.images.n1 img, .images.n1 video { width: auto; max-width: 100%; height: auto; object-fit: contain; } /* never above its own size */
.images:is(.n1, .stack) img[srcset] { width: 100%; } /* one with a smaller copy is wider than the column, and width: auto would take its sizes (.85 on a phone) for its width */
.images img.little, .tile img.little, .shelf .grid img.little { object-fit: scale-down; } /* smaller than its cell: at its own size, in the middle, not blown up to cover it */
.images img, .images video { width: 100%; height: 100%; max-height: 500px; object-fit: cover; border-radius: 8px; display: block; }
.images.n3 > :first-child { grid-row: span 2; }
/* grids of two to four keep their shape whatever the pictures, so little (core_render.go) knows each cell's box: two 2 by 1, three the same with its first cell the height of both beside it, four 3 by 2 */
.images:is(.n2, .n3) { aspect-ratio: 2 / 1; grid-template-rows: 1fr; }
.images.n3 { grid-template-rows: 1fr 1fr; }
.images.n4 { aspect-ratio: 3 / 2; grid-template-rows: 1fr 1fr; }
.images:is(.n2, .n3, .n4) > * { min-height: 0; }
.images:is(.n2, .n3, .n4) :is(img, video) { max-height: none; }
.images a, .images > span { position: relative; } /* a preview's pictures are no links */
/* ALT, small on a dark pill: a described picture's badge, as Bluesky and X mark one (its words are the picture's alt text, and its tooltip), and a picture tile's ALT in the box */
:is(.images .altb, .alt summary) { padding: 0 5px; border-radius: 6px; background: #000b; color: #fff; font-size: .65em; font-weight: bold; line-height: 1.7; }
.images .altb { position: absolute; left: 6px; bottom: 6px; }
.images .rest { position: absolute; inset: 0; display: flex; align-items: center; justify-content: center; border-radius: 8px; background: #0008; color: #fff; font-size: 2em; }
.images.stack { grid-template-columns: 1fr; } /* a comic's page: every picture whole, one under another */
.images.stack img, .images.stack video { width: auto; max-width: 100%; max-height: none; }
details.hid { margin: 12px 0; } /* a drop with a tag you hide: one dashed line, its card in place once opened */
details.hid > summary, p.unhide > a { display: block; list-style: none; cursor: pointer; padding: 12px 16px; border: var(--bw) dashed var(--border); border-radius: 14px; color: var(--muted); } /* p.unhide: the same line where a page turned to the drop (foldTurned) */
details.hid > summary::-webkit-details-marker { display: none; }
:is(details.hid > summary, .unhide) b { color: var(--link); font-weight: normal; }
p.unhide { margin: 12px 0; }
.lightbox :is(a.unhide, .pfold > summary) { padding: 14px 20px; border: 1px dashed #ffffff40; border-radius: 14px; color: #a9a4b0; } /* the picture viewer's fold, a drop's or one picture's, on its dark stage */
.lightbox :is(.unhide, .pfold) b { color: #e8e6ea; }
.lightbox :is(a.unhide, .pfold > summary):hover { color: var(--hover); }
.lightbox .pfold > summary { display: block; list-style: none; cursor: pointer; }
.lightbox .pfold > summary::-webkit-details-marker { display: none; }
.lightbox .pfold[open] > summary { display: none; } /* shown: the picture alone, as any */
.images .pfold, .tile .pfold { display: flex; align-items: safe center; justify-content: center; box-sizing: border-box; height: 100%; padding: 12px; border: var(--bw) dashed var(--border); border-radius: 8px; color: var(--muted); text-align: center; overflow: hidden; } /* a picture with a tag the viewer hides, folded alone (Hidden tags): its place a dashed line, a tap from the picture viewer's Show */
.images:is(.n1, .stack) .pfold { min-height: 120px; } /* alone, a band; in a grid, its cell */
.tile .pfold { flex-direction: column; gap: 2px; padding: 6px; border: 0; font-size: .8em; line-height: 1.2; overflow-wrap: anywhere; } /* the tile's own frame; 🙈 over the #tag alone, small and wrapping so a narrow tile in big text still shows it whole ("Hidden:" in its title and name) */
.tile .pfold > span { max-width: 100%; padding: 0; } /* not a tile of words' padding (.tile span) */
details.hid[open] > summary { display: none; }
details.hid > article { margin: 0; }
.hidetag, .taglock { display: flex; flex-wrap: wrap; align-items: center; gap: 8px 12px; margin: 0 0 12px; } /* Search: 🙈 Hide #tag, or why a hidden tag's drops aren't there; the tag history's 🔒 Lock on and off, for admins */
.hidetag p { margin: 0; }
:is(.hidetag, .taglock) .pill { min-height: 44px; padding: 0 16px; border: var(--bw) solid var(--field); border-radius: 999px; }
.taglock select { width: auto; min-height: 44px; }
.taglock input { flex: 1 1 8em; width: auto; min-width: 0; min-height: 44px; }
.taglog form.inline { margin: 0; } /* the tag history's ↩ Undo and Hide: the · between them is its gap */
.requests { list-style: none; padding: 0; } /* /tag-requests: each request a row, as a list of people's, but only its own row: its drop's lists and Share keep a feed's look */
.requests > li { padding: 8px 0; border-bottom: var(--bw) var(--dash) var(--border); }
/* 18+, to a reader who hides it: frosted as on Discord, each picture blurred from its veil (a few pixels: the
   picture itself waits, lazy, in the closed details), laid out as the pictures would be, a pill in the middle.
   One tap shows them for good: open, the summary goes, as Discord, X and Reddit have no hide button either */
details.adult { margin: 8px 0; }
details.adult > summary, a.veiled { display: block; position: relative; list-style: none; cursor: pointer; } /* a.veiled: the picture page's, a link to it shown */
details.adult > summary::-webkit-details-marker { display: none; }
details.adult[open] > summary { display: none; }
:is(details.adult > summary, a.veiled):has(> .frost.n1) { width: fit-content; max-width: 100%; } /* one picture in its own shape: the pill in its middle */
.frost { display: grid; gap: 4px; }
.frost > span { position: relative; display: block; overflow: hidden; border-radius: 8px; background: #3a3040; } /* the colour while the veil loads, or if it can't */
.frost img { display: block; object-fit: cover; filter: blur(18px) saturate(1.3) brightness(.85); transform: scale(1.25); } /* scaled past the blur's soft edge */
.frost:not(.n1) img { width: 100%; height: 100%; }
.frost.n1 img { max-width: 100%; height: auto; max-height: 500px; } /* as wide as the picture (its width), never past the column */
.frost:is(.n2, .n3) { grid-template-columns: 1fr 1fr; grid-template-rows: 1fr; aspect-ratio: 2 / 1; }
.frost.n3 { grid-template-rows: 1fr 1fr; }
.frost.n3 > :first-child { grid-row: span 2; }
.frost.n4 { grid-template-columns: 1fr 1fr; grid-template-rows: 1fr 1fr; aspect-ratio: 3 / 2; }
.frost .bar { height: 64px; background: linear-gradient(110deg, #4a3656, #2c2134 60%, #3d2c47); } /* a link card, or a video without its picture */
.pill18 { position: absolute; inset: 0; width: fit-content; height: fit-content; margin: auto; display: inline-flex; align-items: center; gap: 7px; padding: 9px 16px; border-radius: 999px; background: rgb(20 14 26 / .62); -webkit-backdrop-filter: blur(6px); backdrop-filter: blur(6px); box-shadow: 0 0 0 1px rgb(255 255 255 / .18); color: #fff; font: 700 15px/1.2 system-ui, -apple-system, "Segoe UI", sans-serif; white-space: nowrap; }
.pill18 svg { flex: none; width: 18px; height: 18px; fill: none; stroke: currentColor; stroke-width: 2.2; stroke-linecap: round; stroke-linejoin: round; }
.pill18 small { font-size: 1em; font-weight: 600; opacity: .85; }
:is(details.adult > summary, a.veiled):is(:hover, :focus-visible) .pill18 { background: rgb(20 14 26 / .8); box-shadow: 0 0 0 2px var(--accent); }
:is(details.adult > summary, a.veiled):focus-visible { outline: none; } /* the pill's ring shows it */
.film { position: relative; margin: 8px 0; } /* a drop's video: the browser's own player, its length in a corner, as other sites show it */
.film video { display: block; width: 100%; height: auto; max-height: 500px; border-radius: 8px; background: #000; }
.film .len { position: absolute; left: 8px; top: 8px; padding: 1px 7px; border-radius: 6px; background: #000b; color: #fff; font-size: .85em; pointer-events: none; }
.words { white-space: pre-wrap; } /* saved words keep their lines */
/* the picture page: a dark stage the size of the screen, the header out of its way, and
   the drop under it; one figure at a time, the one whose radio is checked, else the
   address's #, else the first; each picture as big as fits, never blown up */
body:has(.lightbox) > header { display: none; }
main:has(> .lightbox) { position: static; padding-top: 100vh; padding-top: 100svh; }
.lightbox { position: absolute; z-index: 3; top: 0; left: 0; right: 0; height: 100vh; height: 100svh; background: #0b0a0e; color: #e8e6ea; }
.lightbox figure { position: absolute; inset: 0; display: none; flex-direction: column; margin: 0; }
.lightbox :checked + figure, .lightbox:not(:has(:checked)) :is(figure:target, figure:has(> .to:target)), .lightbox:not(:has(:checked, :target)) figure:first-of-type { display: flex; }
.lightbox :checked + figure + input + figure, .lightbox:not(:has(:checked)) :is(figure:target, figure:has(> .to:target)) + input + figure, .lightbox:not(:has(:checked, :target)) figure:first-of-type + input + figure { display: flex; visibility: hidden; } /* the next one, laid out unseen, so its lazy picture loads while you look at this one */
.lightbox :focus-visible + figure img, .lightbox :focus-visible + figure video { outline: 2px solid var(--accent); outline-offset: -2px; } /* the radios are hidden */
.lightbox a, .lightbox summary { color: #e8e6ea; }
.lightbox p { margin: 0; }
.lightbox .bar { display: flex; gap: 8px; padding: 8px 10px; }
.lightbox .bar .x { margin-right: auto; }
.lightbox .ctl { flex: none; display: flex; align-items: center; justify-content: center; width: 40px; height: 40px; border-radius: 50%; background: #ffffff1c; font-size: 22px; line-height: 1; cursor: pointer; }
.lightbox .dl svg { width: 20px; height: 20px; fill: none; stroke: currentColor; stroke-width: 2.4; stroke-linecap: round; stroke-linejoin: round; } /* an arrow into a tray, drawn: the emoji ⬇️ is a box of its own */
.lightbox .menu { position: relative; }
.lightbox .menu summary { list-style: none; }
.lightbox .menu summary::-webkit-details-marker { display: none; }
.lightbox .menu :is(ul, p) { position: absolute; top: 46px; right: 0; width: max-content; max-width: min(320px, 100vw - 20px); margin: 0; padding: 8px 14px; list-style: none; border-radius: 12px; background: #1d1b22; font-size: 16px; line-height: 1.45; }
.lightbox .menu li { padding: 4px 0; }
.lightbox .desc { position: static; } /* the picture's description, its writer's, in the bar as a menu: a tap on ALT shows it, as Bluesky's does, under the bar at its right, whatever sits right of ALT */
.lightbox .desc summary { font-size: 13px; font-weight: bold; letter-spacing: .03em; }
.lightbox .desc p { top: 58px; right: 10px; max-height: 60svh; overflow-y: auto; white-space: pre-line; overflow-wrap: anywhere; }
.lightbox .tags { position: static; } /* the picture's tags (Creation tags), under the bar at its right, as ALT's words are */
.lightbox .bar:has(.tags[open]) { z-index: 2; } /* over the side margins' arrows, on a computer */
.lightbox .tags summary { display: flex; align-items: center; gap: 6px; font-size: 19px; }
.lightbox .tags svg { flex: none; width: 1.05em; height: 1.05em; fill: none; stroke: currentColor; stroke-width: 2.2; stroke-linejoin: round; } /* a tag, drawn as ⬇ is: the emoji 🏷️ is a white label on Windows, a box on the dark button, and its count ran into it */
.lightbox .tags:has(b) { width: auto; padding: 0 13px; border-radius: 20px; } /* with how many it has beside it, a pill */
.lightbox .tags summary b { font-size: 15px; }
.lightbox .tagbox { position: absolute; top: 58px; right: 10px; z-index: 2; width: min(340px, 100vw - 20px); max-height: 60svh; overflow-y: auto; padding: 10px 14px 14px; border-radius: 12px; font-size: 16px; line-height: 1.45;
  background: linear-gradient(#1d1b22 40%, #1d1b2200) top / 100% 36px no-repeat local, linear-gradient(#1d1b2200, #1d1b22 60%) bottom / 100% 36px no-repeat local, radial-gradient(farthest-side at 50% 0, #ffffff38, #fff0) top / 100% 14px no-repeat scroll, radial-gradient(farthest-side at 50% 100%, #ffffff38, #fff0) bottom / 100% 14px no-repeat scroll, #1d1b22; scrollbar-width: thin; scrollbar-color: #ffffff40 transparent; } /* scroll shadows, the familiar CSS kind: a glow at an edge with more beyond it, so a long list (big text) shows it scrolls; the local covers hide each at its end. A computer's scrollbar, thin and dark, not a white track */
.lightbox .tagbox :is(ul, p) { position: static; width: auto; max-width: none; margin: 0 0 10px; padding: 0; border-radius: 0; background: none; } /* not the ⋮ menu's floating list */
.lightbox .tagbox .th { display: flex; flex-wrap: wrap; align-items: baseline; gap: 0 10px; margin-bottom: 8px; font-weight: bold; white-space: nowrap; } /* 🏷️ Creation tags, and 🕘 History under it when big text leaves no room beside it */
.lightbox .tagbox .th a { margin-left: auto; min-height: 24px; display: inline-flex; align-items: center; color: #a9a4b0; font-size: .9em; font-weight: normal; } /* 🕘 History, at the right, a tap tall enough */
.lightbox .tagbox .th a:hover { color: var(--hover); }
.lightbox .tagbox li { display: flex; align-items: center; min-width: 0; min-height: 32px; padding: 0; } /* a tag a line, as e621's sidebar (owner, 2026-10-30): + – its name, its count, then 👁️ and ✕ at the right */
.lightbox .tagbox li .nm { flex: 1; min-width: 0; padding: 3px 0; overflow-wrap: anywhere; } /* its name, then its count on the same line: a long name breaks after an _ first (wbr) */
.lightbox .tagbox li .pm { flex: none; width: 22px; padding: 3px 0; text-align: center; color: #a9a4b0; } /* + and –: the search with it, or without it */
.lightbox .tagbox li .pm:hover { color: var(--hover); }
.lightbox .tagbox li .pm + .pm { margin-right: 4px; }
.lightbox .tagbox li .tc { color: #a9a4b0; font-size: .85em; white-space: nowrap; } /* its count, e621's grey 2.4k; not .n, the picture's 1 / 3, which a computer floats over the stage */
.lightbox .tagbox li button { flex: none; min-width: 32px; height: 32px; padding: 0; color: #a9a4b0; font-size: 14px; } /* at least 32px: big text widens it rather than run 👁️ into ✕ */
.lightbox .tagbox li button:hover { color: var(--hover); }
.lightbox .tagbox li .eye { padding-left: 6px; } /* 👁️ or 🙈 ends the line: hide it, or unhide it (Hidden tags); ✕ after it, for who may tag */
.lightbox .tagbox li .eye + button { margin: 0 -6px 0 4px; } /* ✕ a little apart from the 👁️, even in big text */
.lightbox .tagbox ul.x li .eye:last-child { margin-right: 30px; } /* a locked tag has no ✕: its 👁️ stays in the column of the others */
.lightbox .tagbox li.kind { display: block; min-height: 0; padding: 8px 0 2px; color: #a9a4b0; font-size: .85em; font-weight: bold; } /* a category's name over its group, always, as on e621 (Categories) */
.lightbox .tagbox li.kind:first-child { padding-top: 0; }
.tagbox .k-fandom a { color: var(--k-fandom); } /* each category its own color in the 🏷️ panel, as e621's sidebar: sky blue, green, orange-red, gold and teal, apart from each other and from every palette's hover, pink or lilac */
.tagbox .k-character a { color: var(--k-character); }
.tagbox .k-species a { color: var(--k-species); } /* e621's species orange-red, light enough on the dark panel */
.tagbox .k-meta a { color: var(--k-meta); }
.tagbox .k-lore a { color: var(--k-lore); }
@media (hover: hover) {
  .tagbox .k-fandom a:hover, .tagbox .k-character a:hover, .tagbox .k-species a:hover, .tagbox .k-meta a:hover, .tagbox .k-lore a:hover { color: var(--hover); } /* as heavy as the kind's color, after it: the hover still wins */
}
/* the creation tag search (/tags): the tags on the pictures found, as e621's sidebar, + – name count, each name in its
   category's color (--k-*, darker on a light palette), General the text's; above the pictures on a phone, running on in lines to
   keep it short, and right of the column on a computer, a tag a line, where the trees are on the left */
#q-tip span { white-space: nowrap; } /* an example in the creation tag search's tip kept whole: Firefox broke mouse -gore after its - */
.tagside h2 { margin: 12px 0 6px; color: var(--muted); font-size: 1em; }
.tagside ul { display: flex; flex-wrap: wrap; column-gap: 14px; margin: 0 0 12px; padding: 0; list-style: none; } /* a phone: the tags run on in lines, so 25 of them leave the pictures near */
.tagside li { display: flex; align-items: center; min-height: 32px; }
.tagside .pm { flex: none; width: 22px; text-align: center; color: var(--muted); text-decoration: none; }
.tagside .pm + .pm { margin-right: 4px; }
.tagside .nm { min-width: 0; overflow-wrap: anywhere; }
.tagside .tc { color: var(--muted); font-size: .85em; white-space: nowrap; }
.tagside .k-general .nm a { color: var(--text); } /* General in the text's color, as in the panel: no palette's link color (Pumpkin's orange, Lily's teal) can pass for a category's */
.tagside .k-fandom .nm a { color: var(--k-fandom); }
.tagside .k-character .nm a { color: var(--k-character); }
.tagside .k-species .nm a { color: var(--k-species); }
.tagside .k-meta .nm a { color: var(--k-meta); }
.tagside .k-lore .nm a { color: var(--k-lore); }
@media (hover: hover) {
  .tagside .pm:hover, .tagside .k-general .nm a:hover, .tagside .k-fandom .nm a:hover, .tagside .k-character .nm a:hover, .tagside .k-species .nm a:hover, .tagside .k-meta .nm a:hover, .tagside .k-lore .nm a:hover { color: var(--hover); } /* after the colors, as heavy: the hover still wins */
}
@media (min-width: 1100px) {
  .tagside { position: absolute; top: 12px; left: calc(100% + 24px); width: clamp(220px, 50vw - 348px, 340px); }
  .tagside ul { display: block; }
}
.tagkind .hidetag select { width: auto; max-width: 100%; min-width: 0; min-height: 44px; } /* a tag's search: its category and Save (Categories) */
.lightbox .tagbox .none { color: #a9a4b0; }
.lightbox .tagbox > :last-child { margin-bottom: 0; }
.lightbox .tagbox .rule { margin-top: 10px; color: #a9a4b0; font-size: .85em; } /* the rule under the box: tag what the picture shows (Creation tags) */
.lightbox .tagbox :is(.none, .rule) a { text-decoration: underline; }
.lightbox .addtag { display: flex; gap: 6px; }
.lightbox .addtag input { flex: 1; min-width: 0; color: #e8e6ea; background: #0b0a0e; border-color: #ffffff40; }
.lightbox .addtag .primary { flex: none; padding: 6px 18px; }
.lightbox .shot { position: relative; flex: 1; min-height: 0; overflow: hidden; display: flex; align-items: center; justify-content: center; container-type: size; }
.lightbox .away { position: absolute; inset: 0; } /* the dark around the picture goes back too */
/* the picture in a frame its own size, so its left and right quarters can turn: the frame's
   width follows the stage, and its height the stage's own (.shot is a size container, so
   100cqh is the room it has between the bar and the foot, big text too), since a height in
   % would need the frame's own */
.lightbox .frame { position: relative; min-width: 0; max-width: 100%; max-height: 100cqh; }
.lightbox .frame > a { display: block; }
.lightbox .frame :is(img, video) { display: block; width: auto; height: auto; max-width: 100%; max-height: 100cqh; }
.lightbox .side { position: absolute; top: 0; bottom: 0; width: 25%; cursor: pointer; } /* no mark: the picture's own left and right quarters turn, as in so many apps */
.lightbox .side.l { left: 0; }
.lightbox .side.r { right: 0; }
.lightbox .foot { padding: 8px 12px 12px; }
.lightbox .who a { font-weight: bold; }
.lightbox .who .avatar { width: 28px; height: 28px; }
.lightbox time { color: #a9a4b0; font-size: .9em; }
.lightbox .say { display: flex; gap: 6px; margin: 4px 0; white-space: nowrap; }
.lightbox .say a:first-child { min-width: 0; overflow: hidden; text-overflow: ellipsis; }
.lightbox .say a + a { color: #a9a4b0; }
.lightbox .row { display: flex; align-items: center; gap: 10px; }
.lightbox .n { color: #a9a4b0; font-size: .9em; }
.lightbox .counts { margin-left: auto; white-space: nowrap; }
.lightbox .to { position: absolute; top: 100%; } /* "See more" and the counts scroll to just under the stage, and keep this picture shown (:target stays in its figure) */
html:has(.lightbox) { scroll-padding: 0; }
@media (prefers-reduced-motion: no-preference) { html:has(.lightbox) { scroll-behavior: smooth; } } /* 💬 and See more glide down to the drop, the same page, rather than jump */
.whole summary { cursor: pointer; color: var(--link); } /* a pond's cover, whole, opened in place: closing it is the way back */
.whole img { display: block; width: auto; max-width: 100%; height: auto; margin: 8px 0; border-radius: 8px; }
/* the crop helper (crop.js): the cover picture picked, the part outside the box dimmed, the box an ebook cover's
   shape with a dot at each corner to resize it. No touch scrolls or zooms the page on it, so it's never taller
   than about half the screen, leaving room to scroll past it */
.coverset:has(.crop) { display: block; } /* the picture picked takes the old cover's place, and the whole width */
.coverset:has(.crop) > :first-child, .coverset:has(.crop) :is(.whole, form[action$="/uncover"]) { display: none; } /* and the old cover's See it full size and Remove cover, which a press would apply to it, not to the picture picked */
.crop .stage { position: relative; width: fit-content; max-width: 100%; overflow: hidden; border-radius: 8px; touch-action: none; user-select: none; -webkit-user-select: none; }
.crop .stage img { display: block; max-width: 100%; max-height: min(28rem, 55svh); image-orientation: none; -webkit-user-drag: none; } /* as the server keeps it: without the camera's turn */
.crop .box { position: absolute; box-sizing: border-box; border: 2px solid #fff; box-shadow: 0 0 0 100vmax rgb(0 0 0 / .55), 0 0 0 1px #0008 inset; cursor: move; }
.crop .box:focus-visible { outline: 3px solid var(--accent); outline-offset: -6px; } /* inside: the picture's edge would cut it off */
.crop .box i { position: absolute; width: 14px; height: 14px; border-radius: 50%; background: #fff; box-shadow: 0 0 0 1px #0008; }
.crop .box i::before { content: ""; position: absolute; inset: -13px; } /* a thumb's 40px to grab */
.crop .tl { left: -2px; top: -2px; cursor: nwse-resize; }
.crop .tr { right: -2px; top: -2px; cursor: nesw-resize; }
.crop .bl { left: -2px; bottom: -2px; cursor: nesw-resize; }
.crop .br { right: -2px; bottom: -2px; cursor: nwse-resize; }
.crop > p { margin: 6px 0 0; }
/* a computer: the picture on the left, the drop beside it, and the stage's controls
   over the picture only while it's pointed at or has the keyboard */
@media (min-width: 900px) {
  body:has(.lightbox) { max-width: 440px; margin: 0 0 0 auto; }
  main:has(> .lightbox) { padding-top: 12px; }
  .lightbox { position: fixed; height: auto; bottom: 0; right: 440px; }
  .lightbox .bar { position: absolute; top: 0; left: 0; right: 0; z-index: 1; padding: 14px; }
  .lightbox .shot { padding: 68px 80px; } /* room for ✕ above it and the arrows beside it, so nothing sits on the picture */
  .lightbox .foot { display: contents; }
  .lightbox .who, .lightbox .say, .lightbox .counts, .lightbox .tipline { display: none; } /* 🐟 Feed the fish shows under the drop beside the stage */
  .lightbox .ctl.prev, .lightbox .ctl.next { position: absolute; z-index: 1; top: 68px; bottom: 68px; width: 80px; height: auto; border-radius: 0; font-size: 30px; background: none; } /* the whole side margin, its circle drawn behind the arrow */
  .lightbox :is(.ctl.prev, .ctl.next)::before { content: ""; position: absolute; z-index: -1; width: 48px; height: 48px; border-radius: 50%; background: #000a; }
  .lightbox .prev { left: 0; }
  .lightbox .next { right: 0; }
  .lightbox .n { position: absolute; bottom: 16px; left: 50%; transform: translateX(-50%); padding: 2px 12px; border-radius: 999px; background: #000a; color: #e8e6ea; }
  .lightbox .bar .ctl { background: #000a; }
  .lightbox .tagbox { top: 62px; right: 14px; width: 380px; max-height: calc(100svh - 124px); } /* the 🏷️ panel on a computer: the screen's height under its button, above the picture's 1 / 3, and a little wider, so a long list or big text isn't cramped into 60% of it */
}
/* with a mouse they fade 3 seconds after the picture shows, and come back when the pointer
   comes onto the stage or leaves it, fading again 3 seconds later while it rests: entering
   swaps quiet for its twin quietly, which starts it over (Facebook's, by CSS alone). On their
   own places (the top bar, the side margins) or with the keyboard they stay. They sit beside
   the picture, never on it. */
@media (min-width: 900px) and (hover: hover) {
  .lightbox figure :is(.bar, .ctl.prev, .ctl.next, .n) { animation: quiet .6s 3s forwards; }
  .lightbox figure:hover :is(.bar, .ctl.prev, .ctl.next, .n) { animation-name: quietly; }
  .lightbox figure:is(:has(.bar:hover, .ctl.prev:hover, .ctl.next:hover, .tags[open]), :focus-within, :focus-visible + figure) :is(.bar, .ctl.prev, .ctl.next, .n) { animation: none; }
}
@media (min-width: 900px) and (hover: hover) and (prefers-reduced-motion: reduce) {
  .lightbox figure :is(.bar, .ctl.prev, .ctl.next, .n) { animation: none; }
}
@keyframes quiet { to { opacity: 0; } }
@keyframes quietly { to { opacity: 0; } }
/* under a drop read in a pond: each always in its place, so the bar never shifts */
.turn { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; margin: 14px 0; }
.turn > * { padding: 10px 0; white-space: nowrap; } /* a word never breaks; short of room, a whole item wraps */
.turn > * + * { margin-left: auto; } /* spread out on one row, and an item that wraps still at the right */
.turn > .primary:only-child { margin-left: auto; } /* a row with only its main button, the welcome step Done: at the right all the same */
.turn > .primary, .turn > form > .primary { padding: 10px 26px; }
.turn > span { color: var(--muted); }
.turn button { min-height: 44px; white-space: normal; } /* a form's last row: every button at least a finger tall (coponder.md, A form's last row); too long for the screen even on a row of its own, its words wrap */
div.turn > a { min-height: 44px; } /* and its Cancel or ← Back; the reading bar is a nav.turn, and keeps its own */
.turn > form { padding: 0; } /* a yes or a no in a form of its own: its button is the item */
.turn > a:active, .float > a:active { transform: translateY(2px); box-shadow: none; }
/* the pond Previous or Next steps into or out to, under it: below the bar, so the bar never shifts; a long name is cut */
.turn > a { position: relative; }
.turn small { position: absolute; top: 100%; left: 0; max-width: min(45vw, 280px); margin-top: 4px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-size: .85em; font-weight: normal; color: var(--muted); }
.turn > .primary small { left: auto; right: 0; }
.turn:not(:has(.primary small)) small, .turn:not(:has(a:not(.primary) small)) small { max-width: min(100vw - 24px, 576px); } /* alone, the whole row */
/* a picture in a drop read in a pond: its left and right fifths turn like the bar
   (its middle opens the picture page); the ‹ › show only under a pointer, not over the art */
.pic { position: relative; }
.pic > .prev, .pic > .next { position: absolute; top: 0; bottom: 0; width: 20%; display: flex; align-items: center; padding: 0 8px; cursor: pointer; }
.pic > .prev { left: 0; }
.pic > .next { right: 0; justify-content: flex-end; }
.pic > a > span { flex: none; width: 44px; height: 44px; border-radius: 50%; background: var(--card); opacity: .7; color: var(--text); font-size: 32px; line-height: 40px; text-align: center; }
.pic > a > span { visibility: hidden; }
@media (hover: hover) { .pic > a:hover > span { visibility: visible; } } /* not on touch, where a hover would cost a second tap */
/* ‹ › pinned to the screen's bottom corners while you read the drop; the bar scrolls
   up over them and keeps them (they sit behind it), so they never cover the reply box */
.reading { display: flow-root; margin-bottom: 14px; }
.reading:has(small) { margin-bottom: 40px; }
.reading > .turn { position: relative; z-index: 1; min-height: 64px; margin-bottom: 0; background: var(--bg); } /* as tall as the pair stands off the screen's foot (16 + 4 + 44), so once the bar is all in view the pair is all behind it */
.float { position: sticky; z-index: 0; bottom: 16px; height: 0; margin: 0; padding: 0 4px; display: flex; justify-content: space-between; align-items: flex-end; }
.float > a { width: 44px; height: 44px; border-radius: 50%; border: var(--bw) solid var(--border); background: var(--card); color: var(--link); font-size: 32px; line-height: 38px; text-align: center; padding: 0; margin-bottom: 4px; }
.float > .primary { margin-left: auto; border-color: var(--accent); background: var(--accent); color: var(--on); } /* alone at the start of the walk, still at the right */
@media (min-width: 760px) { .float, .reading > .turn { margin: 0 -60px; } .reading > .turn { padding: 0 60px; } } /* beside the column, where there's room, so they cover no words; the bar reaches out to keep them */
@media (max-width: 759px) { .reading:has(.focus .images) > .float { display: none; } } /* on a phone they would float over the drop's pictures: its bar, and a comic page's edges, turn it */
/* a pond's Contents: numbered lines; the one you came from (#p{id}) is marked */
.contents { margin: 8px 0; padding-left: 2.4em; }
.contents li { padding: 8px 0; border-bottom: var(--bw) var(--dash) var(--border); }
.contents li::marker { color: var(--muted); }
.contents.plain { padding-left: 0; list-style: none; } /* a book's or comic's New: newest first, so no numbers */
.contents li:target, .addto li:target, .contents li[aria-current] { border-left: 3px solid var(--accent); padding-left: 10px; }
.contents li:is(:target, [aria-current]) > a { font-weight: bold; } /* the line you came for, or on ▶ Up next the drop you're reading */
.contents li:has(> .edit) { position: relative; padding-right: 5.5em; } /* your own line's ✏️ Edit, at its right end, middle of however many lines it takes */
.contents .edit { position: absolute; right: 0; top: 50%; translate: 0 -50%; padding: 2px 10px; border: var(--bw) solid var(--field); border-radius: 999px; color: var(--text); font-size: .9em; white-space: nowrap; }
/* a book's moderators set its order: ↕ Arrange, at the tabs' right end, shows Top ↑ ↓ End
   under each line, like the Tackle box's chips, until ✓ Done */
/* .tool marks each of a pond's tab-row tools (🪷 Add, ↕ Arrange, ✓ Done), a hook for tests; .tools holds them. */
.tabs .tools { margin-left: auto; display: flex; flex-wrap: wrap; gap: inherit; } /* 🪷 Add and ↕ Arrange at the right, wrapping together */
.move { display: flex; gap: 8px; margin-top: 6px; }
.move button, .addto button { min-width: 44px; padding: 4px 12px; border: var(--bw) solid var(--field); border-radius: 999px; font-size: .9em; }
.move button:hover, .addto button:hover { border-color: var(--accent); }
.move button:active, .addto button:active { transform: translateY(2px); }
.move button:disabled { opacity: .4; border-color: var(--field); color: var(--link); cursor: default; transform: none; } /* not pressable: no pink on hover either */
/* a drop's Add to pond page: each pond's name, then at the right 🪷 Add, or ✓ In it lit
   (reading it there) with Take out; the line just pressed is marked like Contents' */
.addto li { display: flex; flex-wrap: wrap; align-items: center; gap: 6px 8px; }
.addto .to { margin-left: auto; display: flex; flex-wrap: wrap; justify-content: flex-end; align-items: center; gap: 6px 8px; }
.addto .on { padding: 4px 12px; border-radius: 999px; font-size: .9em; }
.addto :is(button, .on) { white-space: nowrap; } /* a pill stays whole, and the row wraps instead (240px, big text) */
/* 🔁 n on a pond's page, a chip so it's plainly there to tap; its menu opens from the
   column's edge, not past it as a drop card's padding allows */
.profile .rp, .profile .actions :is(.pill, .primary, .fishtip) { margin: 2px 0 6px; } /* the row of buttons under a pond's or a person's name: Join or Follow, Leave, ⭐ Front page, level with 🔁 Repost and ⋯, and room under them */
.profile .rp summary, .profile .actions .pill, .report .pill { padding: 4px 12px; }
.profile .rp summary, .pondrow .rp summary, .profile .pill, .report .pill, section.book .pill, .resume .pill { border: var(--bw) solid var(--field); border-radius: 999px; } /* a bordered pill: 🔁 n, ✏️ Edit profile, a queue's verdicts, a cover page's Contents, 📥 Download over a book's Contents */
.profile .rp summary:hover, .pondrow .rp summary:hover, .profile .pill:hover, .report .pill:hover, section.book .pill:hover, .resume .pill:hover { border-color: var(--accent); }
:is(.profile, .pondrow) .rp ul { margin-left: 0; }
:is(.profile, .pondrow) .rp li { min-height: 44px; padding: 10px 4px; } /* a menu item under the row or a 🪷 Ponds row's ✓ Joined, ⋯'s Mute, Block, Report and the others: a tap target 44 pixels tall (owner, 2026-10-26), its line in the middle */
.profile .panel ul { left: 0; right: 0; max-height: 60vh; overflow: auto; overflow-wrap: anywhere; } /* 🔗 Invite and an admin's ⋯ on a pond: the column's width under the row, so a long link or list wraps and scrolls, never past a phone's edge */
.profile .panel li a { display: inline; } /* a name in a list of who's banned, not a line of its own */
.profile > .settings { margin: 0 0 12px; } /* ✏️ Edit or Moderator tools, a fold of its own under the row: room before what the pond is about */
/* a repost of a pond: its name close over its address, and its picture a band of one
   shape, so a tall comic page and a wide photo make the same card */
.pond .title { margin: 2px 0 0; }
.pond .meta { margin: 0 0 6px; }
.pond > div > :last-child, .pond .body > :last-child { margin-bottom: 0; } /* as much room under its last line as over its name */
.pond .images img, .pond .images video { width: 100%; aspect-ratio: 2 / 1; object-fit: cover; } /* a band across the card, cropped */
/* what to do next, where a newcomer would stop: the first thing to read on the page */
.hint { padding: 10px 14px; border: var(--bw) solid var(--accent); border-radius: 10px; }
.added > p, .added > .contents { margin: 0; } /* back at a pond's box: what was just added */
.added li:last-child { border-bottom: none; padding-bottom: 0; }
.rules, .vote { margin: 12px 0 0; padding: 8px 14px; border: var(--bw) solid var(--border); border-radius: 10px; } /* a pond's rules, above its box; and a members' vote, whose margin is its own, below */
.rules summary, .vote summary, .all summary { cursor: pointer; color: var(--link); }
.profile .new { --spin: 12s; display: inline-grid; margin: 2px 0 6px; text-align: center; } /* ＋ New folder on your own pages, level with ✏️ Edit profile */
.profile .new > span { grid-area: 1 / 1; } /* its labels in one cell: as wide as the widest, whichever shows. Four, one per row of kinds, hence four delays below */
@media (prefers-reduced-motion: no-preference) { /* New folder, New book, New comic, New gallery in turn, a quarter of --spin each, fading across */
  .profile .new > [hidden] { display: block; }
  .profile .new > span { animation: kinds var(--spin) infinite; }
  .profile .new > :nth-child(2) { animation-delay: calc(var(--spin) * -.75); }
  .profile .new > :nth-child(3) { animation-delay: calc(var(--spin) * -.5); }
  .profile .new > :nth-child(4) { animation-delay: calc(var(--spin) * -.25); }
  .profile .new:is(:hover, :focus-visible) { --spin: 1.2s; } /* pointed at, it spins ten times as fast, as a joke (owner) */
}
@keyframes kinds { 0%, 21% { opacity: 1; } 25%, 96% { opacity: 0; } 100% { opacity: 1; } }
/* the pond form, one question a page: big choices to tap, the one picked lit */
.steps { margin: 12px 0 0; color: var(--muted); font-size: .9em; }
.steps + h1 { margin: 4px 0 12px; }
.choices { display: grid; gap: 8px; margin: 12px 0; } /* tight enough that What kind?'s Next shows on a 390 × 844 phone */
.choices label { position: relative; margin: 0; font-weight: normal; cursor: pointer; }
.choices input { position: absolute; width: 1px; height: 1px; opacity: 0; }
.choices label > span { display: block; padding: 8px 16px 9px; background: var(--card); border: 2px solid var(--border); border-radius: 14px; }
.choices :checked + span { border-color: var(--accent); background: color-mix(in srgb, var(--accent) 14%, var(--card)); }
.choices :focus-visible + span { outline: 2px solid var(--link); outline-offset: 2px; }
.choices b { display: block; font-size: 1.15em; }
.choices .muted { display: block; }
.choices .facts { display: block; color: var(--muted); } /* Who can see: the same facts on every card, one a line */
.choices .facts > span { display: block; }
.choices .facts em { font-style: normal; color: var(--text); }
.seeing { border: 0; margin: 8px 0; padding: 0; min-width: 0; } /* Moderator tools' Who can see cards, one group with its name */
.seeing legend { padding: 0; font-weight: bold; }
.apart { margin: 20px 0 0; font-weight: bold; color: var(--muted); font-size: .9em; } /* 🔐 Private, another kind of thing, set apart below the others */
.answers { margin: 16px 0; padding-top: 8px; border-top: var(--bw) var(--dash) var(--border); } /* the last page: the fields it still asks, a question and its dropdown a line (Who adds to it and Where it lives, or What it is) */
.answers p { display: grid; grid-template-columns: 9.5em minmax(0, 1fr); gap: 12px; align-items: center; }
.answers label { margin: 0; }
.asked { margin: 8px 0 16px; padding-top: 0; } /* the last page's answers, above its fields: each row a link back to its question */
.asked > a { display: grid; grid-template-columns: 9.5em minmax(0, 1fr); gap: 12px; align-items: center; min-height: 44px; padding: 4px 0; border-bottom: var(--bw) var(--dash) var(--border); }
.asked > a > b { color: var(--text); } /* the question; the answer is the link's colour, and turns pink with it */
.sure { padding: 10px 14px; border-left: 4px solid var(--accent); border-radius: 8px; background: color-mix(in srgb, var(--accent) 14%, transparent); } /* reassurance, in the accent colour */
.profile .pill { margin: 2px 0 6px; padding: calc(8px - var(--bw)) 18px; color: var(--text); } /* as tall as ＋ New folder */
/* folder cards: a pond looks like what it holds. A book's cover stands upright beside
   its first lines, a comic shows the top of its first page, a gallery a grid of squares;
   a card with no picture has an emoji cover, its kind's emoji over its name on a soft
   colour from its name (Hue), mixed into the card colour so it suits every palette */
.shelf { padding: 14px 16px; } /* a box like a drop's, with even room round its pictures */
.shelf .title { margin: 0; }
.shelf .meta { margin: 0 0 6px; }
.shelf .body > :last-child { margin-bottom: 0; }
.shelf:has(> .cover), .pond:has(> .cover), .coverset { display: grid; grid-template-columns: 96px minmax(0, 1fr); gap: 14px; align-items: start; }
.shelf :is(.page, .grid a) :is(img, video) { display: block; width: 100%; height: auto; object-fit: cover; border-radius: 8px; }
.cover :is(img, video), .cover.emoji { display: block; width: 100%; height: auto; aspect-ratio: 5 / 8; object-fit: cover; border-radius: 3px 8px 8px 3px; box-shadow: var(--shadow); } /* an ebook cover's shape */
a.cover.emoji { display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 8px; padding: 8px 6px; background: color-mix(in oklab, hsl(var(--hue) 70% 60%) 30%, var(--card)); color: var(--text); text-align: center; }
.cover.emoji span { font-size: 2.5em; line-height: 1; }
/* a folder's card with no cover picture: the folder itself in its hue, its first drops sticking out of its top
   (a picture drop as its picture, a drop of words as a slip of lined paper, the first in front), its flap
   counting what's in it (cards in pond.go) */
.cover.fold { position: relative; display: block; aspect-ratio: 1 / 1.08; margin-top: 2px; }
.fold .back, .fold .front { position: absolute; left: 0; right: 0; }
.fold .back { top: 16%; bottom: 0; border-radius: 3px 8px 8px 8px; background: color-mix(in oklab, hsl(var(--hue) 55% 40%) 75%, var(--card)); }
.fold .back::before { content: ""; position: absolute; left: 0; top: -10%; width: 44%; height: 12%; border-radius: 5px 8px 0 0; background: inherit; } /* its tab */
.fold .front { z-index: 2; bottom: 0; height: 46%; display: flex; align-items: flex-end; justify-content: center; padding: 0 4px 6px; border-radius: 5px 5px 8px 8px; background: color-mix(in oklab, hsl(var(--hue) 70% 62%) 82%, var(--card)); box-shadow: 0 -3px 8px rgb(0 0 0 / .3), inset 0 1px 0 rgb(255 255 255 / .3); }
.fold .front b { color: rgb(0 0 0 / .65); font: 700 11px/1.2 system-ui, -apple-system, "Segoe UI", sans-serif; text-align: center; }
.cover.fold .sheet { position: absolute; top: 2%; left: 20%; width: 60%; height: auto; aspect-ratio: 3 / 4; object-fit: cover; border: 2px solid #fff; border-radius: 4px; background: #fff; box-shadow: 0 2px 6px rgb(0 0 0 / .4); } /* over .cover img's */
.cover.fold .sheet:nth-child(2) { z-index: 1; transform: rotate(-1deg); }
.cover.fold .sheet:nth-child(3) { top: 6%; left: 38%; transform: rotate(9deg); }
.cover.fold .sheet:nth-child(4) { top: 8%; left: 3%; transform: rotate(-11deg); }
.fold .note { overflow: hidden; padding: 4px; color: #2b2b2b; font: 400 6px/1.35 var(--body, var(--head)); text-align: left; overflow-wrap: anywhere; background: repeating-linear-gradient(#fffdf6 0 7px, #e7e2d6 7px 8px); }
.fold .veil { filter: blur(5px) brightness(.85); clip-path: inset(0 round 4px); } /* an 18+ picture, to a reader who hides it */
.cover.emoji b { display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 3; overflow: hidden; font: 700 .75em/1.2 var(--head); }
section.book { margin: 4px 0 24px; text-align: center; } /* a book's cover page (the section only: a book's card carries the class too): the cover as big as the screen allows with its buttons still in view */
section.book > a:first-of-type { display: block; width: min(100%, max(16rem, 100svh - 19rem - var(--resume, 0rem) - var(--bar, 0rem)) * .625); margin: 0 auto; border-radius: 3px 10px 10px 3px; }
section.book img { display: block; width: 100%; height: auto; border-radius: 3px 10px 10px 3px; box-shadow: var(--shadow), 0 10px 30px rgb(0 0 0 / .35); }
section.book h1 { margin: 18px 0 2px; overflow-wrap: break-word; }
section.book > p { margin: 0; }
section.book .open { display: flex; flex-wrap: wrap; justify-content: center; align-items: center; gap: 12px 14px; margin-top: 16px; }
section.book :is(.primary, .pill) { padding: calc(10px - var(--bw)) 22px; white-space: nowrap; }
section.book .primary { padding: 10px 26px; }
section.book .open small { display: block; font-size: .75em; font-weight: normal; } /* under Start reading, a first drop the reader hides by a #tag (Hidden tags) */
.resume { display: flex; flex-wrap: wrap; gap: 10px 12px; margin: 14px 0 4px; } /* ▶ Continue and 📥 Download, over a book's Contents: a box, so the pills' padding keeps its room */
.resume .pill { padding: calc(8px - var(--bw)) 18px; color: var(--text); } /* 📥 Download there: as tall as ▶ Continue beside it */
section.book .resume { justify-content: center; margin-top: 16px; } /* and on its cover, a row over Start reading and Contents */
section.book .resume + .open { margin-top: 12px; }
section.book .resume .primary { white-space: normal; } /* "Continue from chapter 55" wraps inside its pill, rather than run off a zoomed in phone */
section.book:has(> .resume) { --resume: 3.5rem; } /* the cover a row shorter, so the buttons still fit */
section.book .chip { display: inline-block; margin-top: 14px; padding: 4px 12px; font-size: .9em; } /* ＋ New chapter, a smaller pill */
/* A book's cover page is its page 0, in the reader's look (coponder.md, The cover page): the site around it goes, as
   on a page of words, keyed on its own section (never a book's card). It stays in the page's flow, so nothing is cut off. */
body:has(> main > section.page0) > :is(header, footer), main:has(> section.page0) > .trees { display: none; }
main:has(> section.page0) { position: static; } /* the running head along the window's top, where a page of words has it */
section.page0 { margin: 0; padding: 44px 0 24px; }
section.page0 > a:first-of-type { width: min(100%, max(16rem, 100svh - 15rem - var(--resume, 0rem)) * .625); }
section.page0 > .next { position: fixed; z-index: 2; right: 0; bottom: 0; display: flex; align-items: flex-end; justify-content: flex-end; color: var(--muted); font-size: 26px; line-height: 1; } /* the › a page of words has, in its corner, over whatever scrolls under it */
section.page0 > .next span { width: 52px; height: 48px; display: flex; align-items: center; justify-content: center; padding-bottom: 3px; }
@media (min-width: 720px) { section.page0 > .next { top: 0; width: calc(50% - 300px); } } /* on a computer, the whole empty margin right of the column turns too */
.profile:has(> .cover) { display: flow-root; } /* Contents of a book that opens on its cover: the cover small beside its name, back to it */
.profile > .cover { float: left; width: 72px; margin: 6px 14px 6px 0; }
.profile > .cover ~ :is(details, form, .body) { clear: left; }
.hue0 { --hue: 350; } .hue1 { --hue: 25; } .hue2 { --hue: 50; } .hue3 { --hue: 110; } .hue4 { --hue: 170; } .hue5 { --hue: 205; } .hue6 { --hue: 250; } .hue7 { --hue: 295; }
.shelf .page { display: block; margin-top: 8px; }
.shelf .page :is(img, video) { aspect-ratio: 2 / 1; object-position: top; } /* the shape of a reposted pond's cover */
.shelf .grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 4px; margin-top: 8px; }
.shelf .grid :is(img, video) { aspect-ratio: 1; border-radius: 6px; }
/* 🪷 Ponds: a small card per pond, all one height (owner, 2026-10-27: c, small cards). Its real shape on the left, standing on the slot's floor like books on a shelf; its words; Join, Follow or ✓ Joined on the right */
.ponds { display: grid; gap: 8px; margin: 8px 0; padding: 0; list-style: none; }
.pondrow { display: grid; grid-template-columns: 72px minmax(0, 1fr) auto; gap: 14px; align-items: center; padding: 10px 12px 10px 10px; background: var(--card); border: var(--bw) var(--dash) var(--border); border-radius: 14px; box-shadow: var(--shadow); }
.pondrow .thumb { display: flex; align-items: flex-end; justify-content: center; width: 72px; height: 96px; }
.pondrow .shape { display: block; overflow: hidden; color: var(--text); box-shadow: 0 4px 10px rgb(0 0 0 / .3); }
.pondrow .shape :is(img, video) { display: block; width: 100%; height: 100%; object-fit: cover; }
.pondrow .shape.tall { height: 96px; aspect-ratio: 5 / 8; border-radius: 3px 8px 8px 3px; } /* an ebook cover's shape, as a card's */
.pondrow .shape.emoji { display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 4px; padding: 4px 3px; text-align: center; background: color-mix(in oklab, hsl(var(--hue) 70% 60%) 30%, var(--card)); box-shadow: 0 4px 10px rgb(0 0 0 / .3), inset 4px 0 0 rgb(0 0 0 / .18); } /* its spine down the left */
.pondrow .shape.emoji > span { font-size: 28px; line-height: 1; }
.pondrow .shape.emoji > b { display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 3; overflow: hidden; font: 700 10px/1.15 var(--head); }
.pondrow .shape.comic { height: 96px; aspect-ratio: 5 / 7; padding: 2px; border-radius: 2px; background: #fff; } /* a printed page */
.pondrow .shape.comic :is(img, video) { object-position: top; }
.pondrow .shape.gallery { max-width: 72px; max-height: 96px; border-radius: 6px; }
.pondrow .shape.gallery :is(img, video) { width: auto; height: auto; max-width: 72px; max-height: 96px; } /* the picture at its own shape */
.pondrow .shape.doc { position: relative; height: 96px; aspect-ratio: 3 / 4; padding: 7px 5px 4px; border-radius: 2px 10px 2px 2px; color: #2b2b2b; font: 7px/9px var(--body, var(--head)); overflow-wrap: anywhere; background: repeating-linear-gradient(#fffdf6 0 8px, #e7e2d6 8px 9px) content-box, #fffdf6; } /* a sheet of lined paper, its first words on the lines */
.pondrow .shape.doc::after { content: ""; position: absolute; top: 0; right: 0; width: 10px; height: 10px; background: linear-gradient(225deg, var(--card) 50%, #d9d2c3 50%); } /* its corner folded */
.pondrow .shape.doc > span { display: block; height: 100%; overflow: hidden; }
.pondrow .thumb:has(.icon) { align-items: center; }
.pondrow .shape.icon { display: flex; align-items: center; justify-content: center; width: 52px; height: 52px; border-radius: 14px; font-size: 28px; line-height: 1; background: color-mix(in oklab, hsl(var(--hue) 70% 60%) 30%, var(--card)); }
.pondrow h2 { margin: 0; font: 700 1.05em/1.3 var(--head); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.pondrow h2 a { color: var(--text); }
.pondrow .meta { display: flex; margin: 1px 0 0; font-size: .85em; line-height: 1.35; color: var(--muted); white-space: nowrap; }
.pondrow .meta > span { flex: none; }
.pondrow .meta > :first-child { flex: 0 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; } /* only whose it is or its count gives way: its mark, why it has no Join, stays whole */
.pondrow .meta a { color: var(--muted); }
.pondrow .about { display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 2; overflow: hidden; height: 2.7em; margin: 3px 0 0; font-size: .9em; line-height: 1.35; } /* two lines, then …, the same height with one */
.pondrow .about.one { -webkit-line-clamp: 1; height: 1.35em; margin-bottom: 1.35em; color: var(--muted); font-style: italic; }
.pondrow .what:not(:has(.about)) { padding-bottom: 3.05em; } /* no words under it: still one height */
.pondrow > form .primary, .pondrow > .rp > summary { min-width: 5em; padding: 6px 12px; font-size: .9em; text-align: center; white-space: nowrap; }
.pondrow > .rp > summary { padding: calc(6px - var(--bw)) 12px; } /* Join's height, its border inside it: the pill a member gets in its place is the same size */
.pondrow > .rp { position: relative; }
.pondrow > .rp ul { right: 0; white-space: nowrap; } /* Leave opens under the pill, to its left, never off a phone's screen */
:is(.profile, .pondrow) .rp.joined > summary { color: var(--muted); border-style: dashed; } /* a member's ✓ Joined: quiet, its menu holds Leave */
.profile .rp li.apart { min-height: 0; padding: 0; margin: 6px 0; border-top: var(--bw) solid var(--border); } /* in ⋯, the line over the admins' items */
.unfold { display: none; }
@media (max-width: 599px) { /* a pond's long description on a phone: its first three lines, then … and Show more, which opens the rest and goes */
  .profile .body.folds:not(:has(+ .unfold[open])) { display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 3; overflow: hidden; }
  .profile .body.folds:not(:has(+ .unfold[open])) > * { margin: 0; }
  .unfold:not([open]) { display: block; margin: 0 0 8px; }
  .unfold > summary { list-style: none; cursor: pointer; color: var(--link); }
  .unfold > summary::-webkit-details-marker { display: none; }
}
/* a book's or a comic's line with pictures shows its first, small; a gallery's Contents is tiles,
   a drop without a picture one of its first words */
.contents .thumb, .addto .thumb { width: 40px; height: 40px; margin-right: 8px; object-fit: cover; border-radius: 6px; vertical-align: middle; }
.contents a > .thumb { margin-right: 0; } /* a comic's wordless page: its picture is the link */
.view { margin: 12px 0 -4px; text-align: right; } /* a gallery: its wall of pictures, or each upload as a card */
.tiles { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 6px; margin: 12px 0; }
.tile > a, .tile > details > a { position: relative; display: block; aspect-ratio: 1; overflow: hidden; border-radius: 8px; background: var(--card); border: var(--bw) solid var(--border); color: var(--text); }
.tile img { display: block; width: 100%; height: 100%; object-fit: cover; }
.tile span { display: block; padding: 10px; overflow-wrap: anywhere; font: 1em/1.3 var(--head); }
.tile .count { position: absolute; right: 6px; bottom: 6px; padding: 2px 8px; border-radius: 999px; background: #0008; color: #fff; font-size: .85em; }
.tile:target > a { outline: 3px solid var(--accent); }
.tile details.adult { margin: 0; } /* an 18+ tile: frosted, a small pill, its tile once shown */
.tile .frost, .tile .frost > span { padding: 0; } /* .tile span pads a tile of words */
.tile .frost > span { aspect-ratio: 1; border: var(--bw) solid var(--border); }
.tile .pill18 { display: inline-flex; gap: 5px; padding: 6px 11px; font: 700 13px/1.2 system-ui, -apple-system, "Segoe UI", sans-serif; }
.tile .pill18 svg { width: 15px; height: 15px; }
.tile .move { flex-wrap: wrap; }
/* Media: the server picks the rows (mediaRows), so the wall is the same on every screen, only smaller. A tile shares its row by its shape (r67: two thirds), so a
   row is one height; the last row isn't stretched (3 is config.MediaRow). Each tile is a size container, so the pill and words shrink before they'd spill */
.media { display: grid; gap: 6px; margin: 12px 0; }
.media .row { display: flex; gap: 6px; }
.media .tile { position: relative; flex: var(--r) 1 0; min-width: 0; container-type: inline-size; }
.media .last .tile { flex: 0 1 calc((100% - 12px) * var(--r) / 3); }
.media .tile > a, .media .tile > details > a, .media .tile .frost > span { aspect-ratio: var(--r); }
.media .tall img { object-position: top; } /* cut from a picture taller than 1:2: its top, a webtoon's title and first panel */
.media .lock { position: absolute; top: 4px; right: 4px; display: flex; align-items: center; justify-content: center; width: 22px; height: 22px; border-radius: 999px; background: #0008; font: 12px/1 system-ui, -apple-system, "Segoe UI", sans-serif; pointer-events: none; } /* 🔐 on the picture, never under it, at one size as the pill is, so big text doesn't spread it over a narrow tile; a tap goes through it to the tile */
@container (max-width: 99px) { .media .tile > a > span { padding: 6px; font-size: .8em; } }
@container (max-width: 79px) { .media .pill18 { padding: 5px 8px; } .media .pill18 svg { display: none; } .media .lock { top: 3px; right: 3px; width: 16px; height: 16px; font-size: 10px; }
  .media .tile:has(> .lock) .pill18 { inset: auto 0 4px; } } /* a narrow 🔐 18+ tile: the pill at its foot, under the badge, never behind it */
@container (max-width: 69px) { .media .tile > a > span { padding: 4px; font-size: .65em; } }
@container (max-width: 49px) { .media .pill18 { padding: 3px 4px; font-size: 11px; } }
.media .r50 { --r: 0.5; } .media .r56 { --r: 0.5625; } .media .r63 { --r: 0.625; } .media .r67 { --r: 0.6667; } .media .r75 { --r: 0.75; } .media .r80 { --r: 0.8; } .media .r90 { --r: 0.9; } .media .r100 { --r: 1; } .media .r113 { --r: 1.125; } .media .r125 { --r: 1.25; }
.media .r133 { --r: 1.3333; } .media .r150 { --r: 1.5; } .media .r167 { --r: 1.6667; } .media .r178 { --r: 1.7778; } .media .r200 { --r: 2; } .media .r225 { --r: 2.25; } .media .r250 { --r: 2.5; } .media .r275 { --r: 2.75; } .media .r300 { --r: 3; }
.shelf > .move { grid-column: 1 / -1; }
.peek { margin: 6px 0 0; padding-left: 1.6em; }
.peek li { padding: 2px 0; overflow-wrap: anywhere; }
.peek li::marker { color: var(--muted); }
.video { width: 100%; aspect-ratio: 16 / 9; border: 0; border-radius: 8px; margin: 8px 0; }
/* The post box (owner, 2026-10-28, from the mockup he approved, as Apple Notes and Obsidian have it): one box holds the words, the pictures, the places picked, and along its bottom edge its bar: 📎, 🪷 Where it goes, the tools, which scroll sideways, and Drop at the right, which never moves. The edit form has the same box and bar (thread.html), with Cancel and Save where Drop sits */
.field { position: relative; margin: 8px 0; background: var(--card); border: var(--bw) solid var(--field); border-radius: 22px; } /* positioned: the Goes in list and an open tab's panel hang from the box, not from the bar that scrolls, which would clip them */
.field:has(> textarea:focus, .cm-focused, .sayfield input:focus) { outline: auto; } /* the whole box shows the focus of its words, not Goes in's or 📎's */
.field textarea { vertical-align: top; min-height: 3.6em; padding: 12px 16px 2px; border: 0; border-radius: 22px 22px 0 0; background: none; outline: none; } /* a little under 5em: the bar along the bottom makes the box twice the title's height and more */
@supports (field-sizing: content) { .field textarea { resize: none; } } /* it grows with its words: no handle to drag, where a browser can do that */
.field > .drafts { margin: 0; padding: 6px 12px 0; } /* the pictures, squares under the words */
.field > .where { display: flex; flex-wrap: wrap; gap: 6px; margin: 0; padding: 6px 12px 0; } /* the places picked in Goes in, a chip each, under the pictures, or a Wall's line saying where it goes */
.where:empty { position: absolute; } /* out of the flow, so it adds no gap, but still read: a screen reader hears the first chip come */
.where > span { display: inline-flex; align-items: center; min-width: 0; min-height: 34px; padding-left: 12px; border: var(--bw) solid var(--field); border-radius: 999px; background: var(--bg); font-size: .9em; overflow-wrap: anywhere; }
.where > .fixed { padding-right: 12px; } /* an edit's chip with no ✕: where it lives, or where its tag keeps it */
.field > .why { margin: 0; padding: 4px 12px 0; font-size: .85em; } /* under the chips, why one has no ✕: readable on a phone, which shows no title */
.where button { position: relative; flex: none; width: 36px; height: 34px; color: var(--muted); }
.where button::before { content: ""; position: absolute; inset: -5px -4px; } /* ✕: a thumb's 44 by 44 target in a 34px chip, 36px wide, reaching into the gap after it */
.inbar { display: flex; flex-wrap: wrap; align-items: center; gap: 6px; padding: 6px; } /* the bar, then Drop; Drop and Preview wrap under it only where big text leaves the strip less than 10em */
.strip { flex: 1 1 10em; min-width: 0; margin: -3px; padding: 3px; display: flex; align-items: center; gap: 2px; overflow-x: auto; overscroll-behavior-x: contain; scrollbar-width: none; --l: #000; --r: #000; } /* 📎, 🪷 and the tools on one line that scrolls sideways, as Apple Notes' and Obsidian's bars do */
.strip::-webkit-scrollbar { display: none; }
@media not (pointer: fine) { .strip:not(:has([open], #goes:focus)) { -webkit-mask: linear-gradient(to right, var(--l), #000 28px, #000 calc(100% - 28px), var(--r)); mask: linear-gradient(to right, var(--l), #000 28px, #000 calc(100% - 28px), var(--r)); } } /* on a touch screen, a fade at an end with more of the strip past it (editor.js), as Notes' bar has; none while a tab is open or Where it goes has the focus, since a mask would clip the panel or the list of places too */
.strip.left { --l: transparent; } .strip.right { --r: transparent; }
.nudge { display: none; position: sticky; z-index: 1; flex: none; width: 0; height: 44px; margin: 0 -1px; } /* ‹ and › (editor.js): stuck to the strip's ends, taking no room in it */
.nudge.l { left: 0; } .nudge.r { right: 0; }
.nudge button { position: absolute; top: 0; width: 32px; height: 44px; padding: 0; border: 0; border-radius: 0; background: linear-gradient(to right, var(--card) 70%, transparent); color: var(--text); font-size: 1.5em; line-height: 1; cursor: pointer; }
.nudge.l button { left: -3px; padding-right: 6px; } .nudge.r button { right: -3px; padding-left: 6px; background: linear-gradient(to left, var(--card) 70%, transparent); }
.nudge button:hover { color: var(--link); }
@media (pointer: fine) { .strip.left > .nudge.l, .strip.right > .nudge.r { display: block; } } /* a mouse can't swipe: an arrow where there's more past that end, in the fade's place */
.compose:not(.js) .strip { flex-basis: 20em; flex-wrap: wrap; } /* without the writing helper nothing fades its ends or opens Where it goes, so the strip wraps: every tool in sight, and Where it goes… whole; 20em, so on a phone Preview and Drop take the next line */
.clip { flex: none; display: grid; place-items: center; width: 44px; height: 44px; margin: 0; border-radius: 50%; font-size: 1.3em; font-weight: normal; line-height: 1; cursor: pointer; } /* a file field's button and nothing else: the field is out of sight, and the box's tiles say what's picked */
.clip > input[type=file], .choose > input[type=file] { width: 1px; } /* out of sight (.sr), and no wider: input[type=file]'s own width counted it 60px past a phone's edge in Safari */
.clip:has(:focus-visible), .choose:has(:focus-visible) { outline: auto; }
.goeswrap { flex: 0 1 13em; display: flex; align-items: center; min-width: 11em; overflow: hidden; border-radius: 999px; background: var(--bg); } /* 🪷 and Where it goes…, a pill set into the box */
.goeswrap:has(#goes:focus-visible) { outline: auto; }
.lilypad { flex: none; display: grid; place-items: center; width: 44px; height: 44px; margin: 0; font-size: 1.15em; font-weight: normal; line-height: 1; cursor: pointer; } /* 🪷: a tap on it opens Goes in, folded or not */
#goes { display: block; flex: 1; width: 100%; min-width: 0; min-height: 44px; padding: 0 14px 0 0; border: 0; border-radius: 0; background: none; outline: none; appearance: none; } /* appearance: Safari's own search field look would set it apart */
#goes:placeholder-shown::-webkit-search-cancel-button { display: none; } /* Chromium and WebKit keep the hidden ✕ its room while the box is empty, which clipped "Where it goes…" beside the grey Drop; it comes back with the first letter */
.tools { flex: none; display: flex; align-items: center; gap: 2px; }
.tools :is(.pen:not([hidden]), .tg, summary) { display: grid; place-items: center; min-width: 44px; height: 44px; margin: 0; padding: 0 8px; box-sizing: border-box; border-radius: 999px; font-weight: normal; line-height: 1; white-space: nowrap; cursor: pointer; } /* each a thumb's target */
.tools .tg { position: relative; color: var(--text); font-size: .95em; }
.tools .pen { color: var(--text); font-family: var(--head, Georgia, serif); }
.tools .pen.b, .tools .pen.h { font-weight: bold; } .tools .pen.i { font-style: italic; }
.tools .pen.lk { color: var(--link); font-family: inherit; } /* [[ ]], # and @: they open a list or make a link */
.tools .pen mark { padding: 0 3px; border-radius: 3px; }
.tools .pen[aria-pressed="true"] { background: color-mix(in srgb, var(--accent) 30%, transparent); } /* the caret's line is a heading, a list or a task: softer than a lit tab, as Notes' bar has it */
@media not (pointer: coarse) { .tools .pen.hide { display: none; } } /* hide keyboard: a touch screen's alone */
.tools .tg:has(:checked) { background: var(--accent); color: var(--on); } /* 🔐 and 18+ light up when on, as Notes' do, without JavaScript */
.tools .tg:has(:focus-visible) { outline: auto; }
.tools .tg:has(:disabled) { cursor: default; } /* a 🔐 folder's box: always private */
.tools summary { position: relative; list-style: none; } /* holds its words for screen readers (.sr, .word, out of sight by position: absolute), so the strip that scrolls clips them: left to the box, one past the screen's edge widened the page */
.tools summary::-webkit-details-marker { display: none; }
.tools .word { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); } /* 🎣 alone, "Tackle box" its tooltip and for screen readers */
.tools details[open] > summary { background: var(--accent); color: var(--on); } /* the open tab, lit */
.inbar .panel { position: absolute; z-index: 4; left: 0; right: 0; top: calc(100% + 6px); max-height: min(60vh, 440px); overflow: auto; padding: 4px 14px; box-sizing: border-box; background: var(--card); color: var(--text); border: var(--bw) solid var(--field); border-radius: 16px; box-shadow: var(--shadow, 0 6px 20px #0006); } /* a tab's panel, a pop-over under the box; 4: over the sticky header and the phone's nav (3), under a toast (5) */
@media (pointer: coarse) {
  .compose.js .inbar .panel { position: fixed; top: auto; bottom: 0; height: var(--kb, 45vh); max-height: none; padding-bottom: 24px; border-width: var(--bw) 0 0; border-radius: 18px 18px 0 0; overscroll-behavior: contain; } /* a phone: in the keyboard's place, its height (editor.js), so the box doesn't move */
  body:has(.compose.js .inbar details[open] > .panel) { padding-bottom: var(--kb, 45vh); } /* room to keep the box where it was over it */
  .compose.js .inbar .panel:has(.find:focus) { bottom: var(--kb, 0px); height: 232px; padding-bottom: 4px; border-width: var(--bw); border-radius: 18px; } /* 😀's search, typed in: the panel stands on the keyboard, not behind it, the search, the tabs and two rows of emoji, so the box and its bar stay in sight above it */
}
.inbar > .send { flex: none; display: flex; align-items: center; gap: 6px; margin-left: auto; } /* Preview and Drop, together at the right, outside the bar, so Drop never moves */
.send > button:not(.primary) { flex: none; min-height: 44px; padding: 0 8px; } /* Preview, where live formatting is off */
.send > .primary { flex: none; min-height: 44px; } /* Drop, and the edit form's Save */
.send > a { display: grid; place-items: center; min-height: 44px; padding: 0 10px; } /* the edit form's Cancel, beside Save */
.compose > .kept { margin-top: -2px; font-size: .85em; } /* the edit form's line under its box, saying earlier versions are kept (Privacy rule 8): small, as a footnote */
@media (hover: hover) {
  :is(.clip, .lilypad, .tools :is(.pen, .tg:not(:has(:checked)), details:not([open]) > summary)):hover { background: var(--tint); }
  .choose:hover { color: var(--hover); border-color: var(--hover); }
}
/* the writing helper's two looks (editor.js): before you write, the bar is 📎, 🪷 Where it goes… whole and every tool, and Drop is grey until there's something to drop; writing, 🪷 folds to its emoji. A tap on 🪷 opens Where it goes again */
.compose.idle:not(#edit) .tools > .tg:has(input[checked]) { order: -1; } /* before you write in the post box (the edit form keeps its order), a 🔐 or 18+ lit when the page came (a 🔐 folder's, or an unsent private drop's) stands first, beside Where it goes: what decides who reads it stays in sight. The attribute, not :checked, so one tapped on never jumps from under the finger */
.compose.typing .goeswrap:not(:focus-within) { flex: 0 0 44px; min-width: 0; }
.compose.typing .goeswrap:not(:focus-within) #goes { opacity: 0; } /* folded to 🪷: no sliver of its words or caret */
.compose.typing .goeswrap:focus-within { flex: 1 0 13em; } /* opened again, it pushes the tools past the strip's end, where Tab and a swipe still reach them */
@container (max-width: 30em) { /* a phone's edit form: Cancel and Save leave Where it goes… no room to show whole, so it starts folded to 🪷, and a tap opens it to the right, never scrolling 🪷 from under the finger */
  .compose.js#edit .goeswrap:not(:focus-within) { flex: 0 0 44px; min-width: 0; }
  .compose.js#edit .goeswrap:not(:focus-within) #goes { opacity: 0; }
}
.field .cm-editor { max-height: var(--room, none); } /* a long drop's words scroll inside the box, so its bar always shows (editor.js) */
.field.clipped .cm-scroller { -webkit-mask: linear-gradient(transparent, #000 28px); mask: linear-gradient(transparent, #000 28px); } /* scrolled down inside the box: the words above fade out under its top edge */
@media (prefers-reduced-motion: no-preference) {
  .compose.js .goeswrap { transition: flex .45s ease, min-width .45s ease; }
}
/* Profile's 📎 Choose a picture: a pill */
.choose { display: inline-flex; align-items: center; flex: none; min-height: 44px; padding: 6px 14px; border: var(--bw) solid var(--link); border-radius: 999px; color: var(--link); font-weight: normal; cursor: pointer; }
.goeslist { position: absolute; z-index: 4; left: 6px; right: 6px; max-height: 352px; overflow: auto; margin: 0; padding: 4px; list-style: none; background: var(--card); color: var(--text); border: var(--bw) solid var(--field); border-radius: 10px; box-shadow: var(--shadow, 0 4px 14px #0005); } /* the Goes in helper's places, over the box's words, just above its bar (goes.js measures it), about eight before it scrolls, the look of the writing helper's suggestions; 4: over the sticky header and the phone's nav (3), under a toast (5) */
.goeslist li { display: flex; align-items: center; min-height: 44px; padding: 0 12px; border-radius: 8px; overflow-wrap: anywhere; cursor: pointer; } /* a thumb's target each */
.goeslist li:hover { background: var(--tint); }
.goeslist [aria-selected="true"] { background: var(--accent); color: var(--on); } /* reached with ↓ and ↑, as the writing helper's suggestion is */
.compose { container-type: inline-size; } /* the box's width, not the screen's, decides when 🎣's rows put their labels over their chips (below) */
.compose:has(#only:checked) .who { display: none; } /* a hidden pond's reply line says the people who run the site read the reply, untrue of a 🔐 one: it goes as you tick, without JavaScript */
.composebar .go { margin-left: auto; display: flex; align-items: center; gap: 14px; } /* Preview and Drop it under a preview, or the edit form's Preview and Save it, at the right */
@media (max-width: 599px) {
  .top { gap: 4px; }
  header nav { position: fixed; bottom: 0; left: 0; right: 0; flex-wrap: wrap; justify-content: space-around; padding: 6px 0 8px; background: var(--card); border-top: var(--bw) var(--dash) var(--border); }
  header nav .ic, .places .ic { font-size: 1.9em; padding: 4px 20px; }
  footer { padding-bottom: 96px; }
  .float { bottom: 84px; } /* above the bar of places */
  section.book { --bar: 4.5rem; } /* a cover page's buttons above it too */
  .top > a { font-size: 1.35em; padding: 4px 2px; }
  .top .primary { padding: 4px 8px; }
  .profile .head { gap: 10px; }
  .profile .head h1 { font-size: 1.2em; overflow-wrap: anywhere; } /* a name fits one line beside the picture on a phone ("Spooky D Monster" at 360px), the longest (24 wide letters) two */
  .profile .head .avatar.big { width: 64px; height: 64px; }
  .profile .head .avatar.big.none { font-size: 36px; }
  .site { font-size: 1.45em; }
  .me { margin-left: 4px; } /* 🔔's bubble sits 4px past its icon: room so it never touches the picture */
  .site .bubble { font-size: .45em; } /* on the smaller name, .35em would be a speck */
  .me .avatar { width: 32px; height: 32px; }
  .by .avatar { position: absolute; }
  .actions { gap: 4px 10px; }
  .tabs { gap: 4px; }
  .tabs a { padding: 5px 6px; } /* Ocean's four tabs fit one row at 360px, Firefox's scrollbar too */
  .tabs.scroll { gap: 0; }
  .tabs.scroll a { padding: 5px 4px; } /* and a profile's six, Georgia and Firefox's scrollbar too: 318px of Firefox's 324 */
  .by .author::after { content: "\a"; white-space: pre; }
  .by:has(.saytap) .author::after { content: none; } .by .saytap + .copy::before { content: "\a"; white-space: pre; } /* a reply's 💭 stays by the name, and the line ends after it */
  .by .share:focus * { margin: 0; }
}
@media (max-width: 340px) { /* a phone zoomed in: four pills of 20px sides are 310px wide */
  header nav .ic, .places .ic { padding: 4px 8px; }
  footer { padding-bottom: 160px; } /* big text wraps the bar to two rows */
  .float { bottom: 160px; } /* the ‹ › pair above it then too */
  .reading > .turn { min-height: 140px; } /* and the bar tall enough to hide it over one row of places: 160 + 4 + 44 - 68 */
}
input[type=file] { width: auto; flex: 1; min-width: 0; max-width: 100%; border: 0; padding: 0; background: none; color: var(--muted); font-size: .9em; } /* a file box is as wide as its words, wider than a phone outside a flex row (/settings); the browsers shorten "No file chosen" to fit */
input[type=file]::file-selector-button { font: inherit; color: var(--link); background: none; border: var(--bw) solid var(--link); border-radius: 999px; padding: 6px 14px; margin-right: 8px; cursor: pointer; }
@media (hover: hover) {
  input[type=file]::file-selector-button:hover { color: var(--hover); border-color: var(--hover); } /* a button to the eye, so it changes as one */
}
.primary.delete, .primary.follow { background: var(--hot); }
@media (hover: hover) {
  .primary:hover { background: var(--hot); } /* hovered, a primary button takes the palette's other bright color (owner): the highlight turns pink, */
  .primary:is(.delete, .follow, .danger-btn):hover { background: var(--accent); } /* and a pink or red one the highlight */
}
/* Deep water's glow, 🐟 Feed the fish's and the water button's, decided here once (owner, 2026-10-29): an aqua rim and a soft blue light past
   the edge, brighter pointed at or reached with Tab. Each draws it as box-shadow: var(--glow), which takes no room, so nothing moves */
.fishtip, .primary.drop { --glow: 0 0 0 1.5px rgb(170 240 255 / .9), 0 0 14px rgb(80 200 255 / .75), 0 0 30px rgb(40 140 255 / .45); --lit: 0 0 0 1.5px #dffaff, 0 0 20px rgb(110 220 255), 0 0 46px rgb(60 160 255 / .7); }
:is(.fishtip, .primary.drop):focus-visible { --glow: var(--lit); }
@media (hover: hover) {
  :is(.fishtip, .primary.drop):hover { --glow: var(--lit); }
}
/* The water button (coponder.md, CSS, The water button): the post box's Drop and Reply, a glass capsule of 🐟 Feed the fish's deep blue
   water and glow, the same on every palette (owner, 2026-10-29), with bubbles rising, light rippling along its bottom, and a goldfish crossing
   behind the word every 12 seconds. A <button> only: the fish and the shine are its ::before and ::after, kept inside it by its own box, and
   the moving water is the empty span.sea inside it. After .primary:hover, so the water outweighs its plain pink. Everything that moves moves
   by transform alone, so no frame restyles or repaints */
.primary.drop {
  --water: #1468b8; --lite: #2794d8; --deep: #0f529e; /* Feed the fish's blues, a shade deeper, so the white word measures 5:1 on it */
  --f: #ffad1f; --fd: #e0560c; /* a goldfish: orange-yellow, its fins and tail a deeper orange */
  --glint: rgb(255 255 255 / .55);
  position: relative; z-index: 1; overflow: hidden; color: #f2fbff; /* its own stacking box, which keeps the fish and the shine under the word, and lifts the glow over the strip's › beside it (.nudge, z-index 1, before it) */
  text-shadow: 0 0 3px var(--deep), 0 1px 2px rgb(0 30 80 / .6); /* the letters keep a dark rim when the fish passes behind them */
  background:
    radial-gradient(closest-side, transparent 62%, rgb(255 255 255 / .16) 80%, transparent 92%) 7px calc(100% + 1px) / 17px 8px repeat-x,
    radial-gradient(75% 60% at 50% 110%, var(--lite), transparent),
    linear-gradient(var(--lite), var(--water) 48%, var(--deep)); /* a still row of light along the bottom, the glow below, the water */
  box-shadow: var(--glow), inset 0 -3px 6px color-mix(in srgb, var(--lite), transparent 50%);
}
.sea { position: absolute; inset: 0; z-index: -2; pointer-events: none; } /* under the fish and the shine: its ::before and ::after are the water that moves */
.sea::before { content: ""; position: absolute; left: 0; right: 0; top: 0; height: calc(100% + 120px);
  background:
    radial-gradient(circle 2.6px at 3px 3px, transparent 55%, var(--glint) 65% 85%, transparent) 26% 0 / 6px 60px repeat-y,
    radial-gradient(circle 2px at 3px 3px, transparent 45%, var(--glint) 60% 85%, transparent) 71% 20px / 6px 40px repeat-y,
    radial-gradient(circle 1.6px at 3px 3px, transparent 35%, var(--glint) 55% 85%, transparent) 88% 40px / 6px 120px repeat-y; } /* three trails of bubbles, 120px taller than the button, which rise 120px a cycle: a whole number of each trail's repeats, so the loop never jumps */
.sea::after { content: ""; position: absolute; left: -54px; right: 0; bottom: -3px; height: 11px;
  background: radial-gradient(closest-side, transparent 62%, rgb(255 255 255 / .2) 80%, transparent 92%) 0 0 / 27px 11px repeat-x; } /* the other row of light, 54px wider, drifting 54px a cycle over the still one: two of its repeats */
.primary.drop::before { content: ""; position: absolute; z-index: -1; left: 0; top: calc(50% - 1px); width: 100%; height: 13px; pointer-events: none; transform: translateX(-1px);
  background:
    radial-gradient(circle 1.3px at 20.5px 5px, #10131c 75%, transparent) no-repeat,
    radial-gradient(circle 2.3px at 20.5px 5px, #fff 75%, transparent) no-repeat,
    radial-gradient(6px 1.6px at 15px 9px, rgb(255 255 255 / .5), transparent) no-repeat,
    radial-gradient(10px 5.2px at 15px 6.5px, var(--f) 35%, color-mix(in srgb, var(--f), var(--fd)) 72%, var(--fd) 88%, transparent) no-repeat,
    radial-gradient(4.5px 3.5px at 13px 2.2px, var(--fd) 70%, transparent) no-repeat,
    conic-gradient(from 227deg at 8px 6.5px, var(--fd) 34deg, transparent 0 52deg, var(--fd) 0 86deg, transparent 0) 0 0 / 9px 13px no-repeat; } /* the fish, 25 by 13 pixels, facing right: its eye, the shine on its belly, its body, its fin and its forked tail */
.primary.drop::after { content: ""; position: absolute; z-index: -1; left: 6px; right: 6px; top: 2px; height: 38%; border-radius: 999px; pointer-events: none; background: linear-gradient(rgb(255 255 255 / .85), rgb(255 255 255 / .3) 30%, rgb(255 255 255 / 0) 50%); } /* the glass's shine, over the fish: a bright edge that fades out before the white letters begin */
.primary.drop:active { transform: translateY(1px); box-shadow: var(--glow), inset 0 3px 6px rgb(0 0 0 / .3); }
.primary.drop:active::after { opacity: .45; }
@media (prefers-reduced-motion: no-preference) {
  .primary.drop::before { transform: translateX(-27px); animation: fish 12s linear infinite; } /* out of sight between crossings */
  .sea::before { animation: rise 12s linear infinite; }
  .sea::after { animation: drift 12s linear infinite; }
}
.compose.js:not(.filled) .send > .drop { background: var(--field); color: var(--muted); text-shadow: none; box-shadow: none; transform: none; cursor: default; } /* grey and still before there's something to drop (editor.js, aria-disabled), in Drop's own place and size; after the water's rules, so it outweighs them, hovered or pressed too */
.compose.js:not(.filled) .send > .drop .sea, .compose.js:not(.filled) .send > .drop::before, .compose.js:not(.filled) .send > .drop::after { display: none; } /* no water, no fish, no shine: the fish's crossing starts again the moment it comes back */
@keyframes rise { to { transform: translateY(-120px); } }
@keyframes drift { to { transform: translateX(54px); } }
@keyframes fish {
  0% { transform: translateX(-27px); }
  12% { transform: translateX(calc(20% - 12px)) translateY(-1px); }
  24% { transform: translateX(calc(45% - 12px)) translateY(.5px); }
  36% { transform: translateX(calc(70% - 12px)) translateY(-1px); }
  50%, 100% { transform: translateX(calc(100% + 2px)); }
}
/* 🐟 Feed the fish (coponder.md, Feed the fish): a maker's tip link in Deep water (owner, 2026-10-29, style 2 of three, "Not even a contest").
   Deep blue water with light rippling inside it (.ripple), a shine sweeping across (.shine), bubbles rising out of it (.bubbles) and an
   aqua rim that glows. Pointed at, the glow brightens, the bubbles quicken and the fish wiggles. Its size never changes, and it looks the same
   on every palette. Everything that moves moves by transform and opacity; with Reduce motion nothing does, and the bubbles stay out of sight */
.fishtip { position: relative; isolation: isolate; display: inline-flex; align-items: center; gap: 8px; padding: 9px 20px 9px 14px; border-radius: 999px; font: 700 .94rem/1.2 ui-rounded, system-ui, -apple-system, "Segoe UI", sans-serif; letter-spacing: .02em; white-space: nowrap; text-decoration: none; vertical-align: middle; text-shadow: 0 1px 2px rgb(0 30 80 / .6); background: radial-gradient(60% 120% at 20% 0%, rgb(160 240 255 / .55), transparent 60%), radial-gradient(50% 100% at 80% 110%, rgb(40 120 255 / .6), transparent 70%), linear-gradient(#2a9fe0, #145fb8); box-shadow: var(--glow), inset 0 1px 0 rgb(255 255 255 / .6); }
.fishtip::before { content: ""; position: absolute; inset: -4px -2px; } /* a 44px tap target */
.fishtip .word { position: relative; z-index: 2; color: #f2fbff; } /* its own color: the shared hover pink reaches only the link round it */
.fishtip svg { flex: none; transform-origin: 60% 50%; filter: drop-shadow(0 0 3px rgb(255 255 255 / .5)); }
.fishtip :is(.ripple, .shine) { position: absolute; inset: 0; border-radius: inherit; overflow: hidden; pointer-events: none; }
.fishtip .shine { z-index: 1; }
.fishtip .ripple::before, .fishtip .ripple::after { content: ""; position: absolute; inset: -60%; background: repeating-radial-gradient(circle at 30% 40%, transparent 0 6px, rgb(255 255 255 / .22) 7px, transparent 9px); mix-blend-mode: soft-light; }
.fishtip .ripple::after { background-position: 40% 60%; opacity: .7; }
.fishtip .shine::after { content: ""; position: absolute; top: -20%; bottom: -20%; width: 35%; background: linear-gradient(90deg, transparent, rgb(255 255 255 / .55), transparent); transform: translateX(-130%) skewX(-20deg); }
.fishtip .bubbles { position: absolute; inset: 0; z-index: 3; pointer-events: none; }
.fishtip i { position: absolute; bottom: 30%; left: 14%; width: 5px; height: 5px; box-sizing: border-box; border: 1px solid rgb(255 255 255 / .85); border-radius: 50%; background: radial-gradient(circle at 35% 35%, rgb(255 255 255 / .9), rgb(255 255 255 / .1) 60%); opacity: 0; }
.fishtip i:nth-child(2) { left: 22%; width: 3.5px; height: 3.5px; animation-delay: .9s; }
.fishtip i:nth-child(3) { left: 17%; width: 4px; height: 4px; animation-delay: 1.7s; }
.fishtip i:nth-child(4) { left: 70%; width: 3px; height: 3px; animation-delay: 1.2s; }
.fishtip i:nth-child(5) { left: 84%; width: 4px; height: 4px; animation-delay: 2.2s; }
@media (prefers-reduced-motion: no-preference) {
  .fishtip .ripple::before { animation: ripple 7s linear infinite; }
  .fishtip .ripple::after { animation: ripple 11s linear infinite reverse; }
  .fishtip .shine::after { animation: sweep 3.6s ease-in-out infinite; }
  .fishtip i { animation: bubble 2.8s ease-in infinite; }
  .fishtip:is(:hover, :focus-visible) i { animation-duration: 1.4s; }
  .fishtip:is(:hover, :focus-visible) svg { animation: wiggle .5s ease-in-out infinite; }
}
@keyframes ripple { to { transform: translate(18%, 10%) rotate(40deg); } }
@keyframes sweep { 0% { transform: translateX(-130%) skewX(-20deg); } 60%, 100% { transform: translateX(260%) skewX(-20deg); } }
@keyframes bubble { 0% { transform: translateY(0) scale(.6); opacity: 0; } 15% { opacity: .9; } 100% { transform: translate(3px, -34px) scale(1.1); opacity: 0; } }
@keyframes wiggle { 0%, 100% { transform: rotate(0); } 25% { transform: rotate(-10deg) translateX(-1px); } 75% { transform: rotate(10deg) translateX(1px); } }
.tipline { margin: 18px 0 4px; } /* under the drop's actions, whose row reaches 10px down */
.end .tipline { text-align: center; } /* a chapter's end page: centred, as its title and Next chapter are */
.lightbox .tipline { margin: 10px 0 2px; } /* a phone's, on its own line under ‹ › and 💬, so that row fits at 360px with big counts and big text */
.fade { overflow: hidden; animation: fade 6s forwards; }
@keyframes fade { 83% { opacity: 1; max-height: 4em; } 100% { opacity: 0; max-height: 0; padding: 0 16px; margin: 0; } }
.copy { -webkit-user-select: all; user-select: all; }
.users .copy { display: inline-block; font-size: .9em; } /* an invite link moves to its own line whole on phones, and breaks inside only when it's longer than a line (240px, big text); .9em fits it whole in 360px */
.body p, .body ul, .body ol, .body pre, .body table, .callout { margin: 0 0 .5em; }
.body ul, .body ol { padding-left: 1.4em; }
.body :is(h1, h2, h3, h4, h5, h6) { font-size: 1em; margin: .5em 0 .25em; }
.body h2, .doc h1, .compose .cm-line.md-h1 { font-size: 1.6em; } .body h3, .doc h2, .compose .cm-line.md-h2 { font-size: 1.35em; } .body h4, .doc h3, .compose .cm-line.md-h3 { font-size: 1.15em; } /* a drop's # is an h2, a level under the page's h1, and a document's (.doc) an h1; the writing helper's headings too */
.doc h4 { font-size: 1em; }
.body h6 { color: var(--muted); }
.body pre { overflow-x: auto; padding: 8px; border-radius: 6px; background: var(--border); }
.body code { font-size: .9em; }
.indent { display: inline-block; max-width: 50%; overflow: hidden; vertical-align: top; white-space: pre; tab-size: 4; } /* an indented line's tabs, a level each, never past half the line on a phone */
.body blockquote, .share:focus * { margin: 0 0 .5em; }
.body blockquote, .share:focus *, .compose .cm-line.md-quote { padding-left: 10px; border-left: 3px solid var(--border); color: var(--muted); } /* the writing helper's quote lines too, without the margin (CodeMirror's lines take none) */
.body table { border-collapse: collapse; }
.body th, .body td { border: 1px solid var(--border); padding: 2px 6px; }
.callout { padding: 6px 10px; border-left: 3px solid var(--accent); border-radius: 6px; background: var(--border); }
.callout-title { font-weight: bold; margin: 0 0 .25em; }
mark { background: #f7e27a; color: #0b0f14; }
.body img, .body video { max-width: 100%; height: auto; border-radius: 8px; }
.body .gif { display: block; } /* a GIF goes under the text before it, as Discord shows them */
.body hr { border: 0; border-top: 1px solid var(--border); }
/* Task boxes (coponder.md): in a bulleted list a box stands where its bullet would, as in Obsidian and GitHub, and with the space after it
   takes the list's 1.4em indent, so its words line up with their next line. On your own drop it's a button in the link color */
.body ul > li:has(> .task:first-child, > p:first-child > .task:first-child) { list-style: none; }
.body ul > li > .task:first-child, .body ul > li > p:first-child > .task:first-child { display: inline-block; width: 1.15em; margin-left: -1.4em; }
.body button.task { position: relative; }
.body button.task::after { content: ""; position: absolute; inset: 0 -.4em; } /* room at its sides to tap: the button is already its line's height, so the box under it starts where it ends */
.body button.task:disabled { cursor: progress; } /* the task helper waits for the server */
.preview { border: 1px dashed var(--muted); }
article.private { border-style: dashed; } /* a private drop isn't out in the ocean yet, like a preview */
.draft { display: grid; } /* the picture, its ×, ALT and number in one cell, laid over it at its corners, so an open ALT's box hangs from the row of pictures, not from one */
.draft > :is(img, video, .n, .x, .alt) { grid-area: 1 / 1; }
.draft :is(img, video) { width: 80px; height: 80px; object-fit: cover; border-radius: 8px; display: block; }
.draft .n { align-self: end; justify-self: start; margin: 4px; padding: 0 6px; border-radius: 6px; background: #000b; color: #fff; font-size: .8em; } /* a comic's page number, in its preview; 🎬 on a picked video */
/* A picture's ALT (owner, 2026-10-29): a small + ALT at the tile's top left, as Bluesky's, ✓ ALT once it has a description; a tap opens its box under the row of pictures, the box growing to make room. */
.drafts { position: relative; }
.drafts:has(.alt[open]) { padding-bottom: calc(5.4em + 10px); }
.alt { align-self: start; justify-self: start; margin: 4px; }
.alt summary { position: relative; display: block; list-style: none; cursor: pointer; }
.alt summary::-webkit-details-marker { display: none; }
.alt summary::before { content: "+ "; content: "+ " / ""; }
.alt:has(textarea:not(:placeholder-shown)) summary::before { content: "✓ "; content: "✓ " / ""; }
.alt summary::after { content: ""; position: absolute; inset: -4px -4px -14px; } /* a bigger target, short of the × at its right */
.alt[open] summary { background: var(--accent); color: var(--on); }
.draft:has(.alt[open]) :is(img, video) { outline: 2px solid var(--accent); outline-offset: 2px; }
.field .alt textarea { position: absolute; left: 12px; right: 12px; bottom: 6px; width: auto; height: 5.4em; margin: 0; padding: 6px 10px; field-sizing: fixed; font-size: .9em; background: var(--bg); border: var(--bw) solid var(--field); border-radius: 12px; outline: revert; resize: none; } /* as the edit form's box is a .field too */
/* The upload helper (static/upload.js): the box outlined while files are dragged over the page, and the bar a press fills. */
.compose.dropping { outline: 2px dashed var(--accent); outline-offset: 2px; border-radius: 10px; }
.compose[inert] :is(.field, .where, .drafts, .composebar) { opacity: .6; } /* while it goes */
.upload { display: flex; align-items: center; gap: 10px; color: var(--muted); font-size: .9em; font-variant-numeric: tabular-nums; }
.upload progress { flex: 1; min-width: 0; height: 6px; border: 0; border-radius: 3px; background: var(--border); appearance: none; }
.upload progress::-webkit-progress-bar { background: var(--border); border-radius: 3px; }
.upload progress::-webkit-progress-value { background: var(--accent); border-radius: 3px; }
.upload progress::-moz-progress-bar { background: var(--accent); border-radius: 3px; }
.draft .x { align-self: start; justify-self: end; margin: 4px; width: 24px; height: 24px; border-radius: 50%; background: #000b; color: #fff; }
.sr { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); }
.inline { width: auto; display: inline; margin: 0 4px 0 0; font-weight: normal; }
.spoiler { background: var(--text); border-radius: 4px; cursor: pointer; }
.spoiler, .spoiler * { color: transparent; }
.spoiler:focus, .spoiler:focus * { background: none; color: inherit; outline: none; }
.share { cursor: pointer; } /* older iPhone Safari passes a tap on a span up to the share helper's listener on document only when it looks tappable */
.share::before { content: "\a0·\a0Share"; color: var(--link); } /* no space before it in the byline, so it never starts a line */
.share[data-said] .copy:first-child::before { content: "✓ Link copied\a"; white-space: pre; } /* the share helper copied it: said on the line under the word, so the word never moves, even centred on a cover page */
.handle { position: relative; -webkit-user-select: all; user-select: all; cursor: pointer; } /* an @handle beside a name: a tap selects it whole and the share helper copies it */
.handle[data-said] { z-index: 2; } /* its pill over the links under it in a drop's card (1), under the header (3) */
.handle[data-said]::after { content: "✓ Copied"; position: absolute; left: 0; top: calc(100% + 3px); padding: 1px 8px; border-radius: 999px; background: var(--text); color: var(--bg); font-size: .75rem; font-weight: bold; white-space: nowrap; pointer-events: none; -webkit-user-select: none; user-select: none; } /* under its start, over what's below, so nothing moves; rem, so a byline's small size doesn't shrink it */
@media (hover: hover) {
  .handle:hover { color: var(--hover); } /* a span, not a link: the shared hover rule doesn't reach it */
}
.muted .share:focus * { font-size: 1em; } /* a pond's Share, in the line under its name: that line's size, not smaller */
section.book .share:focus * { margin: 0; padding: 0; border: 0; } /* a cover page's, centred under its line: a quote's left line has no left edge to stand on there */
@media (hover: hover) {
  .share:hover::before { color: var(--hover); } /* a span, not a link: the shared hover rule doesn't reach it */
}
.share:focus * { display: block; margin: -5px 0 0; }
.share:focus * + * { margin-top: 0; } /* a titled drop's [[link]], a line under its address */
.tap { position: relative; } /* the card holds its link itself, not through article's rule for the menus */
.tap > .by .when::after { content: ""; position: absolute; inset: 0; } /* a drop in a list opens wherever it's tapped, as on X and Bluesky: its time link covers its card, no script, no second link */
.tap :where(a:not(.when), button, summary, .saytap, iframe, .film, pre, .copy, .share, .spoiler, .tap) { position: relative; z-index: 1; } /* above it, what you press, select whole or scroll stays yours; :where lets a rule that places one (.pic > .prev) win */
.tap .actions { pointer-events: none; } /* positioned for its menu, it would cover the link: its gaps, and the counts a visitor sees, open the drop too */
.tap .actions > :not(span) { pointer-events: auto; }
.tackle summary, .cheat summary, .wand summary, .pnote summary { width: fit-content; cursor: pointer; color: var(--link); }
.tackle dl { display: grid; grid-template-columns: auto 1fr; align-items: baseline; gap: 6px 8px; margin: 8px 0; }
.tackle dd { display: flex; flex-wrap: wrap; gap: 6px; margin: 0; }
.tackle dd[hidden], .tackle .tabbed dt { display: none; } /* tabs (editor.js): a row at a time; its label is its tab */
.ttabs { display: flex; gap: 4px; margin: 6px 0 4px; padding: 3px; border-radius: 999px; background: var(--bg); }
.ttabs button { flex: 1; min-height: 38px; border-radius: 999px; color: var(--text); font-size: .9em; white-space: nowrap; }
.ttabs [aria-pressed="true"] { background: var(--accent); color: var(--on); }
.tackle .tabbed { display: block; } .tackle .tabbed dd { margin: 4px 0; }
.tackle .copy, .cheat .copy, .emo .copy { padding: 1px 10px; border: var(--bw) solid var(--field); border-radius: 999px; cursor: pointer; }
.tackle .copy:hover, .cheat .copy:hover, .emo .copy:hover { border-color: var(--accent); }
.writes, .writes dd { min-width: 0; } /* so a long chip ends in … instead of widening its box past the column */
.writes .copy { -webkit-user-select: none; user-select: none; -webkit-touch-callout: none; white-space: nowrap; max-width: 100%; overflow: hidden; text-overflow: ellipsis; vertical-align: top; } /* with the writing helper a tap writes the chip into the box (editor.js), so it no longer selects itself, and a long pond name ends in … on its one line; top, as a clipped box sits on its bottom edge and the line would grow under it */
@container (max-width: 16em) { .tackle.writes dl { grid-template-columns: 1fr; } } /* big text on a phone: each row's label over its chips, so a chip has the whole width for its name before its … */
/* Formatting: cards of a chip and what it makes, as many to a row as fit; sized from their
   words, not a grid's em columns, so big text (whose minimum size em doesn't follow) gets one a row */
.cheat dl { display: flex; flex-wrap: wrap; gap: 10px 12px; margin: 8px 0; }
.cheat dl > div { flex: 0 1 auto; min-width: 9em; }
.cheat dl > div:last-child { flex-basis: 100%; } /* the link's long chip */
.cheat .copy { display: inline-block; }
/* 😀 the emoji browser (coponder.md, The writing helper, 😀 Emoji), as Discord's: a search box and a tab for each group, staying at the panel's top, over every emoji in a grid of thumb-sized buttons, each group under its name */
.emo .used { display: flex; flex-wrap: wrap; gap: 6px; margin: 8px 0; } /* without the writing helper: the emoji you use most, to select and copy */
.ehead { position: sticky; top: -4px; z-index: 1; margin: -4px -14px 0; padding: 10px 14px 0; background: var(--card); }
.ehead .find { min-height: 40px; border-radius: 999px; padding: 6px 14px; }
.etabs { margin-bottom: 0; }
.etabs button { min-width: 0; padding: 0; font-size: 1.1em; } /* nine groups and Recent, an emoji each, sharing the row */
.eh { margin: 10px 4px 2px; color: var(--muted); font-size: .85em; }
.egrid { display: grid; grid-template-columns: repeat(auto-fill, minmax(42px, 1fr)); padding-bottom: 4px; }
.egrid button { height: 44px; padding: 0; border-radius: 10px; font-size: 1.55em; line-height: 1; }
.egrid > p { grid-column: 1 / -1; }
@media (hover: hover) {
  .egrid button:hover { background: var(--tint); }
}
.cheat dd { margin: 2px 0 0 10px; overflow-wrap: normal; } /* "Heading" whole */
.cheat dd * { margin: 0; } /* a quote's <p> too, so every card is as tall as its words */
.cheat dd a { pointer-events: none; } /* the results look like links but never leave the page and the half-written drop */
.cheat dd h2 { line-height: 1.15; }
/* a person's folders, like Obsidian's file list: nested <details>, folders only, the one
   you're on bold; a folder with none inside lines up with the names past the markers */
/* Each tree's title is a line like a folder's, its chevron first in the folders' 44px square and their color, its words muted, what's
   inside it a step in, as inside a folder. Each folds and opens as a folder does, the one the page is in starting open */
.tree summary { cursor: pointer; }
.tree > summary { color: var(--text); } /* the arrow, in the text color as a folder's is */
.tree > summary > :is(a, span) { color: var(--muted); } /* the title muted, so the folders it holds lead the eye */
.tree ul { list-style: none; margin: 0; padding-left: 1.1em; }
.tree a { color: var(--text); }
/* the name twice: folded, plain words, so no tap on the line leaves the page; open, the link (your stream, or their page), the rest of the line folding it */
.tree > summary > a, .tree[open] > summary > span { display: none; }
.tree[open] > summary > a { display: inline; }
.tree [aria-current] { font-weight: bold; }
/* A folder opens like a file browser's (owner, 2026-10-23): its arrow always opens and closes it, a 10px chevron whose 17px margins make
   a 44px square a thumb finds; closed, its name lets a tap through to the line, so it only opens it; open, the name goes in.
   Every line is 44px tall, the title's too, and the title's arrow is the same chevron. */
.tree summary { list-style: none; }
.tree summary::-webkit-details-marker { display: none; }
.tree summary::before { content: ""; float: left; flex: none; box-sizing: border-box; width: 10px; height: 10px; margin: 17px; border: solid; border-width: 0 2px 2px 0; transform: translate(-3px) rotate(-45deg); }
.tree[open] > summary::before, .tree [open] > summary::before { transform: translate(0, -3px) rotate(45deg); }
.tree details:not([open]) > summary > a { pointer-events: none; }
.tree li > a { display: block; margin-left: 44px; padding: 10px 0; min-height: 44px; } /* a wrapped name stays under its first line */
.tree li > details > summary { display: flex; align-items: flex-start; }
.tree li > details > summary > a { padding: 10px 0; } /* only the name: the rest of the line opens and closes it, as the title's does */
.tree > summary { min-height: 44px; padding: 10px 0 10px 44px; }
.tree > summary::before { margin: 8px 17px 0 -27px; } /* hangs in the padding, so a long title's lines line up after it (a folder's line is flex, where a float can't) */
/* A folder's notes (owner, 2026-10-23, wiki/Design/Your home.md, step 2): files past the arrows, as a folder with nothing inside,
   each its first picture small, or 📄, hanging before its words, which wrap under themselves, never leaving the picture alone on a
   line, at most two lines of them; "… more in the folder" muted */
.tree .note a { display: flex; gap: .3em; align-items: flex-start; }
.tree .note a > img, .tree .note a > .ic { flex: none; }
.tree .note a > img { margin-top: .2em; } /* level with the first line of words */
.tree .note a > span:not(.ic) { min-width: 0; display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 2; overflow: hidden; } /* the words, not the link: its padding would show a third line */
.tree .note img { width: 20px; height: 20px; object-fit: cover; border-radius: 3px; }
.tree a.muted { color: var(--muted); }
/* 🪷 Ponds' and 👣 Following's last line, as YouTube's (owner, 2026-10-27): Show more, its chevron ⌄ where the lines' arrows are, so it's
   the list's and not the open line's above it, its words where the names are, past the faces' 20px; it shows the rest in place, under the names before them, and becomes Show less ⌃ at the foot of the list.
   The foot is kept as tall as the line (1lh where a browser knows it), and the line sits in it */
.tree li.rest > details > summary { display: flex; align-items: center; gap: calc(20px + .4em); min-height: 44px; padding: 10px 0; box-sizing: border-box; }
.tree li.rest > details > summary::before { float: none; margin: 0 17px; transform: translateY(-3px) rotate(45deg); }
.tree li.rest > details[open] > summary::before { transform: translateY(3px) rotate(-135deg); }
.tree li.rest > details[open] { position: relative; padding-bottom: 44px; padding-bottom: max(44px, 1lh + 20px); }
.tree li.rest > details[open] > summary { position: absolute; bottom: 0; left: 0; right: 0; }
.tree li.rest > details[open] > summary > :first-child, .tree li.rest > details:not([open]) > summary > :last-child { display: none; }
.tree li.rest > details > ul { padding-left: 0; }
/* 👣 Following's people: a small face, then the name, plain, on one line, cut with … */
.tree a.who { display: flex; align-items: center; gap: .4em; min-width: 0; }
.tree a.who > .avatar { flex: none; width: 20px; height: 20px; margin: 0; font-size: 12px; }
.tree a.who > span:not(.avatar, .new) { overflow: hidden; white-space: nowrap; text-overflow: ellipsis; }
.tree a.who > .new { flex: none; width: 9px; height: 9px; border-radius: 50%; background: #3b82f6; } /* 👣 Following: they made something you haven't seen (owner, 2026-10-28). One blue on every palette, as 🔔's red is: 3.3:1 or more on every palette's page and card */
/* The drag helper (coponder.md, Dragging into folders): the pond a dragged drop is over lights up, a chip moves with the pointer
   (drawn off the screen, where the browser copies it), and a line at the foot of the screen says how it went, above a phone's bar */
.tree li.over > a, .tree li.over > details > summary { outline: 2px solid var(--accent); outline-offset: -2px; border-radius: 8px; background: color-mix(in srgb, var(--accent) 16%, transparent); }
.dragchip { position: fixed; top: -100px; left: 0; max-width: 320px; padding: 6px 14px; border: 2px solid var(--accent); border-radius: 999px; background: var(--card); color: var(--text); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.toast { position: fixed; z-index: 5; bottom: 24px; left: 50%; translate: -50%; width: max-content; max-width: calc(100vw - 32px); box-sizing: border-box; padding: 10px 16px; border: 2px solid var(--accent); border-radius: 12px; background: var(--card); color: var(--text); box-shadow: var(--shadow, 0 6px 20px rgb(0 0 0 / .35)); }
.toast button { margin-left: 10px; }
@media (max-width: 599px) { .toast { bottom: 96px; } }
/* very narrow (a phone with large text), a slimmer cover leaves the words room */
@media (max-width: 340px) {
.shelf:has(> .cover), .pond:has(> .cover), .coverset { grid-template-columns: 64px minmax(0, 1fr); gap: 10px; }
.coverset > :not(.cover) { grid-column: 1 / -1; } /* the form (and the note standing in for a cover) under it: beside it, 142px at 240px, a file button can't wrap and was cut off */
section.book .open > * { padding-inline: 14px; } /* Start reading → stays on one line at 240px with big text */
.top { flex-wrap: wrap; justify-content: flex-end; } /* logged out with big text, Sign up goes under Log in rather than off the screen */
.profile > .cover { display: block; float: none; width: 64px; margin: 0 0 8px; } /* above its name: beside it, ＋ New folder ran off the screen */
a.cover.emoji { padding: 6px 3px; }
.cover.emoji span { font-size: 1.8em; }
.cover.emoji b { font-size: .6em; }
}
/* The trees, all together: wide enough, left of the column; narrower, a drawer out of the left edge, which ☰ in the header opens (owner,
   2026-10-27, as on most websites). It's the browser's own popover, closed by a tap outside it, ✕ or Escape, with no script, and the
   popover's own look is undone beside the column. A browser without popovers (Safari before 17, Firefox before 125) has no ☰, and no trees on a narrow screen. A script
   (static/drawer.js) puts the focus on ✕ when ☰ is pressed from the keyboard, so a tap leaves no ring */
.trees { width: auto; height: auto; margin: 0; padding: 0; border: 0; overflow: visible; background: none; color: inherit; }
.trees > .x { display: none; }
.burger { display: none; align-items: center; justify-content: center; width: 44px; height: 44px; margin: -8px -12px -8px -13px; color: var(--text); } /* a 44px square for a thumb from the screen's edge, its lines in line with the column's, taking no more room in the row than they need: a logged-out row still fits at 360px, and 375px with Georgia */
span.burger { visibility: hidden; } /* logged out on a page with no trees, ☰'s place held, so the site name never moves between pages */
.burger::before { content: ""; width: 18px; height: 14px; box-sizing: border-box; border-block: 2px solid; background: linear-gradient(currentColor 0 0) center / 100% 2px no-repeat; } /* ☰ drawn, not a character: the same three lines in every font */
@supports selector(:popover-open) {
  .burger { display: flex; }
  @media (min-width: 1100px) { .burger { display: none; } body:has(main .focus) .burger { display: flex; } }
  @media (min-width: 1240px) { body:has(main .focus) .burger { display: none; } }
}
@supports not selector(:popover-open) { @media (max-width: 1099px) { .trees { display: none; } } }
@media (min-width: 1100px) {
  main { position: relative; }
  .trees { display: block; position: absolute; inset: 12px calc(100% + 24px) 0 auto; width: clamp(220px, 50vw - 348px, 340px); } /* 36px from the window's edge, as wide as that leaves, 340px at most */
  .trees.drawer { display: none; } /* the viewer's own on a page with none of its own, Settings say: the ☰ drawer's alone, so a computer's pages are as they were */
  .trees > div { position: sticky; top: 86px; max-height: calc(100vh - 98px); overflow-y: auto; overscroll-behavior: contain; scrollbar-color: var(--muted) transparent; } /* as YouTube's side panel (owner, 2026-10-27): in view under the header as the page scrolls, and taller than the window, it scrolls with its own bar while the page stays put; the bar in the palette's colors, not a white one beside the dark trees (Firefox), light enough to see */
}
/* Beside a drop it stands as far out as the right column, clear of the ‹ › pair (60px out), so it waits for 1240px as that column does */
main:has(.focus) > .trees { display: none; } /* a rule of its own: a browser without :has() drops the whole rule */
@media (min-width: 1240px) {
  main:has(.focus) > .trees:not(.drawer) { display: block; right: calc(100% + 72px); width: clamp(240px, 50vw - 396px, 340px); } /* as wide as .side across from it, never under 240px */
}
/* The drawer: the full height of the screen, over the header and the bar of places, leaving a strip of the dimmed page to tap, but never
   under 280px wide, so a phone with big text has the whole screen and ✕ (owner: an ✕ for when there's no outside to tap); taller than
   the screen, it scrolls by itself, its ✕ pinned at its top, where ☰ is on a phone, and the page behind stays still */
main > .trees:popover-open { display: block; position: fixed; inset: 0 auto 0 0; width: min(320px, max(100% - 56px, min(100%, 280px))); height: auto; padding: 0 12px 24px 0; overflow-y: auto; overscroll-behavior: contain; scrollbar-color: var(--muted) transparent; border-right: var(--bw) var(--dash) var(--border); background: var(--bg); }
.trees:popover-open > .x { display: flex; position: sticky; top: 0; z-index: 1; margin: 0 -12px 0 0; padding: 6px 0; border-bottom: var(--bw) var(--dash) var(--border); background: var(--bg); }
.trees .x > button { width: 44px; height: 44px; color: var(--text); font-size: 1.35em; } /* the drawer's ✕, at the size of the header's icons */
.trees:popover-open > div { position: static; max-height: none; overflow: visible; }
.trees::backdrop { background: rgb(0 0 0 / .5); }
html:has(.trees:popover-open) { overflow: hidden; }
.trees :focus-visible { outline-offset: -2px; } /* the keyboard's ring inside the line: the column's edges, and the drawer's, cut one drawn outside it (Firefox, WebKit) */
@media (prefers-reduced-motion: no-preference) { main > .trees:popover-open { animation: drawer .2s ease-out; } }
@keyframes drawer { from { translate: -100%; } }
/* Beside a drop, wide enough: On this page, ▶ Up next and 🕸️ Threads from here, right of the column past the ‹ › pair (60px out), staying in view where it starts as you scroll */
.side { display: none; }
@media (min-width: 1240px) {
  main:has(.focus) { display: flow-root; } /* the first card's top margin stays inside, so the columns on both sides start level with the card */
  .side { display: block; position: absolute; top: 12px; bottom: 0; left: calc(100% + 72px); width: min(340px, 50vw - 396px); }
  .side > div { position: sticky; top: 86px; max-height: calc(100vh - 98px); overflow-y: auto; } /* 86: under the header, where it starts; taller than the window, it scrolls by itself */
  .side section + section { margin-top: 26px; }
  .side h2 { margin: 0 0 8px; color: var(--muted); }
  .side h2 a { color: var(--text); }
  .side .contents { margin: 0; }
  .side .contents li { padding-block: 6px; }
  .side .contents a { color: var(--text); } /* calm beside the drop: the links are the whole list */
}
/* On this page: beside a drop on a wide screen, and at the top of /privacy */
.toc ol { list-style: none; margin: 0; padding-left: 12px; border-left: 2px solid var(--border); }
.toc li { padding: 4px 0; line-height: 1.3; }
.toc .sub { padding-left: 1em; }
.toc a { color: var(--muted); }
nav.toc p { margin: 0 0 6px; }
/* 🕸️ Threads from here: the old web's frame, for the web's own parts only, so a frame means a doorway.
   A thread you've opened takes the one change a browser lets a visited link have: its color */
.oldweb { margin: 0 4px 4px 0; border: 2px solid var(--accent); border-radius: 4px; background: var(--card); box-shadow: 4px 4px 0 color-mix(in srgb, var(--accent) 35%, transparent); } /* 4px: room for the shadow */
.oldweb > h2 { margin: 0; padding: 4px 10px; font-size: 1em; background: var(--accent); color: var(--on); }
.oldweb ul { margin: 0; padding: 2px 12px; list-style: none; }
.oldweb li { padding: 7px 0; line-height: 1.3; }
.oldweb li + li { border-top: 1px dotted var(--border); }
.oldweb a { text-decoration: underline; text-underline-offset: 3px; }
.oldweb a:visited { color: var(--hot); }
@media (hover: hover) {
  .oldweb a:visited:hover { color: var(--text); } /* a thread you've opened is pink already: hovered, it turns the text color */
}
.oldweb .kind { display: block; font-size: .82em; color: var(--muted); }
.oldweb > p { margin: 0; padding: 0 12px 8px; }
.focus + .threads { margin: 16px 4px 18px 0; } /* under the drop on a narrower screen */
@media (min-width: 1240px) { .focus + .threads { display: none; } }
/* Wander: 🧵 your trail, a muted line over the drop, each drop cut short so the line stays a line or two; under the drop, the webring bar,
   ◀ Back and 🎲 Wander in the old web's frame, never pink: they're the way on, not a place you've been */
.yourtrail { margin: 12px 0 10px; font-size: .9em; line-height: 1.5; color: var(--muted); }
.yourtrail a { display: inline-block; max-width: 14em; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; vertical-align: bottom; color: var(--muted); text-decoration: underline dotted; text-underline-offset: 3px; }
.wander { display: flex; flex-wrap: wrap; justify-content: center; gap: 6px 32px; margin: 16px 4px 18px 0; padding: 8px 12px; }
.wander a { font-weight: bold; }
.wander a:visited { color: var(--link); }
@media (hover: hover) {
  .wander a:visited:hover { color: var(--hover); } /* ◀ Back and 🎲 Wander are never pink at rest, so they take the pink on hover, opened or not */
}
/* 🕸️ Web (web.html): from 1100px, where the pond map spreads too, the drop's web drawn past the column, centered on it: five columns, the drop
   in the middle filled with the highlight color, its threads beside it, theirs in the outer columns, fainter, and the server's lines under
   them (a stretched <svg>, its strokes kept even). Each box sits in its rows by class, its words cut after three lines, two further out.
   Narrower, the threads box instead */
.webhead { text-align: center; }
.web { display: none; }
.web + .threads { margin: 16px 4px 12px 0; }
@media (min-width: 1100px) {
  .web { display: block; --w: min(100vw - 48px, 1200px); width: var(--w); margin: 18px 0; margin-left: calc(288px - var(--w) / 2); }
  .web + .threads, .webnote { display: none; }
}
.webmap { position: relative; display: grid; grid-template-columns: repeat(5, 1fr); grid-auto-rows: minmax(6.4em, 1fr); } /* rows alike, each as tall as the tallest needs: the lines meet the boxes with big text too */
.webmap svg { position: absolute; inset: 0; width: 100%; height: 100%; }
.webmap line { stroke: var(--accent); stroke-width: 2; stroke-dasharray: 6 5; vector-effect: non-scaling-stroke; }
.webmap line.far { opacity: .5; }
/* 🧬 Timeline (admin.html): everyone who joined, drawn as the distro timeline is, in a box that scrolls both ways; from 1100px spread past the
   column, as a pond's map is. Each branch under a top account takes a pond cover's hue (--hue), mixed toward the words so it reads on light and
   dark. Lit (the script's .on): the account and its whole branch, in the pink */
.timeline { overflow: auto; max-height: 75vh; margin: 8px 0; border: var(--bw) solid var(--border); border-radius: 10px; background: var(--card); overscroll-behavior: contain; }
.timeline svg { display: block; touch-action: manipulation; --line: var(--accent); } /* no double-tap zoom, so a quick second tap opens the tree */
.timeline [class*="hue"] { --line: color-mix(in oklab, hsl(var(--hue) 75% 58%) 80%, var(--text)); }
.timeline .day { stroke: var(--border); stroke-width: 1; }
.timeline .week { stroke: var(--field); stroke-width: 2; }
.timeline text { font-size: 12px; fill: var(--text); paint-order: stroke; stroke: var(--card); stroke-width: 4px; stroke-linejoin: round; }
.timeline .when { fill: var(--muted); }
.timeline .left { text-anchor: end; } /* a name that would run past today, left of its dot */
.timeline .axis rect { fill: var(--card); } /* the days, kept at the top of the view by the script, over the lines */
.timeline path { fill: none; stroke: var(--line); stroke-width: 3; stroke-linecap: round; }
.timeline path.up { stroke-width: 2; }
.timeline path.filled { stroke-dasharray: 3 4; }
.timeline circle { fill: var(--line); }
.timeline .deleted > a { opacity: .35; }
.timeline .suspended > a { --line: var(--danger); } /* its own line, not its branch's */
.timeline .on { --line: var(--hot); }
.timeline .on path { stroke-width: 5; }
.timeline .on path.up { stroke-width: 3; }
.timeline .on > a text { font-weight: bold; }
.timeline .zoom { position: sticky; top: 0; left: 0; z-index: 1; padding: 8px 10px 0; background: var(--card); border-bottom: var(--bw) solid var(--border); } /* stuck to the box's top left as the chart scrolls under it, so who you lit shows */
.timeline .zoom p { margin: 0 0 6px; }
.timeline .chartinfo { height: 2.6em; line-height: 1.3; overflow: hidden; display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 2; } /* always two lines high: a longer name never moves the chart under a finger between two taps */
.timeline .zoom button { min-width: 44px; min-height: 36px; padding: 0 14px; border: var(--bw) solid var(--field); border-radius: 999px; } /* −, ＋ and Fit, bordered pills */
.timeline .zoom button:hover { border-color: var(--accent); }
.timeline svg a:focus-visible { outline: none; }
.timeline svg a:focus-visible text { text-decoration: underline; } /* the label underlined instead of a box round the whole line */
@media (min-width: 1100px) { .timeline { --w: min(100vw - 48px, 1400px); width: var(--w); margin-left: calc(288px - var(--w) / 2); } }
.webmap > .oldweb { position: relative; place-self: center; width: 74%; margin: 5px 0; padding: 8px 10px; font-size: .92em; line-height: 1.3; } /* 5px: a gap between boxes stacked in neighbouring rows, inside each row, so the rows stay alike and the lines still meet them */
.webmap > .oldweb a { display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 3; overflow: hidden; }
.webmap > .oldweb > .muted { font-size: .86em; } /* under the words, which are a block, beside a red 18+ */
.webmap > .far { border-color: color-mix(in srgb, var(--accent) 45%, var(--card)); box-shadow: 4px 4px 0 color-mix(in srgb, var(--accent) 15%, transparent); }
.webmap > .far > * { opacity: .7; }
.webmap > .far a { -webkit-line-clamp: 2; }
.webmap > .here { position: absolute; left: 50%; top: 50%; translate: -50% -50%; width: 16%; margin: 0; padding: 10px 12px; font-size: 1em; background: var(--accent); color: var(--on); }
.webmap > .here a, .webmap > .here a:visited { font-family: var(--head); font-size: 1.15em; color: var(--on); }
.webmap > .here > .muted { color: inherit; opacity: .8; }
.webmap > .c0 { grid-column: 1; }
.webmap > .c1 { grid-column: 2; }
.webmap > .c3 { grid-column: 4; }
.webmap > .c4 { grid-column: 5; }
.webmap > .r0 { grid-row-start: 1; }
.webmap > .r1 { grid-row-start: 2; }
.webmap > .r2 { grid-row-start: 3; }
.webmap > .r3 { grid-row-start: 4; }
.webmap > .r4 { grid-row-start: 5; }
.webmap > .r5 { grid-row-start: 6; }
.webmap > .s2 { grid-row-end: span 2; }
@media (max-width: 1099px) { .widetab:not(.on) { display: none; } } /* 🗺️ Map and 🕸️ Web; a map's own tab, lit, stays, so a map opened on a phone says what it is */
/* A pond's 🗺️ Map (the pool template in community.html): every pond inside it a pool, a pool inside a pool tinting the water a little more, so deeper
   ponds sit in deeper water; each holds its first drops, a picture as a square, words as a chip. From 1100px it spreads past the column, centered on
   it, the top pools side by side, 340px each, as many as fit, the pond's own drops at the column's width; narrower, one under another */
.map { margin: 12px 0; }
.pools, .pads { list-style: none; margin: 0; padding: 0; }
.pools { display: grid; gap: 12px; }
.pool { min-width: 0; padding: 10px 14px 14px; border-radius: 18px; background: color-mix(in srgb, var(--link) 7%, transparent); border: var(--bw) solid color-mix(in srgb, var(--link) 22%, transparent); }
.pool h2 { margin: 0; font-size: 1.1em; overflow-wrap: anywhere; }
.pool .pool h2 { font-size: 1em; }
.pool h2 a { color: var(--text); }
.pool > .muted { margin: 2px 0 8px; font-size: .9em; }
.pool > .muted:last-child { margin-bottom: 0; } /* "Nothing here yet.", or Its own map: nothing under it */
.pool h2 + .pools, .pads + .pools { margin-top: 10px; } /* a pool's heading, or its drops, then the pools inside it */
.pads { display: flex; flex-wrap: wrap; align-items: center; gap: 6px; }
.pads li { display: flex; align-items: center; gap: 4px; min-width: 0; max-width: 100%; }
.pads a { min-width: 0; padding: 4px 12px; border-radius: 999px; background: color-mix(in srgb, var(--card) 70%, transparent); border: var(--bw) solid color-mix(in srgb, var(--link) 35%, transparent); color: var(--text); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.pads a:has(img) { flex: none; padding: 0; width: 56px; height: 56px; border-radius: 12px; }
.pads img { display: block; width: 100%; height: 100%; object-fit: cover; }
@media (min-width: 1100px) {
  .map { --w: min(100vw - 48px, 1400px); width: var(--w); margin-left: calc(288px - var(--w) / 2); }
  .map > .pads { max-width: 576px; margin-left: auto; margin-right: auto; }
  .map > .pools { grid-template-columns: repeat(auto-fit, 340px); justify-content: center; align-items: start; }
}
/* The writing helper (editor/main.js): CodeMirror over the box's textarea, or the invite tree's Handle box (.lookup), looking like it; the class beats CodeMirror's own rules */
:is(.compose, .lookup) .cm-editor { background: var(--card); border: var(--bw) solid var(--field); border-radius: 10px; }
:is(.compose, .lookup) .cm-editor.cm-focused { outline: auto; }
:is(.compose, .lookup) .cm-scroller { font: inherit; }
:is(.compose, .lookup) .cm-content { padding: 8px 10px; caret-color: var(--text); }
.field .cm-editor { border: 0; border-radius: 22px 22px 0 0; background: none; } /* in the post box, the box is .field, its line of 📎 and Drop included */
.field .cm-editor.cm-focused { outline: none; } /* .field shows it */
.field .cm-content { min-height: 3.6em; padding: 12px 16px 2px; } /* as the plain box in it */
:is(.compose, .lookup) .cm-line { min-height: 1lh; padding: 0; } /* text where the plain box has it; in the drop box a line of only hidden marks (a quote's lone >) keeps its height */
.compose .cm-placeholder { color: var(--muted); }
.compose.reply.folded > :not(.field), .compose.reply.folded .inbar { display: none; } /* a reply box folded to its one line (editor/main.js): the text box alone, no 📎 or Reply, until it opens */
.compose.reply.folded .cm-content { min-height: 0; padding: 12px 18px; } /* a 48px line */
/* ✨ Style your words (coponder.md, The writing helper): the first of the bar's tools, the post box's and the edit form's, its panel every mark */
.styles { padding: 8px 0 10px; } /* in the tab's panel, as 🎣 Tackle box's and Formatting's are */
.styles > div { display: flex; gap: 6px; margin: 0 0 7px; } /* the mockup's rows, the owner's yes: Heading, Subheading and Body; the marks on words; the line marks; the six colors; the effects and plain */
.styles > div > button { flex: 1; min-width: 0; min-height: 42px; padding: 0 4px; border-radius: 12px; background: color-mix(in srgb, var(--field) 60%, transparent); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.styles > div > :where(button:not([name=color])) { color: var(--text); } /* a color keeps its own (its nc- class) */
.styles .hh { font: bold 1.1em var(--head); } .styles .sh { font: bold 1em var(--head); }
.styles mark { padding: 0 3px; border-radius: 3px; }
.styles .sp { color: var(--muted); background: repeating-linear-gradient(45deg, transparent 0 3px, #0002 3px 6px), color-mix(in srgb, var(--field) 60%, transparent); }
.styles .cd { font-family: ui-monospace, monospace; font-size: .9em; }
.styles .dots { gap: 5px; } .styles .dots > button { padding: 0 1px; font-size: .8em; font-weight: bold; } /* each name in its own color (its nc- class) */
.styles .moves > button { font-weight: bold; }
.styles :is(.dots, .moves) { flex-wrap: wrap; } .styles :is(.dots, .moves) > button { flex: 1 0 auto; } /* a name or an effect whole, never cut to …: where the six don't fit a line (a narrow phone, big text, a wider font), the row wraps */
.styles [name=plain] { color: var(--muted); font-size: .85em; }
.styles [aria-pressed="true"] { background: var(--accent); color: var(--on); } /* lit, as a tab is: the caret's kind of line, the mark the words are in */
.styles p { margin: 8px 0 0; font-size: .85em; }
.md-h { font-weight: bold; font-family: var(--head); }
.md-b { font-weight: bold; } .md-i { font-style: italic; } .md-s { text-decoration: line-through; }
.md-a { color: var(--link); }
.md-mono { font-family: monospace; font-size: .9em; } /* code, in the browser's monospace like code on a drop */
.md-q { color: var(--muted); }
.md-hl { background: #f7e27a; color: #0b0f14; } /* as mark */
.md-hl.md-mark { color: #6b5a10; } /* the == on yellow: faded, still readable */
.md-sp { background: var(--text); color: var(--bg); border-radius: 4px; } /* the drop's spoiler bar, its words still readable to its writer */
.md-sp.md-mark { color: var(--bg); opacity: .6; }
.md-mark { color: var(--muted); opacity: .8; } /* # ** [[ ==: faded, on the lines you are writing on */
/* Like the drop (its heading sizes and quote bar are with .body's): marks hidden off the lines you're on (editor/main.js) */
.md-hide { display: none; }
.md-to::before { content: "→"; color: var(--link); } /* [[!pens]] reads →pens, as on the drop */
/* the front page, logged out: the pitch, files and folders explained once, then the ⭐ shelf and the stream */
.pitch h1 { font-size: 2.1em; line-height: 1.15; margin-bottom: .3em; }
.lede { margin-top: 0; font-size: 1.25em; }
.how { display: grid; gap: 12px; margin: 1.2em 0; padding: 0; list-style: none; }
.how li { display: grid; grid-template-columns: 2em minmax(0, 1fr); gap: 10px; }
.how span { font-size: 1.5em; line-height: 1.1; text-align: center; }
.how p { margin: 0; }
.cta { display: flex; flex-wrap: wrap; align-items: center; gap: 10px 18px; }
.shelfhead { margin: 1.4em 0 .2em; font: 700 1.6em/1.25 var(--head); font-size-adjust: .5; font-synthesis: none; } /* .title's font, bigger than the cards' under it */
.shelfhead + .muted { margin-top: 0; }
/* A wide screen's ⭐ shelf, like a bookshop window: up to six covers a row, centered on the column, the heading and the words
   staying in it. Under 1100px, the cards as everywhere else */
@media (min-width: 1100px) {
  .pitch ~ .shelves { container: covers / inline-size; --w: clamp(150px, 9vw, 200px); display: grid; grid-template-columns: repeat(auto-fit, var(--w)); justify-content: center; gap: 28px 20px;
    width: calc(6 * var(--w) + 100px); margin: 16px 0 8px calc(50% - 3 * var(--w) - 50px); }
  .pitch ~ .shelves:not(:has(> :nth-child(4))) { grid-template-columns: repeat(3, minmax(0, var(--w))); width: auto; margin-left: 0; justify-content: start; } /* three or fewer: under the heading, from its edge, and never past the column's other edge */
  .pitch ~ .shelves .cover.emoji span { font-size: 3em; }
  .pitch ~ .shelves .cover.emoji b { font-size: .95em; }
  .pitch ~ .shelves .title { margin: 12px 0 2px; font-size: 1em; }
  .pitch ~ .shelves .meta { margin: 0; }
}
/* Covers: the cards of a shelf named covers (the wide ⭐ shelf above, a person's row of covers below) each its cover over its
   name. A comic's first page or a gallery's first pictures stand in for a cover it lacks, and its description and first lines
   wait on its page. One set of rules for both, as each is a container named covers only where it shows covers */
@container covers (min-width: 0) {
  .shelves > .shelf { display: flex; flex-direction: column; align-items: stretch; gap: 0; margin: 0; padding: 0; background: none; border: 0; }
  .shelves > .shelf > div { display: contents; } /* its name and pictures join the cover's column, to be put in order */
  .shelves :is(.body, .peek), .shelves > .shelf:has(> .cover) :is(.page, .grid) { display: none; }
  .shelves .cover.fold { margin-top: calc((1.6 - 1.08) * 100%); } /* a folder stands on the shelf beside the covers, its name in line with theirs */
  .shelves :is(.page, .grid) { order: -1; margin: 0; aspect-ratio: 5 / 8; overflow: hidden; border-radius: 3px 8px 8px 3px; background: var(--card); }
  .shelves :is(.cover:not(.fold) :is(img, video), .cover.emoji, .page, .grid) { box-shadow: var(--shadow, 0 0 #0000), 0 6px 18px rgb(0 0 0 / .25); }
  .shelves .grid { grid-template-columns: 1fr; grid-auto-rows: 1fr; gap: 2px; }
  .shelves .grid:has(> :nth-child(4)) { grid-template-columns: 1fr 1fr; } /* fewer, two across would be tall slivers */
  .shelves .grid:has(> :nth-child(4)) > :last-child:nth-child(odd) { grid-column: span 2; }
  .shelves :is(.page, .grid a) { min-height: 0; }
  .shelves :is(.page, .grid a) :is(img, video) { height: 100%; aspect-ratio: auto; border-radius: 0; }
}
/* A person's row of covers (coponder.md, A person's row of covers): on a phone, where the trees are in the ☰ drawer, their folders in one row
   that scrolls sideways from the column's edge to the screen's, stopping at each cover, its bar only with a mouse. From 1100px
   its covers are cards on the desk among the drops (below) */
.shelves.row { container: covers / inline-size; display: flex; gap: 12px; overflow-x: auto; scroll-snap-type: x mandatory; scroll-padding-inline: 12px; margin: 0 -12px; padding: 4px 12px 14px; scrollbar-width: none; }
.shelves.row > * { flex: 0 0 96px; scroll-snap-align: start; }
.shelves.row .title { display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 2; overflow: hidden; margin: 8px 0 0; font-size: .85em; } /* two lines, then … */
.shelves.row .cover.fold { margin-top: 0; aspect-ratio: 5 / 8; } /* as tall as a book: every cover the same size, so no empty band shows over or under a run of folders */
.shelves.row .cover.emoji b { display: none; } /* its name is right under it */
.shelves.row > a { display: flex; align-items: center; justify-content: center; align-self: flex-start; aspect-ratio: 5 / 8; box-sizing: border-box; padding: 8px; border: var(--bw) solid var(--border); border-radius: 3px 8px 8px 3px; background: var(--card); text-align: center; }
@media (pointer: fine) { .shelves.row { scrollbar-width: thin; scrollbar-color: var(--border) transparent; } }
/* The desk (coponder.md, The desk, on a wide screen): a person's page and a pond's. From 1100px the head (a profile, a pond's
   name and words) and the box stand on the left, the trees under them, or, from 1400px with many lines in them (.many), in a
   column of their own on the far left; the tabs and the cards fill the rest. The grid's first two rows are the tabs' and the
   notes' under them (a pond's rules, a Wall's hint) alone, so the head's extra height goes to the third, where the cards start
   right under them. Under 1100px the wrappers are nothing,
   the cards are hidden and a phone's page is the column it was, the pile a person's row of covers, a pond's folder cards, or
   nothing */
.tabbar, .notes, .work { display: contents; }
@media not all and (min-width: 1100px) { .pile:not(.shelves), .pile > .wc, .span > h2, .tabs > .views { display: none; } }
.tabs > .views { margin-left: auto; } /* 💧 or 📅, the desk's view, the row's last: right of 🪷 Add and ↕ Arrange, at the end with none */
.tabs > .tools + .views { margin-left: 0; }
.tabs > form.views button { padding: 5px 14px; border-radius: 999px; } /* as a tab, logged in; logged out it's a link, a tab already */
@media (min-width: 1100px) {
  body:has(> main.desk) { --side: 340px; --gap: 40px; --cards: calc(var(--side) + var(--gap)); max-width: none; padding: 0 24px; } /* the columns' widths, here for the footer too, which stands outside main: where the cards start */
  body:has(> main.desk) > :is(header, footer) { max-width: 576px; margin: 0 auto; } /* the header as it is everywhere */
  main.desk { display: grid; grid-template-columns: var(--side) minmax(0, 1fr); grid-template-rows: auto auto auto auto 1fr; column-gap: var(--gap); align-items: start; }
  main.desk > .profile { grid-area: 1 / 1 / 4; }
  main.desk > .tabbar { display: block; grid-area: 1 / 2; }
  main.desk > .notes { display: block; grid-area: 2 / 2; }
  main.desk > .compose { grid-area: 4 / 1; }
  main.desk > .trees { grid-area: 5 / 1; position: static; inset: auto; width: auto; margin-top: 12px; }
  main.desk:not(.many) > .trees > div { position: static; max-height: none; overflow: visible; } /* few: they scroll with the page */
  main.desk > .work { display: block; grid-area: 3 / 2 / 6; }
  /* Held (owner, 2026-10-28): in 📅 Calendar view only the cards scroll. The header's band runs the window's width, so no card
     shows beside it, and the tabs stick under it. The left column's parts can't share one box (the tabs come between them on a
     phone), so each sticks under the one above it, at the heights the desk helper measures (held, --hd and the rest). The trees
     take the rest of the window, at least 160px, and scroll by themselves. Taller than the window even so, the column rises with
     the page until its foot shows, then stays. The footer stands under the cards, beside the column, in a last row of the grid's
     own, so at the page's end it pushes none of the column's parts up into the one above */
  body:has(> main.desk.held)::before { content: ""; position: fixed; z-index: 2; inset: 0 0 auto; height: var(--hd); background: inherit; } /* the band, the page's own background behind the header (3), over the cards. Fixed: hung from the header, Firefox let the page scroll 12px past its end */
  body:has(> main.desk.held) > footer { max-width: none; margin: calc(-1 * var(--fh)) 0 0 var(--cards); } /* in the row below, under the cards */
  main.desk.held::after { content: ""; grid-area: 6 / 1; height: var(--fh); }
  html:has(> body > main.desk.held) { scroll-padding-top: calc(var(--hd) + var(--tb) + 12px); } /* a card reached with Tab, or a #link, lands under the tabs */
  main.desk.held { --room: calc(100vh - var(--hd) - var(--ph) - var(--ch) - 12px); --top: min(var(--hd), 100vh - var(--ph) - var(--ch) - var(--th)); }
  main.desk.held > .tabbar { position: sticky; z-index: 2; top: calc(var(--hd) - var(--bw)); background: var(--bg); } /* up to the header's line, which it stays under, so no card shows through beside it */
  main.desk.held > :is(.notes, .work) { isolation: isolate; } /* what scrolls goes under the tabs, a folder's front (2) too */
  main.desk.held > :is(.profile, .compose, .trees) { position: sticky; }
  main.desk.held > .profile { top: var(--top); }
  main.desk.held > .compose { top: calc(var(--top) + var(--ph)); }
  main.desk.held > .trees { top: calc(var(--top) + var(--ph) + var(--ch)); margin-top: 0; padding-top: 12px; } /* its 12px inside it: Firefox scrolls a sticky part's margin past the page's end */
  main.desk.held > .trees > div { position: static; max-height: max(160px, var(--room)); overflow-y: auto; }
  main.desk:not(.plain) .work > article { display: none; } /* the column's drops: the cards are them */
  main.desk:not(.plain) :is(.pile, .work > .shelves) { container: covers / inline-size; --w: clamp(150px, 9vw, 190px); display: grid; grid-template-columns: repeat(auto-fill, minmax(var(--w), 1fr)); gap: 0 22px; align-items: start; overflow: visible; margin: 22px 0 0; padding: 0; scroll-snap-type: none; } /* the pile, and the Ponds tab's covers */
  main.desk:not(.plain) :is(.pile, .work > .shelves).packed { grid-auto-rows: 4px; } /* desk.js gives each card its span */
  main.desk:not(.plain) :is(.pile, .work > .shelves) > * { padding-bottom: 30px; } /* the room under a card, in it: desk.js measures it with the card */
  main.desk .pile > a { align-self: start; aspect-ratio: 5 / 8; padding: 8px 8px 30px; border: 0; background: var(--card) content-box; } /* +N more, a cover's size, its room under it */
  main.desk:not(.plain) :is(.pile, .work > .shelves) .title { margin-top: 10px; font-size: .95em; }
  main.desk:not(.plain) :is(.pile, .work > .shelves) .cover.fold { margin-top: 0; aspect-ratio: 1 / 1.08; } /* the folder itself, as everywhere */
  main.desk :is(.pile, .work > .shelves, .wbook) .cover.emoji b { display: -webkit-box; font-size: 1em; }
  main.desk :is(.pile, .work > .shelves, .wbook) .cover.emoji span { font-size: 3em; }
  main.desk:not(.plain) :is(.pile, .work > .shelves) .meta { margin: 2px 0 0; font-size: .8em; } /* a pond's members, small under its name, as a card's time */
  main.desk .work > .tiles { grid-template-columns: repeat(auto-fill, minmax(180px, 1fr)); gap: 10px; } /* a gallery's wall: more squares across */
  main.desk .work > .contents { max-width: 760px; } /* a book's or a comic's lines, at a reading width */
  main.desk.plain > .work > :not(.map) { max-width: 600px; } /* a pond's Queue, Log and Arrange: its column, in the desk's frame, so the tabs stay where they were tapped */
  main:not(.desk) :is(.span > h2, .shelves.row) { display: none; } /* 💧 Drip view, the page as it was: no Folders heading, a pond's folders the column's and a person's the trees beside it */
  main.desk .work > .map { width: auto; margin-left: 0; } /* the map fills the desk's room, beside the head */
  .span > h2 { margin: 34px 0 14px; font: 700 1.25em/1.2 var(--head); } /* a section's heading: Folders, Pinned, Today, This week, a month, a year */
  .span:first-child > h2 { margin-top: 24px; }
  main.desk:not(.plain) .span > .pile { margin-top: 0; }
  main.desk :is(.wcap, .span .shelf .title, .span .shelf .meta) { text-align: center; } /* the name and the date under a card, centred, as Apple Notes' gallery has them (owner, 2026-10-28) */
  .wby { justify-content: center; }
  .wyt .wf > img { aspect-ratio: 16 / 9; min-height: 0; } /* a YouTube still is 4:3 with black bars baked in: the 16:9 picture inside them */
  /* A card: the drop in its own shape (a picture as it is, a page of words, a pond's cover), its name under it */
  .wc { position: relative; display: flex; flex-direction: column; min-width: 0; container-type: inline-size; }
  .wf { position: relative; display: block; overflow: hidden; border-radius: 8px; background: var(--card); box-shadow: var(--shadow, 0 0 #0000), 0 6px 18px rgb(0 0 0 / .3); transition: transform .15s ease, box-shadow .15s ease; }
  .wc:hover .wf, .wc:has(:focus-visible) .wf { transform: translateY(-3px); box-shadow: 0 0 0 2px var(--accent), 0 10px 24px rgb(0 0 0 / .4); }
  .wpic .wf > img { display: block; width: 100%; height: auto; min-height: 50cqw; max-height: 160cqw; object-fit: cover; } /* its own shape, but a panorama or a strip */
  .wpic .wf:has(> .pill18) > img { filter: blur(18px) saturate(1.3) brightness(.85); transform: scale(1.25); } /* 18+: frosted, as everywhere */
  .wf .pill18 { padding: 7px 13px; font: 700 14px/1.2 system-ui, -apple-system, "Segoe UI", sans-serif; }
  .wbook .wf { overflow: visible; background: none; box-shadow: none; }
  .wnote .wf { aspect-ratio: 8.5 / 11; border-radius: 3px; padding: 16px 16px 0; background: color-mix(in oklab, var(--card) 88%, var(--text)); } /* a letter's page */
  .wwords { height: 100%; overflow: hidden; font-size: .86em; line-height: 1.45; -webkit-mask-image: linear-gradient(#000 72%, transparent 96%); mask-image: linear-gradient(#000 72%, transparent 96%); }
  .wshort .wwords { font: 1.45em/1.3 var(--head); } /* a few words, big on their page */
  .wwords .wt { display: block; margin-bottom: 6px; font: 700 1.2em/1.25 var(--head); }
  .wwords > * { margin: 0 0 .6em; }
  .wwords :is(h1, h2, h3, h4) { font-size: 1.05em; }
  .wwords img { max-width: 100%; height: auto; }
  .wwords blockquote { margin: 0; padding-left: 8px; border-left: 3px solid var(--border); color: var(--muted); }
  .wpin, .wlock { position: absolute; z-index: 1; top: 6px; right: 8px; filter: drop-shadow(0 1px 2px rgb(0 0 0 / .5)); }
  .wpin + .wlock { right: 34px; }
  .wmany { position: absolute; top: 8px; right: 8px; width: 22px; height: 22px; }
  .wmany svg, .wplay svg { width: 100%; height: 100%; fill: none; stroke: #fff; stroke-width: 2; filter: drop-shadow(0 1px 2px rgb(0 0 0 / .7)); }
  .wplay { position: absolute; inset: 0; width: 46px; height: 46px; margin: auto; padding: 11px 9px 11px 13px; border-radius: 50%; background: rgb(20 14 26 / .62); -webkit-backdrop-filter: blur(4px); backdrop-filter: blur(4px); }
  .wplay svg { fill: #fff; stroke: none; }
  .wdur { position: absolute; right: 6px; bottom: 6px; padding: 1px 6px; border-radius: 4px; background: rgb(0 0 0 / .75); color: #fff; font: 600 12px/1.4 system-ui, -apple-system, "Segoe UI", sans-serif; }
  .wcap { margin: 10px 0 0; line-height: 1.3; }
  .wcap a { color: var(--text); }
  .wcap a::after { content: ""; position: absolute; inset: 0; z-index: 2; } /* the whole card opens it */
  .wcap b { display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 2; overflow: hidden; font-size: .95em; }
  .wcap small { display: block; margin-top: 2px; font-size: .8em; }
  .wby { display: flex; align-items: center; gap: 6px; margin-bottom: 4px; color: var(--muted); font-size: .85em; }
  .wby .avatar { width: 20px; height: 20px; margin: 0; font-size: 12px; }
}
/* With the desk helper running, the cards wait unseen until they're packed, so they don't jump into place; if it never packs
   them (the script didn't load), they show anyway after two seconds, in rows. Without scripts, they show in rows at once */
@media (min-width: 1100px) and (scripting: enabled) {
  main.desk:not(.plain) :is(.pile, .work > .shelves):not(.packed) { visibility: hidden; animation: unpacked 0s 2s forwards; }
}
@keyframes unpacked { to { visibility: visible; } }
@media (min-width: 1400px) {
  body:has(> main.desk.many) { --trees: 250px; --gap: 36px; --cards: calc(var(--trees) + var(--side) + 2 * var(--gap)); }
  main.desk.many { grid-template-columns: var(--trees) var(--side) minmax(0, 1fr); }
  main.desk.many > .trees { grid-area: 1 / 1 / -1; align-self: stretch; margin-top: 0; }
  main.desk.many > .profile { grid-column: 2; }
  main.desk.many > .compose { grid-column: 2; }
  main.desk.many > :is(.tabbar, .notes, .work) { grid-column: 3; }
  main.desk.held.many { --top: min(var(--hd), 100vh - var(--ph) - var(--ch)); } /* the trees in their own column, as before: the profile and the box held alone */
  main.desk.held.many > .trees { position: static; grid-row: 1 / 7; padding-top: 0; } /* down beside the footer too */
  main.desk.held.many > .trees > div { position: sticky; max-height: calc(100vh - 98px); }
}
/* The writing helper's @ and [[ list, and the invite tree's: a card like the box, the picked one in the accent, rows a thumb can tap. */
:is(.compose, .lookup) .cm-editor .cm-tooltip { background: var(--card); color: var(--text); border: var(--bw) solid var(--field); border-radius: 10px; overflow: hidden; box-shadow: var(--shadow, 0 4px 14px #0005); }
:is(.compose, .lookup) .cm-editor .cm-tooltip.cm-tooltip-autocomplete > ul { font: inherit; max-height: none; min-width: 12em; }
:is(.compose, .lookup) .cm-editor .cm-tooltip-autocomplete > ul > li { padding: 8px 12px; line-height: 1.3; }
:is(.compose, .lookup) .cm-editor .cm-tooltip-autocomplete li[aria-selected] { background: var(--accent); color: var(--on); }
:is(.compose, .lookup) .cm-editor .cm-completionDetail { margin-left: .6em; color: var(--muted); font-style: normal; }
:is(.compose, .lookup) .cm-editor li[aria-selected] .cm-completionDetail { color: inherit; }
/* The book reader (coponder.md, The book reader): a chapter's pages over the site, one at a time like the
   picture viewer's (radio buttons; reader.js shows its own page, .now). The sides of a page turn it, the
   ‹ › at its foot only say so (owner: small bare arrows, the zone is what you tap). */
.reader { position: fixed; inset: 0; z-index: 3; background: var(--bg); }
/* While a page of words shows, the site's header, bar of places and footer go, so the keyboard and
   screen readers start in the words; the end page keeps them (below). Without the script: the checked
   page, or the page marked at when nothing is checked or aimed at on the end page. */
body:has(.reader.js > figure.now:not(.end)) > :is(header, footer),
body:has(.reader:not(.js) > :checked + figure:not(.end)) > :is(header, footer),
body:has(.reader:not(.js) > figure.at:not(.end)):not(:has(.reader > :checked + figure.end, .reader figure.end :is(.thread :target, #compose:target))) > :is(header, footer) { display: none; }
.reader figure { position: absolute; inset: 0; margin: 0; display: none; }
.reader:not(.js) :checked + figure, .reader:not(.js, :has(:checked)) figure:has(.thread :target, #compose:target),
.reader:not(.js, :has(:checked, .thread :target, #compose:target)) figure.at { display: block; }
.reader.js figure.now { display: block; } /* apart, so a browser without :has keeps it */
.runhead { position: absolute; top: 0; left: 0; right: 0; height: 40px; display: flex; gap: 12px; align-items: center; margin: 0; padding: 0 16px; color: var(--muted); font-size: .85em; white-space: nowrap; }
.runhead > * { min-width: 0; overflow: hidden; text-overflow: ellipsis; }
.runhead .rt { align-self: stretch; display: flex; align-items: center; color: var(--muted); } /* to the end page, its replies: the running head's whole height */
.runhead .rt > span { display: flex; align-items: center; gap: 6px; min-width: 0; padding: 1px 10px; border: var(--bw) solid var(--field); border-radius: 999px; } /* the title and 💬, one pill: its own border, as .pill has none of its own outside a profile, a report or a cover page */
.runhead .t { min-width: 0; overflow: hidden; text-overflow: ellipsis; }
.runhead .talk { flex: none; } /* 💬 never goes: only the title is cut */
.runhead .n { flex: none; margin-left: auto; }
.runhead > :first-child { max-width: 55%; } /* the book's name leaves the title room: it's the way to the replies */
.leaf { position: absolute; top: 40px; bottom: 48px; left: 0; right: 0; overflow-y: auto; padding: 4px 20px 12px; scrollbar-width: thin; container-type: inline-size; }
.edges { position: sticky; top: 0; height: 0; z-index: 1; }
.edges > * { position: absolute; top: -4px; height: calc(100dvh - 88px); width: max(20px, 50% + 20px - 17 * 1.125rem); cursor: pointer; } /* the margin beside the words, so they stay selectable (reader.js turns on the page itself) */
.edges > .prev { left: -20px; }
.edges > .next { right: -20px; }
.edges span { display: none; }
.prose :is(a, summary, .spoiler), .ctop a { position: relative; z-index: 2; } /* links and spoilers in the words stay theirs (not the sides, which are links too) */
.reader .foot { position: absolute; left: 0; right: 0; bottom: 0; height: 48px; display: flex; align-items: center; }
.reader .foot > :is(.prev, .next) { flex: none; width: 52px; height: 48px; display: flex; align-items: center; justify-content: center; color: var(--muted); font-size: 26px; line-height: 1; padding-bottom: 3px; cursor: pointer; }
.reader .foot > .next { order: 2; }
.reader .foot progress { order: 1; flex: 1; min-width: 0; height: 3px; border: 0; border-radius: 2px; background: var(--border); appearance: none; }
.reader .foot progress::-webkit-progress-bar { background: var(--border); border-radius: 2px; }
.reader .foot progress::-webkit-progress-value { background: var(--accent); border-radius: 2px; }
.reader .foot progress::-moz-progress-bar { background: var(--accent); border-radius: 2px; }
.reader .foot:not(:has(.prev)) :is(progress, .seek) { margin-left: 52px; }
.reader .foot:not(:has(.next)) :is(progress, .seek) { margin-right: 52px; }
.ctop { max-width: 34em; margin: 0 auto; padding-top: 6vh; text-align: center; }
.ctop .kicker { margin: 0; font-size: .9em; }
.ctop h1 { margin: 6px 0 10px; font-size: 2.5em; line-height: 1.15; overflow-wrap: break-word; }
.ctop .cby { margin: 0 0 6vh; color: var(--muted); font-size: .9em; }
.ctop .cby::after { content: ""; display: block; width: 48px; margin: 28px auto 0; border-top: 2px solid var(--accent); }
.prose { max-width: 34em; margin: 0 auto; font-size: 1.125rem; line-height: 1.55; text-align: justify; hyphens: auto; } /* wrapped plainly: Safari's "pretty" wrapping breaks a short typed line that fits, "Chap-" / "ter 3" (TestReaderWrap) */
.prose > p { margin: 0 0 1.1em; text-indent: 1.4em; text-indent: 1.4em each-line; } /* a paperback's indent on every typed line */
.prose > :last-child { margin-bottom: 0; } /* a page ends at its words, not their gap */
.prose > .cont:not(.nl)::before { content: ""; margin-left: -1.4em; } /* a page that starts mid line starts flush */
.end .leaf { padding: 4px max(12px, 50% - 210px) 24px; } /* the drop's page, in one calm column, 420 pixels at most */
/* The end page is the way out of the book: in the page's flow, under the site's header and over its
   bar of places, like any drop's page (owner, 2026-10-17), its running head and line along with it. */
.reader.js:has(> figure.end.now), .reader:not(.js):has(> :checked + figure.end),
.reader:not(.js, :has(:checked)):has(> figure.end :is(.thread :target, #compose:target)),
.reader:not(.js, :has(:checked, .thread :target, #compose:target)):has(> figure.end.at) { position: static; background: none; }
.reader figure.end, .reader .end :is(.runhead, .leaf, .foot) { position: static; overflow: visible; }
body:has(> header > .donate:not([hidden])) .reader .end > .runhead { margin-top: 4.5rem; } /* the 🐟's Donate bubble hangs from the header over the page: the running head, its ← and 💬, stays clear under it, the bubble wrapped to two lines too (big text, a narrow phone) */
.fin { margin: 20px 0 24px; text-align: center; }
.fin p { margin: 0; color: var(--muted); font-size: .75em; letter-spacing: .12em; text-transform: uppercase; }
.fin h2 { margin: 4px 0 0; font-size: 1.75em; line-height: 1.2; overflow-wrap: break-word; }
.fin::after { content: ""; display: block; width: 48px; margin: 16px auto 0; border-top: 2px solid var(--accent); }
/* On, back and out: Next chapter big and alone, then Previous, Contents and the author's ✏️ Edit, each a finger tall */
.onward { margin: 0 0 24px; }
.onward > .primary { display: flex; flex-direction: column; align-items: center; padding: 12px 18px; border-radius: 14px; font-size: 1.15em; text-align: center; }
.onward small { max-width: 100%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-size: .75em; font-weight: normal; }
.onward > span { display: block; padding: 12px; text-align: center; color: var(--muted); }
.onward > p { display: flex; gap: 10px; margin: 12px 0 0; }
.onward > p > * { flex: 1 1 0; min-width: 0; display: flex; flex-direction: column; align-items: center; justify-content: center; min-height: 44px; padding: 4px 8px; border: var(--bw) solid var(--field); border-radius: 999px; white-space: nowrap; }
.onward > p > span { color: var(--muted); opacity: .6; } /* nowhere to go back to */
.onward > p small { color: var(--muted); }
.end .focus > article:not(.private) { margin: 0; padding: 0; background: none; border: 0; } /* the chapter's byline and actions sit in the column, unframed: the end page isn't a feed */
@container (max-width: 19rem) { .prose { text-align: left; } } /* a narrow page, or big text: justified lines of 15 letters open wide gaps */
@media (min-width: 900px) { .prose { font-size: 1.25rem; } .edges > * { width: max(20px, 50% + 20px - 17 * 1.25rem); } } /* the sides of the screen, clear of the words */
.reader .probe { position: absolute; height: 0; overflow: hidden; visibility: hidden; white-space: nowrap; } /* reader.js measures letters a line with it */
.reader .probe span { display: inline-block; } /* a box, so a ResizeObserver sees it change */
.reader.ragged .prose { text-align: left; } /* reader.js: under 34 letters a line, whatever made it so */
.prose li.cont { list-style: none; } /* a list item carried on from the page before: its number stays there */
.prose img, .prose video { display: block; margin: 0 auto; max-height: calc(100dvh - 104px - 3em); width: auto; height: auto; max-width: 100%; } /* a picture taller than the page shrinks to fit it, with a line of words under it */
.reader .foot .seek { order: 1; flex: 1; min-width: 0; width: auto; height: 48px; margin: 0; padding: 0; border: 0; border-radius: 0; background: none; box-shadow: none; appearance: none; cursor: pointer; } /* reader.js: the line at the foot, a slider over the words */
.reader .seek::-webkit-slider-runnable-track { height: 3px; border-radius: 2px; background: linear-gradient(var(--accent), var(--accent)) 0 0 / var(--p, 0%) 100% no-repeat var(--border); }
.reader .seek::-webkit-slider-thumb { appearance: none; width: 14px; height: 14px; margin-top: -5.5px; border: 0; border-radius: 50%; background: var(--accent); }
.reader .seek::-moz-range-track { height: 3px; border-radius: 2px; background: var(--border); }
.reader .seek::-moz-range-progress { height: 3px; border-radius: 2px; background: var(--accent); }
.reader .seek::-moz-range-thumb { width: 14px; height: 14px; border: 0; border-radius: 50%; background: var(--accent); }
.reader .seek:focus-visible { outline: 2px solid var(--accent); outline-offset: -2px; } /* inside it: the foot is the screen's edge */
/* Settings (coponder.md, Settings): cards of plain rows, each section its own page with the way back */
.back { display: inline-block; margin-top: 8px; padding: 10px 0; min-height: 44px; }
.back + h1 { margin-top: 0; }
.group { margin: 22px 0 6px; padding: 0 16px; font: 700 .8em var(--body, var(--head)); letter-spacing: .06em; text-transform: uppercase; color: var(--muted); }
.rows { list-style: none; margin: 0 0 8px; padding: 0; background: var(--card); border: var(--bw) solid var(--border); border-radius: 14px; overflow: hidden; }
.group small { text-transform: none; letter-spacing: 0; font-weight: normal; } /* ✓ Saved beside Colors */
.rows.far { margin-top: 32px; } /* Delete account, set apart */
.rows > li + li { border-top: var(--bw) var(--dash) var(--border); }
.rows > li > a, .rows .row { display: flex; align-items: center; gap: 12px; width: 100%; min-height: 56px; padding: 10px 16px; color: var(--text); text-align: left; }
.rows > li > a:hover, .rows button.row:hover { background: var(--border); color: var(--text); }
.rows .out, .rows .out:hover { color: var(--link); } /* Log out, a button like the picture menu's */
.rows .danger, .rows .danger:hover { color: var(--danger); }
.rows .ic { flex: none; width: 1.6em; text-align: center; font-size: 1.15em; }
.rows .txt { flex: 1; min-width: 0; }
.rows .txt b, .fields b { display: block; font-weight: bold; }
.rows small { display: block; color: var(--muted); font-size: .85em; line-height: 1.35; margin-top: 1px; }
.rows .go { flex: none; color: var(--muted); font-size: 1.4em; line-height: 1; }
.rows .val { flex: none; color: var(--muted); font-size: .9em; }
.rows .me-card { padding: 14px 16px; }
.rows .me-card .avatar { flex: none; width: 56px; height: 56px; margin: 0; }
.rows .me-card .avatar.none { font-size: 30px; }
.rows .me-card b { font: 700 1.2em var(--head); }
.saved { animation: saved 6s forwards; } /* ✓ Saved, on the row you changed */
@keyframes saved { 83% { opacity: 1; } 100% { opacity: 0; } }
/* a switch: a submit button showing the state, not the verb, its tap area 44px tall */
.sw { flex: none; position: relative; width: 52px; height: 32px; border-radius: 999px; background: var(--field); }
.sw::before { content: ""; position: absolute; inset: -6px; }
.sw::after { content: ""; position: absolute; top: 3px; left: 3px; width: 26px; height: 26px; border-radius: 50%; background: var(--text); box-shadow: 0 1px 3px #0006; }
.sw[aria-checked="true"] { background: var(--accent); box-shadow: var(--shadow); }
.sw[aria-checked="true"]::after { left: 23px; background: var(--on); }
.sw:hover { filter: brightness(1.1); }
/* two choices: one pill, each half a submit button */
.rows .stack { margin: 0; padding: 12px 16px 0; }
.seg { display: flex; margin: 8px 16px 14px; padding: 3px; border-radius: 999px; background: var(--bg); border: var(--bw) solid var(--border); }
.seg button { flex: 1; min-height: 44px; padding: 0 10px; border-radius: 999px; color: var(--text); }
.seg [aria-pressed="true"] { background: var(--accent); color: var(--on); font-weight: bold; box-shadow: var(--shadow); }
/* colors: each chip carries its palette's class, so it draws itself in its own colors and heading font;
   what a palette leaves to :root comes from here, not from the page's palette */
:where(.chips button) { --head: "Young Serif", Georgia, serif, "Emoji backup"; --bw: 1px; --shadow: none; color-scheme: dark; }
.chips { display: flex; flex-wrap: wrap; gap: 10px; padding: 14px 16px 16px; }
.chips button { flex: none; width: calc((100% - 20px) / 3); min-width: min-content; overflow-wrap: normal; padding: 8px; border-radius: 12px; background: var(--bg); border: 2px solid var(--border); color: var(--text); text-align: left; font: bold .82em/1.2 var(--head); font-size-adjust: .5; }
.chips .dots { display: flex; gap: 4px; margin-bottom: 8px; padding: 8px 6px; border-radius: 8px; background: var(--card); }
.chips .dots i { width: 14px; height: 14px; border-radius: 50%; background: var(--accent); }
.chips .dots i + i { background: var(--hot); }
.chips .dots i + i + i { background: var(--link); }
.chips [aria-pressed="true"] { border-color: var(--accent); box-shadow: 0 0 0 2px var(--accent); }
.chips .auto .dots { padding: 0; overflow: hidden; } /* Automatic: half Water Lilies, half its light, as a computer draws its Auto look */
.chips .auto .dots > span { display: flex; flex: 1; gap: 3px; padding: 9px 4px; background: var(--card); } /* narrow enough for a third of a 360 pixel phone */
.chips .auto .dots i { width: 12px; height: 12px; }
/* Name style: a preview, then chips showing your name in each font and effect, and swatches */
.ns { padding: 4px 16px 16px; }
.ns .prev { overflow-wrap: break-word; margin: 12px 0; padding: 14px 12px; border-radius: 12px; background: var(--bg); text-align: center; font-size: 1.6em; line-height: 1.3; font-weight: bold; }
.ns h3 { margin: 14px 0 6px; font-size: .85em; font-weight: normal; color: var(--muted); }
.ns .pick { display: grid; grid-template-columns: repeat(auto-fill, minmax(130px, 1fr)); gap: 8px; }
.ns .pick button { min-width: 0; min-height: 56px; padding: 6px 8px; border-radius: 12px; background: var(--bg); border: 2px solid var(--border); color: var(--text); line-height: 1.15; }
.ns .pick b { display: block; overflow: hidden; padding: .2em 0; font-size: 1.15em; white-space: nowrap; text-overflow: ellipsis; }
.ns .pick b:has(.ne-glow) { padding: 1em; margin: -.8em -1em; } /* the clip is for the …: this room lets the glow fade out, and the margin takes it back. Only the glow: Firefox draws a rainbow's letters past the … */
.ns .pick :is(.ne-wave, .ne-pop) [aria-hidden] > span { display: inline; } /* a chip is one line, cut short with … */
.ns .pick b:has(.ne-wave, .ne-pop, .ne-hover) { padding: .5em 0; margin: -.3em 0; } /* room for the letters to move, inside the chip that cuts it short */
.ns .pick .ne-hover { overflow: hidden; text-overflow: ellipsis; vertical-align: bottom; } /* moving, a hover is a box of its own, so it cuts itself short with … */
.ns .pick small { display: block; margin-top: 3px; font-size: .72em; color: var(--muted); }
.ns .dots { display: grid; grid-template-columns: repeat(7, minmax(0, 44px)); justify-content: space-between; gap: 6px; }
.ns .dots button { aspect-ratio: 1; padding: 0; border-radius: 50%; border: 2px solid var(--border); background: currentColor; } /* its nc- class sets the color */
.ns .dots button:not([class]) { color: var(--text); } /* Plain */
.ns .pick [aria-pressed="true"] { border-color: var(--accent); box-shadow: 0 0 0 2px var(--accent); }
.ns .dots [aria-pressed="true"] { border-color: var(--accent); box-shadow: 0 0 0 3px var(--card), 0 0 0 5px var(--accent); }
.ns .dots .auto { background: linear-gradient(135deg, currentColor 50%, var(--n2, var(--hot)) 50%); } /* the second color picked for you: half your color (its nc- class), half the one that goes with it */
.ns .dots .auto:not([class*="nc-"]) { color: var(--text); } /* your color is the text color */
@media (hover: hover) {
  :is(.chips, .ns) button:hover { border-color: var(--accent); } /* a chip or swatch, a box of its own: its border turns the highlight, as a bordered pill's does */
}
.ns h3 + small { margin: -2px 0 8px; color: var(--muted); }
/* A picture of a name: at most 1.6 lines of the words around it, still taking one line's room, and never wider than its column (it shrinks whole) */
.np { width: auto; height: auto; max-width: 100%; max-height: 1.6em; margin: -.3em 0; vertical-align: middle; }
/* Its outline, a thin edge in the text's color: where its ink is under 3:1 on the background (dark ink on a dark palette and in the always dark viewer, light ink on Water Lilies light), or everywhere when its owner turns Outline on */
.np.outline, :root:not(.light) .np.ink-dark, .lightbox .np.ink-dark, .light .np.ink-light:not(.lightbox *) { filter: drop-shadow(0 0 .6px currentColor) drop-shadow(0 0 .6px currentColor); }
.profile h1 .np { max-height: 2.2em; margin: 0; }
.ns .prev .np { max-height: 2.6em; margin: 0; }
.ns.np-row { padding-top: 0; }
.np-row .up { display: flex; flex-wrap: wrap; gap: 8px; align-items: center; }
.np-row > small, .np-row form small { display: block; margin-top: 8px; font-size: .8em; color: var(--muted); }
.np-row h3 .saved { display: inline; } /* beside its title, not under it as .rows small would put it */
.np-row .up + small + form { margin-top: 14px; }
/* Profile: one form, one Save */
.face { display: flex; align-items: center; gap: 16px; padding: 16px; }
.face .avatar.big { flex: none; margin: 0; }
.face > div { flex: 1; min-width: 0; }
/* Profile's two picture pickers: a pill (.choose) on a line of its own each. The name picture's field is required, so once a picture is chosen it's :valid and the pill reads ✓ Picture chosen, with no script; its form is novalidate, so Upload with none still sends it and the server says so */
.choose { margin: 4px 0; }
.choose > span + span, .choose:has(:valid) > span:first-child { display: none; }
.choose:has(:valid) > span + span { display: inline; }
.tick { display: flex; align-items: center; min-height: 44px; margin: 0; font-weight: normal; color: var(--muted); }
.tick input { width: 20px; height: 20px; margin-right: 10px; accent-color: var(--accent); }
.fields { padding: 4px 16px 16px; }
.fields.flat { padding: 0; } /* the delete page's password, under its cards */
.fields input { min-height: 44px; }
.fields p { margin: 12px 0 0; }
.fields small.error { color: var(--danger); } /* the count helper's line, past the limit: .rows small would keep it muted */
.actions-bar { display: flex; flex-wrap: wrap; align-items: center; gap: 8px 16px; margin: 16px 0; }
.actions-bar .primary { min-height: 48px; padding: 10px 28px; }
.rows .clear { flex: none; min-height: 44px; padding: 0 18px; border: var(--bw) solid var(--link); border-radius: 999px; }
.rows .add { display: flex; gap: 8px; margin: 8px 16px 14px; } /* 🙈 Hidden tags: the box and Hide, under the row's words */
.rows .add input { flex: 1; min-width: 0; min-height: 44px; }
.warn { padding: 16px; }
.warn p { margin: 0; }
.warn ul { margin: 8px 0 0; padding-left: 1.2em; }
.warn li { margin: 4px 0; }
.primary.danger-btn { background: var(--danger); color: var(--on); }
.branch, .branch ul { padding-left: 1.2em; } /* the invite tree: each level steps in a little, so a deep branch still fits a phone */
.branch time { white-space: nowrap; } /* a joined day never splits from its year */
/* Petitions (coponder.md, Petitions): a members' vote on a moderator, boxed under the Moderators line like a pond's rules; the fold to start one is a plain line until it's opened. */
.vote { margin: 12px 0; } /* its border and padding are a pond's rules' */
details.vote:not([open]) { margin: 4px 0 12px; padding: 0; border: 0; }
.vote select { width: auto; max-width: 100%; }
.vote > :first-child { margin-top: 6px; } /* as much room inside its border above as below, whatever ends it */
.vote > :last-child { margin-bottom: 6px; }
/* Buttons that play (coponder.md, CSS, Buttons that play): on a computer, a button's emoji turns once as the pointer comes onto the button,
   which itself stays still, so nothing slips from under the pointer. An emoji that plays is a .ic carrying itself again in data-e: hovered, the
   emoji stays put, unseen, and a copy turns on top of it. Most rock; a second class names what the
   others do. Only transforms, so no frame lays the page out; only where a device can hover (no stuck turn on a phone) and hasn't asked for less
   motion; and hover only, since a focus ring wraps whatever turns inside its button */
.top .ic { display: contents; } /* 🔍 and 🔔 have no padding: a box round the emoji would size their focus ring by the page's font, smaller than the emoji's own */
@media (hover: hover) and (prefers-reduced-motion: no-preference) {
  :is(a, button, summary):hover > .ic[data-e] { -webkit-text-fill-color: transparent; } /* the emoji itself, still and unseen, so the words beside it never shift */
  :is(a, button, summary):hover > .ic[data-e]::before { content: attr(data-e); content: attr(data-e) / ""; position: absolute; display: inline-block; -webkit-text-fill-color: currentColor; animation: roll .6s ease-out; } /* the copy, silent to screen readers: out of the flow at the place it would have had, so on the emoji to the pixel, as wide */
  :is(a, button, summary):hover > .ic.spin::before { animation-name: spin; animation-timing-function: ease-in-out; } /* 🔁: only round things spin, a 👍 spun shows 👎 halfway */
  :is(a, button, summary):hover > .ic.ring::before { animation-name: ring; animation-duration: .7s; transform-origin: 50% 8%; } /* 🔔 swings from its top */
  :is(a, button, summary):hover > .ic.tumble::before { animation-name: tumble; animation-duration: .7s; } /* 🎲, thrown */
  :is(header nav, .places) .on > .ic[data-e] { -webkit-text-fill-color: currentColor; } /* the place you're on is lit already: it stays still */
  :is(header nav, .places) .on > .ic[data-e]::before { content: none; animation: none; }
}
@media (prefers-reduced-motion: no-preference) { /* the 🔔's number grew while the page was open (static/bell.js): it swings once, on a phone too, and the number pops in */
  .top .rang > .ic[data-e] { -webkit-text-fill-color: transparent; }
  .top .rang > .ic[data-e]::before { content: attr(data-e); content: attr(data-e) / ""; position: absolute; display: inline-block; -webkit-text-fill-color: currentColor; animation: ring .7s; transform-origin: 50% 8%; }
  .top .rang > .unread { animation: grow .3s ease-out; }
}
@keyframes grow { from { transform: scale(0); } } /* not pop, the name effect's */
@keyframes roll { 20% { transform: rotate(-16deg); } 50% { transform: rotate(12deg); } 75% { transform: rotate(-5deg); } }
@keyframes spin { to { transform: rotate(1turn); } }
@keyframes ring { 10%, 50% { transform: rotate(16deg); } 30%, 70% { transform: rotate(-16deg); } 85% { transform: rotate(6deg); } }
@keyframes tumble { 45% { transform: translateY(-.3em) rotate(200deg); } 75% { transform: rotate(340deg); } 88% { transform: translateY(-.06em) rotate(355deg); } to { transform: rotate(1turn); } }
/* Automatic (the auto class): Water Lilies, and while the device is set to light, Water Lilies, light. Each rule here is a .light rule's twin,
   the same declarations (TestAutoPalette keeps them the same). Last in the sheet, so a twin wins where another rule is as specific */
@media (prefers-color-scheme: light) {
  .auto { --card-hover: #f7f8fc; --raise: #eef1f7; --raise2: #e2e7f1; --lip: #c9d0de; --pop: #fff; --pop-line: #d3d9e6; --mine-bg: #fbe6f0; --mine-lip: #d9a3bf; --mine-text: #9c2f63; --g-feel: #b8326a; --g-agree: #1f64a8; --g-credit: #2f7a34; --g-dis: #5b45b8; --t-reply: #2f7fd0; --t-repost: #3c9a44; --t-react: #e0742a; --scrim: rgb(20 24 40 / .45); }
  .auto { --bg: #f3f5fa; --card: #fff; --text: #1c2433; --muted: #5d6779; --border: #d8deea; --field: #c3cbdb; --link: #2f63a3; --hover: #b03f78; --accent: #7a63c4; --on: #fff; --logo: #4a8a3c; --hot: #c2558a; --onhot: #fff; --danger: #c4261d; color-scheme: light; }
  .auto { --rose: #c2185b; --ember: #b84a00; --gold: #8a6100; --leaf: #2e7d32; --sky: #1565c0; --violet: #6a3fc4; }
  .auto { --k-fandom: #1f5fbf; --k-character: #2e7d32; --k-species: #c2410c; --k-meta: #8a6100; --k-lore: #00796b; }
  .auto .ne-glow:not(.lightbox *) { filter: drop-shadow(0 0 .02em var(--n2)) drop-shadow(0 0 .05em var(--n2)) drop-shadow(0 0 .1em color-mix(in srgb, var(--n2) 55%, transparent)); }
  .auto .lightbox { --hot: #eaa3c2; --hover: var(--hot); }
  .auto .ne-pop:not(.lightbox *) { text-shadow: .07em .07em 0 color-mix(in srgb, var(--n2) 55%, transparent); }
  .auto :is(.body, .styles, .cm-content) .ne-glow:not(.lightbox *) { filter: drop-shadow(0 0 .05em var(--n2)) drop-shadow(0 0 .12em color-mix(in srgb, var(--n2) 60%, transparent)); }
  @media (prefers-reduced-motion: no-preference) { .auto .ne-glow:not(.lightbox *) { animation-name: glow-light; } }
  .auto :is(.body, .styles, .cm-content) .ne-glow { animation: none; }
  .auto .np.ink-light:not(.lightbox *) { filter: drop-shadow(0 0 .6px currentColor) drop-shadow(0 0 .6px currentColor); }
  .auto .np.ink-dark:not(.outline, .lightbox *) { filter: none; } /* dark ink reads on light: no outline but its owner's */
}
