/*
  site.css -- the site's structure. No colours and no typefaces of its own: every colour, face
  and measure is a custom property a THEME sets (themes/<name>/theme.css). A theme that only
  sets the properties below restyles the whole site; a theme may also add rules of its own.

  Colours     --bg --panel --recess            the page, a raised surface, a sunk one
              --off                            a faint wash: inline code, a table's head, a hovered row
              --text --text-2 --text-3         primary, secondary, dim
              --link --link-hover              what acts
              --mark --mark-wash               what locates: entry ids, the current item
              --rule --rule-2                  hairline, control border
              --quote                          quoted text
              --owner --claude --openai        who is speaking in a log (and the owner's own recordings,
                                               the runs handed to a model)
              --made                           what a session made: a file, an agent's recording
              --add --del                      lines added, lines removed
              --spoiler-bg --spoiler-text
  Faces       --font-body --font-title --font-ui --font-mono
  Measures    --size-body --line --col-text --col-log --col-list
              --size-title --size-h1 --size-h2 --size-h3 --weight-title

  The colours in the second group carry MEANING on a log page (who speaks, what a card is). A
  theme may retune them but must keep them apart from each other: blue, terracotta, teal, gold.

  The reader's own settings multiply those: --user-text, --user-column, --user-line (site.js).

  Sizes and gaps are the old engine-drawn client's, read off its source (renderer/theme.lua
  FONTS_NEXT, canvas.lua, elements.lua, logview.lua) at 1x and written in rem (16px = 1rem), so
  the reader's text size scales the whole page as the old font scale did.
*/

:root {
  --user-text: 1; --user-column: 1; --user-line: var(--line);
  --top-h: 4rem;                       /* the top line's height */
  /* The old client's text came out a little narrower or wider than a browser's at each size (its
     font engine rounded every letter's width to whole pixels). These nudges put the browser's
     lines at the widths it drew, so paragraphs break where they did. Measured for Arial 16,
     Arial bold 32 and 21, Cascadia 14; a theme with other faces sets them to 0. */
  --track-body: -0.045px; --track-italic: -0.03px; --track-title: 0.25px; --track-heading: 0.2px; --track-mono: -0.2px;
  color-scheme: dark;
}
*, *::before, *::after { box-sizing: border-box; }
html { font-size: calc(var(--size-body) * var(--user-text)); -webkit-text-size-adjust: 100%; scroll-padding-top: calc(var(--top-h) + 16px); }
body { margin: 0; background: var(--bg); color: var(--text); font-family: var(--font-body); line-height: var(--user-line); overflow-wrap: break-word; }
a { color: var(--link); text-decoration: none; }
a:hover { color: var(--link-hover); text-decoration: underline; }
img, video { max-width: 100%; height: auto; }
button, input, select { font: inherit; color: inherit; }
::selection { background: color-mix(in srgb, var(--link) 25%, transparent); }
.sep { color: var(--text-3); }
.dim { color: var(--text-3); }
.mono { font-family: var(--font-mono); }
[hidden] { display: none !important; }

/* ── The top line: stays at the top of the window, the page scrolls under it ───── */
.top { position: sticky; top: 0; z-index: 20; height: var(--top-h); display: flex; align-items: center; padding: 0 2rem; }
html.scrolled .top { background: var(--bg); }     /* (site.js sets .scrolled once the page has moved) */
.top-nav { display: flex; flex-wrap: nowrap; align-items: center; gap: 0 1.625rem; font-family: var(--font-ui); font-size: 0.875rem; line-height: 1.25rem; white-space: nowrap; }
.top-nav a, .top-nav button { position: relative; color: var(--text-2); background: none; border: 0; padding: 0; cursor: pointer; letter-spacing: inherit; text-transform: inherit; }
.top-nav a:hover, .top-nav button:hover { color: var(--text); text-decoration: none; }
.top-nav a.current { color: var(--text); }
.top-nav a.current::after { content: ''; position: absolute; left: 0; right: 0; bottom: -4px; height: 2px; background: currentColor; }
.top-search input { width: 9rem; background: none; border: 0; border-bottom: 1px solid transparent; color: var(--text); padding: 0; outline: none; letter-spacing: inherit; text-transform: inherit; }
.top-search input::placeholder { color: var(--text-2); opacity: 1; text-transform: inherit; letter-spacing: inherit; }
.top-search input:focus { border-bottom-color: var(--rule-2); width: 14rem; }

/* ── Columns ──────────────────────────────────────────────────────────────────── */
.page { margin: 39px auto 96px; padding: 0 20px; max-width: calc(var(--col-text) * var(--user-column) + 40px); }
/* where each kind of page starts under the top line, as the old client had it */
.page-log { margin-top: 47px; max-width: calc(var(--col-log) * var(--user-column) + 40px); }
.page-index, .page-list { max-width: calc(var(--col-list) * var(--user-column) + 40px); }
.page-index { margin-top: 47px; }
.page-list, .page-post, .page-game, .page-artifacts { margin-top: 45px; }
.page-artifacts { max-width: calc(900px * var(--user-column) + 40px); }

.title { font-family: var(--font-title); font-size: var(--size-title); font-weight: var(--weight-title); letter-spacing: var(--track-title); line-height: 1.25; margin: 0 0 20px; }
.page-post .title, .page-game .title { font-size: var(--size-h1); margin-bottom: 21px; }
.title-extra { font-family: var(--font-ui); font-size: 0.875rem; font-weight: 400; letter-spacing: 0; color: var(--text-3); margin-left: 7px; }
.crumb { display: flex; justify-content: space-between; gap: 16px; font-family: var(--font-ui); font-size: 0.75rem; color: var(--text-3); margin-bottom: 21px; }
.crumb a { color: inherit; text-decoration: underline; }
.meta { font-family: var(--font-ui); font-size: 0.75rem; line-height: 1rem; color: var(--text-3); }

/* ── Lists of entries (the index, the logs list) ──────────────────────────────── */
/* The old client's list row (front.lua LIST_ROW, draw_row): 40 tall, the date in a 160 column, the
   #id in a 64 one, the title in bold UI type; the row's box (its rule, its hover wash) reaches 24
   past the column on both sides. The chips above the index say which kinds of entry show: all of
   them at first; one left on alone is filled. */
.chips { display: flex; flex-wrap: wrap; gap: 8px; margin: 0 0 13px; }
.chip { display: inline-flex; align-items: center; height: 1.75rem; padding: 0 12px; font-family: var(--font-ui); font-size: 0.875rem; background: var(--off); border: 1px solid var(--rule-2); border-radius: 999px; cursor: pointer; color: var(--text); }
.chip[aria-pressed="false"] { background: none; border-color: var(--rule); color: var(--text-3); }
.chip.solo { background: var(--link); border-color: var(--link); color: var(--bg); }
.chip:hover { box-shadow: inset 0 0 0 2rem color-mix(in srgb, var(--link) 12%, transparent); }
.entries { margin: 0 -24px; }
.page-list .entries { border-top: 1px solid var(--rule); }
.month { display: none; }
.entry { display: grid; grid-template-columns: 160px 64px 1fr auto; align-items: center; height: 2.5rem; padding: 0 24px; border-bottom: 1px solid var(--rule); color: var(--text); font-family: var(--font-ui); }
.entry:hover { background: color-mix(in srgb, var(--link) 12%, transparent); border-radius: 10px; text-decoration: none; color: var(--link); }
.entry-date { font-size: 0.75rem; color: var(--text-3); white-space: pre; }
.entry-id { font-size: 0.75rem; color: var(--mark); }
.entry-title { font-family: var(--font-title); font-weight: 700; font-size: 0.875rem; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
/* the hidden logs' line (front.lua: "faded, non-bold, italic", the attribution lines' look, at a row's size) */
.entry-title.entry-note { font-family: var(--font-ui); font-size: 0.875rem; font-weight: 400; font-style: italic; color: var(--text-3); letter-spacing: var(--track-italic); }
a.entry-hidden:hover .entry-note { text-decoration: underline; }
/* a game's row (the owner, 2026-11-11: "Each (game) tagged item should also shine like gold in the Phylactery theme and have
   related matching colors in the other themes"): the title in the theme's gold (--release, its --release-deep and
   --release-shine), a sheen crossing it now and then; the "game" word in the same gold. Still for a reader who asks
   for less motion. */
.entry-game { --plate: var(--release, var(--made)); --plate-deep: var(--release-deep, var(--made)); --plate-shine: var(--release-shine, #fff); --plate-glow: var(--release-glow, transparent); }
/* a prototype's row (the owner, 2026-11-11: "Skyland and Horse Game should be classified as prototypes instead and be
   silver plated instead of gold"): the same plate in each theme's silver (--proto, --proto-deep, --proto-shine, --proto-glow) */
.entry-proto { --plate: var(--proto, #cfd5dc); --plate-deep: var(--proto-deep, #8f98a3); --plate-shine: var(--proto-shine, #fff); --plate-glow: var(--proto-glow, transparent); }
.entry-plate .entry-title {
  /* a band of light crossing it (the first layer) over the gold, a little deeper at its foot (the second) */
  background-image: linear-gradient(105deg, transparent 38%, var(--plate-shine) 50%, transparent 62%),
                    linear-gradient(180deg, var(--plate) 45%, var(--plate-deep) 100%);
  background-size: 300% 100%, 100% 100%; background-position: 100% 0, 0 0; background-repeat: no-repeat;
  -webkit-background-clip: text; background-clip: text; -webkit-text-fill-color: transparent; color: transparent;
  animation: release-shine 5s ease-in-out infinite;
  filter: drop-shadow(0 0 6px var(--plate-glow));   /* the gold's own light */
}
.entry-plate .entry-kind { color: var(--plate); border-color: color-mix(in srgb, var(--plate) 55%, transparent); }
/* the row itself a plate of the gold (the owner, 2026-11-11: "Not just the title, but the background should be changed as
   well, it should be like a plate that stands out"): a gold field, a gold edge, the gold's own light round it on the
   dark themes, and the band of light crossing the plate with the title's */
.entry.entry-plate {
  position: relative; overflow: hidden; border-radius: 10px; border-bottom-color: transparent; margin: 3px 0;
  background: linear-gradient(100deg, color-mix(in srgb, var(--plate) 22%, transparent),
                                      color-mix(in srgb, var(--plate) 9%, transparent) 55%,
                                      color-mix(in srgb, var(--plate) 17%, transparent));
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--plate) 55%, transparent), 0 0 16px var(--plate-glow);
}
.entry.entry-plate:hover { background: color-mix(in srgb, var(--plate) 26%, transparent); }
.entry.entry-plate::after {
  content: ''; position: absolute; inset: 0; pointer-events: none;
  background: linear-gradient(105deg, transparent 38%, color-mix(in srgb, var(--plate-shine) 20%, transparent) 50%, transparent 62%);
  background-size: 300% 100%; background-position: 100% 0; background-repeat: no-repeat;
  animation: release-shine-plate 5s ease-in-out infinite;
}
@keyframes release-shine-plate { 0% { background-position: 100% 0; } 45%, 100% { background-position: 0% 0; } }
@media (prefers-reduced-motion: reduce) { .entry.entry-plate::after { animation: none; background: none; } }
@keyframes release-shine { 0% { background-position: 100% 0, 0 0; } 45%, 100% { background-position: 0% 0, 0 0; } }
@media (prefers-reduced-motion: reduce) { .entry-plate .entry-title { animation: none; } }
.entry-kind { display: inline-flex; align-items: center; height: 1.25rem; padding: 0 7px; margin-left: 10px; font-size: 0.75rem; color: var(--text-3); border: 1px solid var(--rule); border-radius: 999px; }
.entries .entry.off { display: none; }

/* ── Prose ────────────────────────────────────────────────────────────────────── */
/* Gaps. An element's top margin is the gap the old client put BEFORE it, its bottom margin the
   gap AFTER; adjoining margins collapse to the larger, which was its rule too (canvas.lua
   layout_list: gap = max(gap_after(prev), gap_before(el))). A paragraph: 16 before. A heading:
   24 (h3: 16). A list: 8 before (it hugs the line that introduces it), 22 after; 4 between
   items. An image, a video, a gallery: 16 both sides. A quote: 24 both sides.
   `.block` is the wrapper that carries a transcript block's role; it makes no box of its own. */
.block { display: contents; }
.prose { letter-spacing: var(--track-body); }
.prose p, .prose pre.code, .prose .table-wrap, .prose .math, .prose .tweet, .prose .embed, .prose .details, .prose .video-missing, .prose .game-link, .prose .spoiler { margin: 1rem 0 0; }
.prose .h1, .prose .h2, .prose .h3 { font-family: var(--font-title); font-weight: 700; scroll-margin-top: calc(var(--top-h) + 16px); }
.prose .h1 { font-size: var(--size-h1); line-height: 2.4375rem; margin: 1.5rem 0 0; }
.prose .h2 { font-size: var(--size-h2); line-height: 1.9375rem; margin: 1.5rem 0 0; }
.prose .h3 { font-size: var(--size-h3); line-height: 1.5rem; margin: 1rem 0 0; }
.prose .byline { font-size: 0.75rem; color: var(--text-3); margin-top: 3px; }
.prose p.right { text-align: right; }
.prose blockquote { margin: 1.5rem 0; padding: 0 0 0 16px; border-left: 1px solid var(--rule); color: var(--quote); font-style: italic; }
.prose blockquote, .prose em { letter-spacing: calc(var(--track-body) + var(--track-italic)); }
.prose ul, .prose ol { margin: 0.5rem 0 1.375rem; padding: 0 0 0 1.75rem; list-style: none; }
.prose li { position: relative; margin: 4px 0 0; }
.prose li:first-child { margin-top: 0; }
.prose ul > li::before { content: ''; position: absolute; left: calc(-12px - 2.5px); top: calc(0.5rem * var(--user-line) - 2.5px); width: 5px; height: 5px; border-radius: 50%; background: var(--text-3); }
.prose ol { counter-reset: item; }
.prose ol > li { counter-increment: item; }
.prose ol > li::before { content: counter(item) '.'; position: absolute; right: calc(100% + 10px); top: 0; color: var(--text-3); white-space: nowrap; }
.prose hr { border: 0; border-top: 1px solid var(--rule); margin: 1rem 0 0; }
.prose .spacer { height: 1.125rem; margin-top: 1rem; }
.prose figure, .prose .gallery, .prose .inline-video { margin: 1rem 0; }
/* The old client drew a line's glyphs at the TOP of its line box and left the leading under them;
   a browser splits the leading above and below. Text is lifted by half of it so a line sits
   where it did against the rows, cards and rules around it. */
.prose p, .prose li { position: relative; top: calc((1.125rem - 1rem * var(--user-line)) / 2); }
.prose .h1, .prose .h2, .prose .h3 { position: relative; top: -0.1875rem; }
.prose li li, .prose li p { top: 0; }
/* the first thing in a container has no gap above it, the last none below */
.prose > :first-child, .prose > .block:first-child > *, .prose blockquote > :first-child, .prose li > :first-child,
.user-message > :first-child, .more-rest > :first-child, .details-body > :first-child, .row-body > :first-child { margin-top: 0; }
.prose > :last-child, .prose > .block:last-child > *, .prose blockquote > :last-child, .prose li > :last-child,
.user-message > :last-child, .row-body > :last-child, .details-body > :last-child { margin-bottom: 0; }

code { font-family: var(--font-mono); font-size: 0.875rem; letter-spacing: var(--track-mono); background: var(--off); }
pre.code { font-family: var(--font-mono); font-size: 0.875rem; letter-spacing: var(--track-mono); line-height: 1.25rem; background: var(--recess); border: 1px solid var(--rule-2); padding: 11px; overflow-x: auto; position: relative; scrollbar-width: thin; scrollbar-color: var(--rule-2) var(--rule); }
pre.code code { background: none; font-size: inherit; }
pre.code.wrap { white-space: pre-wrap; overflow-wrap: anywhere; }
.copy-code { position: absolute; top: 6px; right: 6px; font-family: var(--font-ui); font-size: 0.75rem; background: var(--bg); border: 1px solid var(--rule-2); color: var(--text-2); padding: 1px 8px; cursor: pointer; opacity: 0; }
pre.code:hover .copy-code, .copy-code:focus { opacity: 1; }
.table-wrap { overflow-x: auto; }
table { width: 100%; border-collapse: collapse; border: 1px solid var(--rule); }
th, td { padding: 8px 12px; text-align: left; vertical-align: top; font-weight: 400; border-bottom: 1px solid var(--rule); }
tbody tr:last-child td { border-bottom: 0; }
th { background: var(--off); }
/* display math: the browser's MathML, set in the body face as the old client drew it (Arial, scripts smaller) */
.math { text-align: center; overflow-x: auto; overflow-y: hidden; }
.math math { font-family: var(--font-body); font-size: 1rem; }
.math .v { font-style: italic; }
.pixel { image-rendering: pixelated; font-family: var(--font-mono); }
.redacted { background: var(--spoiler-bg); color: transparent; user-select: none; }
.redacted:hover { color: var(--spoiler-text); }
.redacted.shape:hover { color: transparent; }   /* a shape bar (and the owner's live ones, redact.js) never reveals */
.was-link { color: inherit; cursor: text; }
.artifact { color: var(--link); }
.emoji { height: 1.125em; width: 1.125em; vertical-align: -0.2em; }
.spoiler-inline, .spoiler { background: var(--spoiler-bg); color: transparent; cursor: pointer; }
.spoiler { padding: 8px 12px; }
.spoiler * { visibility: hidden; }
.spoiler-inline.revealed, .spoiler.revealed { color: var(--spoiler-text); }
.spoiler.revealed * { visibility: visible; color: var(--spoiler-text); }
.details { border: 1px solid var(--rule-2); }
.details > summary { padding: 4px 10px; cursor: pointer; }
.details-body { padding: 16px; border-top: 1px solid var(--rule); }

/* ── Media ────────────────────────────────────────────────────────────────────── */
figure { margin: 1rem 0; }
figure.image img, .inline-video { display: block; }
.zoomable { cursor: zoom-in; }
.gallery { display: grid; grid-template-columns: repeat(var(--cols, 2), 1fr); gap: 8px; }
.gallery img { width: 100%; height: 100%; object-fit: cover; aspect-ratio: 16 / 10; border: 1px solid var(--rule); }
figure.video video { display: block; width: 100%; background: var(--recess); border: 1px solid var(--rule); }
figure.video-tall video { max-height: 80vh; width: auto; margin: 0 auto; }
figure.video figcaption { font-family: var(--font-ui); font-size: 0.75rem; color: var(--text-2); margin-top: 6px; display: flex; flex-wrap: wrap; gap: 0 6px; }
.video-missing { border: 1px solid var(--rule); background: var(--panel); padding: 12px 14px; }

.tweet { font-family: var(--font-ui); font-size: 0.9375rem; line-height: 1.45; border: 1px solid var(--rule-2); border-radius: 12px; background: var(--panel); padding: 14px 16px; max-width: 560px; }
.tweet-head { display: flex; align-items: center; gap: 8px; margin-bottom: 8px; }
.tweet-avatar { width: 36px; height: 36px; border-radius: 50%; }
.tweet-name { font-weight: 700; }
.tweet-handle { color: var(--text-2); }
.tweet-text { overflow-wrap: anywhere; }
.tweet-media { display: grid; gap: 4px; margin-top: 10px; border-radius: 10px; overflow: hidden; }
.tweet-media-2, .tweet-media-3, .tweet-media-4 { grid-template-columns: 1fr 1fr; }
.tweet-media img, .tweet-media video { display: block; width: 100%; height: auto; }
.tweet-media-2 img, .tweet-media-3 img, .tweet-media-4 img { height: 100%; object-fit: cover; aspect-ratio: 1; }
.tweet-quoted { margin: 10px 0 0; background: none; max-width: none; }
.tweet-link { display: block; margin-top: 10px; font-size: 0.8125rem; color: var(--text-2); }

.embed { display: flex; gap: 14px; align-items: center; border: 1px solid var(--rule-2); border-radius: 6px; background: var(--panel); overflow: hidden; color: var(--text); max-width: 560px; }
.embed:hover { text-decoration: none; border-color: var(--link); color: var(--text); }
.embed img { width: 46%; max-width: 230px; display: block; }
.embed-text { display: flex; flex-direction: column; gap: 2px; padding: 8px 12px 8px 0; font-family: var(--font-ui); }
.embed-title { font-weight: 700; font-size: 0.9375rem; }
.embed-label { font-size: 0.75rem; color: var(--text-2); }
.game-link { border: 1px dashed var(--rule-2); padding: 12px 14px; font-family: var(--font-ui); font-size: 0.875rem; }

/* ── A game's page ────────────────────────────────────────────────────────────── */
/* The game plays in a frame (the game player). The frame is as wide as the window allows and
   keeps a 16:9 shape, never taller than the window; the text under it keeps the text column. */
.page-game { max-width: none; padding: 0; }
.page-game > .crumb, .page-game > .title, .page-game > .prose > :not(.game-frame) { max-width: calc(var(--col-text) * var(--user-column)); margin-left: auto; margin-right: auto; padding-left: 20px; padding-right: 20px; box-sizing: content-box; }
.game-frame { container-type: inline-size; width: min(100%, calc((100vh - 150px - var(--under, 0px)) * 16 / 9)); min-width: min(100%, 320px); margin: 1rem auto 1.5rem; background: var(--recess); }
/* 16:9, plus the strip the player asks for under the game on a touch screen (--under, set by site.js) */
.game-frame iframe { display: block; width: 100%; height: calc(56.25cqw + var(--under, 0px)); border: 0; }
/* the game's maximize button: the frame covers the window (also where the browser has no fullscreen, as on an iPhone) */
.game-frame.maximized { position: fixed; inset: 0; z-index: 60; width: 100%; margin: 0; }
.game-frame.maximized iframe { height: 100%; }
html.game-maximized { overflow: hidden; }
/* A small demo inside a post (a chart, the fire demos): its own shape at twice its size (--w,
   --ar from the game host's list), centred on the column and allowed past it, as the old client
   drew it, never wider than the window. Its box is 18 taller than the demo (canvas.lua: el.h =
   the demo + 18), and the usual gap to the next block comes after that. */
.prose .demo { margin: 1rem 0; padding-bottom: 18px; }
.demo-frame { position: relative; left: 50%; width: min(var(--w), 100vw - 32px); aspect-ratio: var(--ar); transform: translateX(-50%); background: var(--recess); }
.demo-frame iframe { display: block; width: 100%; height: 100%; border: 0; }

/* ── Cards: what a session made ───────────────────────────────────────────────── */
/* Each kind has its own colour so it reads as what it is at a glance: blue = the owner's own
   recording, terracotta = a run handed to a model, gold = something the session made (a file,
   an agent's recording), gray = a code state. --tint colours the surface and the border,
   --ink the icon, the name and the button. (logview.lua kind_accent, card_shell.) */
.k-replay { --tint: var(--owner); --ink: var(--owner); }
.k-run    { --tint: var(--claude); --ink: var(--claude); }
.k-made   { --tint: var(--made); --ink: var(--made); }
.k-code   { --tint: var(--text); --ink: var(--text-2); }
.card, .att, .row-compaction {
  background: color-mix(in srgb, var(--tint) 8%, var(--panel));
  border: 1px solid color-mix(in srgb, var(--tint) 43%, transparent);
  border-radius: 8px; font-family: var(--font-ui); color: var(--text);
}
a.card:hover, a.att:hover, .card[role="button"]:hover, .att[role="button"]:hover, .row-compaction > summary:hover {
  background: color-mix(in srgb, var(--tint) 16%, var(--panel)); border-color: color-mix(in srgb, var(--tint) 67%, transparent);
  text-decoration: none; color: var(--text); cursor: pointer;
}
.kind-icon { flex: none; color: var(--ink); }
.card-btn { flex: none; display: inline-flex; align-items: center; height: 2rem; padding: 0 14px; border: 1px solid var(--ink); border-radius: 6px; font-family: var(--font-ui); font-size: 0.875rem; font-weight: 700; color: var(--ink); white-space: nowrap; }
a:hover > .card-btn, [role="button"]:hover > .card-btn, summary:hover > .card-btn { background: color-mix(in srgb, var(--tint) 16%, transparent); }
.btn-play { margin-right: 7px; }

/* a card where it was made, inside a turn */
.card { display: flex; align-items: center; height: 4rem; padding: 0 11px 0 15px; }
.card .kind-icon { margin-right: 12px; }
.card-kind { flex: none; width: 7.375rem; font-size: 0.875rem; color: var(--ink); white-space: nowrap; }
.card-text { flex: 1; min-width: 0; display: flex; flex-direction: column; }
.card-name { font-family: var(--font-mono); font-size: 0.875rem; line-height: 1.0625rem; color: var(--ink); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.k-code .card-name, .k-code .att-name { color: var(--text); }
.card-sub { font-size: 0.75rem; line-height: 0.875rem; margin-top: 4px; color: var(--text-3); overflow: hidden; text-overflow: ellipsis; white-space: pre; }
.card-sub .add { color: var(--add); margin-left: 12px; }
.card-sub .del { color: var(--del); margin-left: 8px; }
.card .card-btn { margin-left: 16px; }
.card-slot { margin: 1.25rem 0; scroll-margin-top: calc(var(--top-h) + 24px); }
.card-slot:has(+ .card-slot) { margin-bottom: 0; }
.card-slot + .card-slot { margin-top: 6px; }
.card-slot.playing > .card { display: none; }

/* a recording playing in place: a header with its name, "Collapse replay" and "Open larger", over the video */
.player { border: 1px solid var(--rule-2); border-radius: 8px; background: var(--panel); overflow: hidden; font-family: var(--font-ui); }
.player-head { display: flex; align-items: center; height: 2.75rem; padding: 0 14px 0 16px; border-bottom: 1px solid var(--rule); }
.player-title { flex: 1; min-width: 0; font-family: var(--font-body); font-weight: 700; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.player-act { flex: none; display: inline-flex; align-items: center; gap: 4px; background: none; border: 0; padding: 0; font-size: 0.875rem; color: var(--link); cursor: pointer; }
.player-act:hover { color: var(--link-hover); }
.player-sep { flex: none; width: 1px; height: 1rem; margin: 0 12px; background: var(--rule-2); }
.player-well { display: flex; justify-content: center; background: var(--recess); }
.player-well video { display: block; width: auto; max-width: 100%; height: auto; max-height: 72vh; }

/* ── A log (logview.lua) ──────────────────────────────────────────────────────── */
/* head: the way back, the title, then one line: #id, the date, the model(s) at the right */
.log-crumb { font-family: var(--font-ui); font-size: 0.875rem; line-height: 1rem; }
.log-crumb .back, .log-back { display: inline-flex; align-items: center; gap: 7px; }
.page-log .title { font-size: var(--size-title); line-height: 2.6875rem; margin: 11px 0 0; padding-bottom: 2px; }
.log-line { display: flex; flex-wrap: wrap; align-items: center; min-height: 1.75rem; row-gap: 6px; margin-top: 0.875rem; font-family: var(--font-ui); font-size: 0.875rem; }
.log-line .sep, .turn-head .sep { margin: 0 0.556em; }
.log-id { font-family: var(--font-mono); font-size: 0.75rem; color: var(--mark); margin-right: 0.875rem; }
.log-date { color: var(--text-3); }
.log-legacy { display: inline-flex; align-items: center; height: 1.75rem; padding: 0 12px; margin-left: 0.875rem; border: 1px solid var(--rule-2); border-radius: 6px; color: var(--text-2); }
.log-models { margin-left: auto; padding-left: 1.5rem; font-size: 0.75rem; color: var(--text-3); }
.log-legacy-note { margin-top: 6px; font-family: var(--font-ui); font-size: 0.75rem; line-height: 0.875rem; color: var(--text-3); }
.log-back { margin-top: 1.75rem; font-family: var(--font-ui); font-size: 0.875rem; }

/* "Find in this session": the field; while it is in use it stays under the top line */
.log-find { position: relative; display: flex; align-items: center; height: 2.75rem; margin-top: 1.25rem; padding: 0 5px 0 13px; background: var(--recess); border: 1px solid var(--rule-2); border-radius: 6px; font-family: var(--font-ui); font-size: 0.875rem; cursor: text; }
.log-find:hover:not(.active) { background: color-mix(in srgb, var(--link) 12%, var(--recess)); }
.log-find.active { position: sticky; top: calc(var(--top-h) + 10px); z-index: 15; border-color: var(--link); box-shadow: 0 0 0 10px var(--bg), 0 11px 0 0 var(--rule); }
.find-icon { flex: none; margin-top: 2px; color: var(--text-3); }
.find-input { flex: 1; min-width: 0; height: 100%; margin-left: 10px; background: none; border: 0; outline: 0; color: var(--text); }
.find-input::placeholder { color: var(--text-3); opacity: 1; }
.find-key { flex: none; display: inline-flex; align-items: center; height: 1.5rem; padding: 0 8px; margin-right: 4px; border: 1px solid var(--rule-2); border-radius: 4px; font-family: var(--font-mono); font-size: 0.75rem; color: var(--text-3); }
.find-count { flex: none; margin-right: 10px; color: var(--text-2); white-space: nowrap; }
.find-btn { flex: none; display: none; align-items: center; justify-content: center; width: 2rem; height: 2rem; margin-left: 6px; background: none; border: 1px solid var(--rule-2); border-radius: 6px; color: var(--text-2); cursor: pointer; }
.find-btn:hover { background: color-mix(in srgb, var(--link) 12%, transparent); color: var(--link-hover); }
.log-find.active .find-btn { display: inline-flex; }
.log-find.active .find-key, .log-find:not(.active) .find-count { display: none; }
.find-list { position: absolute; left: -1px; right: -1px; top: calc(100% + 7px); padding: 6px 0; background: var(--panel); border: 1px solid var(--rule-2); border-radius: 8px; cursor: default; }
.find-row { position: relative; display: flex; align-items: center; height: 2.5rem; padding: 0 16px; cursor: pointer; white-space: nowrap; }
.find-row:hover { background: var(--off); }
.find-row.current { background: color-mix(in srgb, var(--link) 12%, transparent); }
.find-row.current::before { content: ''; position: absolute; left: 0; top: 0; bottom: 0; width: 2px; background: var(--mark); }
.find-who { flex: none; width: 250px; overflow: hidden; text-overflow: ellipsis; font-weight: 700; }
.find-who .when { font-size: 0.75rem; font-weight: 400; color: var(--text-3); white-space: pre; }
.find-snippet { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: pre; }
.find-snippet mark { background: color-mix(in srgb, var(--link) 15%, transparent); color: inherit; outline: 1px solid transparent; }
.find-row.current .find-snippet mark { background: color-mix(in srgb, var(--mark) 25%, transparent); }
.find-none { display: flex; align-items: center; justify-content: space-between; height: 3rem; padding: 0 16px; color: var(--text-3); }
.find-none button { background: none; border: 0; padding: 0; color: var(--link); cursor: pointer; }
.find-foot { padding: 6px 16px 6px; font-size: 0.75rem; color: var(--text-3); white-space: pre; }
::highlight(find) { background-color: color-mix(in srgb, var(--link) 15%, transparent); }
::highlight(find-current) { background-color: color-mix(in srgb, var(--mark) 25%, transparent); }

/* "Show" and a checkbox per kind of block */
.log-filter { display: flex; flex-wrap: wrap; align-items: center; gap: 8px 24px; margin-top: 0.875rem; font-family: var(--font-ui); font-size: 0.875rem; }
.filter-show { margin-right: -4px; line-height: 1.5rem; color: var(--text-2); }
.filter-item { display: inline-flex; align-items: center; gap: 8px; height: 1.5rem; color: var(--text-2); cursor: pointer; }
.filter-item:has(input:checked) { color: var(--text); }
.filter-item input { appearance: none; -webkit-appearance: none; flex: none; width: 1rem; height: 1rem; margin: 0; border: 1px solid var(--rule-2); border-radius: 3px; cursor: pointer; }
.filter-item:hover input:not(:checked) { border-color: var(--link); background: color-mix(in srgb, var(--link) 12%, transparent); }
.filter-item input:checked { border-color: var(--link); background: var(--bg) linear-gradient(var(--link), var(--link)); position: relative; }
.filter-item:hover input:checked { border-color: var(--link-hover); background-image: linear-gradient(var(--link-hover), var(--link-hover)); }
.filter-item input:checked::after { content: ''; position: absolute; inset: -1px; background: var(--bg); -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Cpath d='M4 8l3 3 5-6' fill='none' stroke='black' stroke-width='2'/%3E%3C/svg%3E") center / 1rem 1rem no-repeat; mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Cpath d='M4 8l3 3 5-6' fill='none' stroke='black' stroke-width='2'/%3E%3C/svg%3E") center / 1rem 1rem no-repeat; }

/* sections: Summary, Attachments, Transcript. A hairline and 28 above every one but the first. */
.log-section { margin-top: 2.25rem; padding-top: 1.75rem; border-top: 1px solid var(--rule); }
.log-section.first { margin-top: 1.75rem; padding-top: 0; border-top: 0; }
.log-section-title { display: flex; align-items: baseline; letter-spacing: var(--track-heading); font-family: var(--font-title); font-size: var(--size-h2); font-weight: 700; line-height: 1.4375rem; margin: 0; padding-bottom: 4px; }
.log-section-extra { margin-left: 10px; letter-spacing: 0; font-family: var(--font-ui); font-size: 0.875rem; line-height: 1; font-weight: 400; color: var(--text-3); white-space: pre-wrap; }
.log-section > .prose { margin-top: 1rem; }
.more { display: flex; align-items: center; gap: 7px; height: 1.375rem; margin-top: 8px; padding: 0; background: none; border: 0; font-family: var(--font-ui); font-size: 0.875rem; color: var(--link); cursor: pointer; }
.more:hover { color: var(--link-hover); }
.more[aria-expanded="true"] .more-chevron { transform: rotate(180deg); }

/* every card in the log: one row of them until "View all N" */
.att-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(min(18.75rem, 100%), 1fr)); gap: 12px; margin-top: 0.875rem; }
.att-grid[data-collapsed] { grid-template-rows: 4rem; grid-auto-rows: 0; row-gap: 0; overflow: hidden; }
.att { display: flex; align-items: center; height: 4rem; min-width: 0; padding: 0 11px 0 13px; }
.att .kind-icon { margin-right: 14px; }
.att-text { flex: 1; min-width: 0; display: flex; flex-direction: column; }
.att-name { font-family: var(--font-body); font-weight: 700; line-height: 1.125rem; color: var(--ink); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.att-sub { font-size: 0.75rem; line-height: 0.875rem; margin-top: 2px; color: var(--text-3); overflow: hidden; text-overflow: ellipsis; white-space: pre; }
.att .card-btn { margin-left: 12px; }
.att-more { margin-top: 11px; }

/* turns: a hairline between them, 20 above and below; the speaker line; the blocks 16 in.
   Only the prompter's turn carries the bar and the face. */
.turn { position: relative; padding: calc(1.25rem - 1px) 0 1.25rem; border-top: 1px solid var(--rule); }
.turn.first { padding-top: 4px; border-top: 0; }
.turn-main { padding-left: 1rem; }
.turn-user .turn-main { padding-left: calc(1rem - 3px); border-left: 3px solid var(--owner); }
.turn-user.tone-claude .turn-main { border-left-color: var(--claude); }
.turn-avatar { position: absolute; left: -52px; top: calc(1.25rem - 1px); width: 36px; height: 36px; }
.turn.first .turn-avatar { top: 4px; }
.turn-head { display: flex; align-items: center; height: 1.125rem; font-family: var(--font-ui); font-size: 0.75rem; color: var(--text-3); white-space: nowrap; }
.turn-speaker { font-family: var(--font-body); font-size: 1rem; font-weight: 700; }
.tone-owner .turn-speaker { color: var(--owner); }
.tone-claude .turn-speaker { color: var(--claude); }
.tone-openai .turn-speaker { color: var(--openai); }
.tone-neutral .turn-speaker { color: var(--text-2); }
.turn-sub { margin-left: 6px; }
.turn-time { font-family: var(--font-mono); }
.turn-right { margin-left: auto; padding-left: 1.5rem; }
/* the browser skips a turn's blocks until they are near the screen (a log can hold thousands) */
.turn-body { margin-top: 8px; content-visibility: auto; contain-intrinsic-size: auto 300px; }
/* the first block a reader has left showing sits right under the speaker line, the last ends the turn (site.js marks them) */
.turn-body > .first-shown, .turn-body > .block.first-shown > * { margin-top: 0; }
.turn-body > .last-shown, .turn-body > .block.last-shown > * { margin-bottom: 0; }
.model-change .mono { font-size: 0.75rem; }

/* collapsed rows: thinking, tool calls, system blocks, an agent run's steps */
.row { margin: 8px 0 0; border: 1px solid var(--rule-2); border-radius: 6px; background: var(--recess); font-family: var(--font-ui); }
.row > summary { display: flex; align-items: center; height: calc(2.25rem - 2px); padding: 0 11px 0 13px; border-radius: 5px; font-size: 0.875rem; cursor: pointer; list-style: none; overflow: hidden; white-space: nowrap; }
.row > summary::-webkit-details-marker { display: none; }
.row > summary:hover { background: var(--off); }
.row[open] > summary { border-bottom: 1px solid var(--rule); border-radius: 5px 5px 0 0; height: calc(2.25rem - 1px); }
.row-chevron { flex: none; color: var(--text-2); }
.row[open] > summary > .row-chevron { transform: rotate(90deg); }
.row-name { flex: 0 1 auto; min-width: 2rem; margin-left: 12px; color: var(--text-2); overflow: hidden; text-overflow: ellipsis; }
.row-tool > summary > .row-name { font-weight: 700; color: var(--text); }
.row-arg { flex: 0 100 auto; min-width: 0; margin-left: 10px; font-family: var(--font-mono); font-size: 0.75rem; color: var(--text-3); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.row-fill { flex: 1 1 16px; min-width: 8px; }
.row-time { flex: none; font-family: var(--font-mono); font-size: 0.75rem; color: var(--text-3); }
.row-note { flex: none; margin-left: 20px; color: var(--text-3); }
.row-body { padding: 12px; font-family: var(--font-body); }
.row-think > .row-body { color: var(--text-2); }
.row-label { margin-top: 12px; font-family: var(--font-ui); font-size: 0.75rem; line-height: 0.875rem; color: var(--text-3); }
.row-body > .row-label:first-child { margin-top: 0; }
.row-body > pre.code.tight, .row-output > :first-child { margin-top: 6px; }
.row-output { display: contents; }
.row-part { display: contents; }          /* a thinking block joined to the row above it (site.js) */
.row.merged { display: none; }
/* a context compaction's summary: the row of a code card, the summary opening inside it */
.row-compaction > summary { height: calc(4rem - 2px); padding: 0 11px 0 15px; border-radius: 7px; }
.row-compaction > summary:hover { background: none; }
.row-compaction[open] > summary { height: calc(4rem - 1px); border-radius: 7px 7px 0 0; }
.row-compaction .kind-icon { margin-right: 12px; }
.row-compaction .card-name { color: var(--text); }
.row-compaction .card-btn { margin-left: 16px; }
.row-compaction:not([open]) .when-open, .row-compaction[open] .when-closed { display: none; }
.add { color: var(--add); }
.del { color: var(--del); }

/* what the reader chose not to see (site.js sets these on <body>) */
.hide-user .r-user, .hide-user .turn-user,
.hide-assistant .r-assistant,
.hide-think .r-think,
.hide-tool .r-tool,
.hide-system .r-system { display: none; }
.turn.empty { display: none; }

/* ── Artifacts ────────────────────────────────────────────────────────────────── */
.works { display: flex; flex-direction: column; gap: 22px; border-top: 1px solid var(--rule); padding-top: 23px; }
.work { display: block; color: var(--text); }
.work:hover { text-decoration: none; color: var(--link); }
.work img { display: block; width: 100%; border: 1px solid var(--rule); }
.work:hover img { border-color: var(--link); }
.work-caption { display: flex; flex-direction: column; font-family: var(--font-ui); font-size: 0.875rem; margin-top: 6px; }
.work-meta { font-size: 0.75rem; color: var(--text-2); }
.works-mosaic { display: grid; grid-template-columns: 0.735fr 1fr; gap: 24px; }
.works-stack { display: flex; flex-direction: column; justify-content: space-between; gap: 24px; }

/* ── Dialogs, the lightbox ────────────────────────────────────────────────────── */
dialog.settings { background: var(--panel); color: var(--text); border: 1px solid var(--rule-2); border-radius: 6px; padding: 18px 20px; font-family: var(--font-ui); font-size: 0.875rem; min-width: 290px; }
dialog.settings::backdrop { background: rgba(0, 0, 0, 0.5); }
dialog.settings h2 { font-size: 1rem; margin: 0 0 12px; }
dialog.settings label { display: grid; grid-template-columns: 110px 1fr 44px; align-items: center; gap: 10px; margin: 0 0 10px; }
dialog.settings label.check { display: flex; }
dialog.settings select, dialog.settings button { background: var(--recess); border: 1px solid var(--rule-2); border-radius: 4px; padding: 3px 10px; cursor: pointer; }
dialog.settings input[type=range] { accent-color: var(--link); width: 100%; }
dialog.settings output { font-family: var(--font-mono); font-size: 0.75rem; color: var(--text-2); }
.settings-actions { display: flex; justify-content: flex-end; gap: 8px; margin-top: 14px; }
.lightbox { position: fixed; inset: 0; z-index: 50; background: rgba(0, 0, 0, 0.88); display: flex; align-items: center; justify-content: center; cursor: zoom-out; overflow: auto; }
.lightbox img { max-width: 96vw; max-height: 96vh; }
.lightbox.full { align-items: flex-start; justify-content: flex-start; }
.lightbox.full img { max-width: none; max-height: none; }
mark.passage { background: var(--mark-wash); color: inherit; outline: 1px solid var(--mark); }
.settings-note { grid-column: span 2; color: var(--text-2); font-size: 0.8125rem; }
.link-preview { position: absolute; z-index: 30; width: min(420px, calc(100vw - 16px)); background: var(--panel); border: 1px solid var(--rule-2); border-radius: 6px; padding: 10px 12px; box-shadow: 0 8px 24px rgba(0, 0, 0, 0.35); font-family: var(--font-ui); pointer-events: none; }
.link-preview-title { font-family: var(--font-title); font-weight: var(--weight-title); font-size: 0.9375rem; margin-bottom: 4px; }
.link-preview-text { font-size: 0.8125rem; line-height: 1.45; color: var(--text-2); }

/* ── The account page (renderer/account.lua: a 720 column, the email and tier in bold UI type) ── */
.page-account { max-width: calc(720px + 40px); }
.account { font-family: var(--font-ui); }
.account p { margin: 0 0 6px; }
.account-who { display: flex; align-items: center; gap: 6px; font-size: 0.875rem; }
.account-tip { position: relative; width: 1rem; height: 1rem; padding: 0; border: 1.5px solid var(--text-3); border-radius: 50%; background: none; color: var(--text-3); font: 700 0.625rem/1 var(--font-ui); cursor: help; }
.account-tip:hover, .account-tip:focus { color: var(--text); border-color: var(--text); }
.account-tip:hover::after, .account-tip:focus::after { content: attr(data-tip); position: absolute; left: 0; bottom: calc(100% + 8px); width: max-content; max-width: min(560px, 80vw); padding: 2px 4px; background: var(--text); color: var(--bg); font: 400 0.75rem/1.35 var(--font-ui); text-align: left; white-space: normal; z-index: 5; }
.account-h2 { font-family: var(--font-title); font-size: var(--size-h2); margin: 30px 0 6px; }
.account-gap { margin-top: 28px !important; }
.account-link { background: none; border: 0; padding: 0; font: inherit; font-size: 0.875rem; color: var(--link); cursor: pointer; }
.account-link:hover { color: var(--link-hover); }
.account-link.strong { font-weight: 700; }
.account-link.dim { color: var(--text-3); }
.account-form { display: flex; gap: 8px; margin: 12px 0; }
.account-form input { flex: 1; min-width: 0; background: var(--recess); border: 1px solid var(--rule-2); border-radius: 6px; padding: 8px 10px; outline: none; }
.account-form input:focus { border-color: var(--link); }
.account-form button { background: none; border: 1px solid var(--link); border-radius: 6px; padding: 0 14px; color: var(--link); font-weight: 700; cursor: pointer; }
.account-note { margin-top: 10px !important; }

/* ── Search ───────────────────────────────────────────────────────────────────── */
.page-search { max-width: calc(var(--col-list) * var(--user-column) + 40px); }
.search-form { display: flex; gap: 8px; margin: 0 0 10px; }
.search-form input { flex: 1; background: var(--recess); border: 1px solid var(--rule-2); border-radius: 4px; padding: 7px 10px; outline: none; }
.search-form input:focus { border-color: var(--link); }
.search-form button { background: var(--panel); border: 1px solid var(--rule-2); border-radius: 4px; padding: 7px 14px; cursor: pointer; }
.search-entry { grid-template-columns: 110px 1fr auto; height: auto; padding-top: 9px; padding-bottom: 9px; row-gap: 3px; }
.search-snippet { grid-column: 2 / -1; font-family: var(--font-ui); font-size: 0.8125rem; color: var(--text-2); }

/* ── The lifetime account's box (account.js makeBox; renderer/account.lua account_box_*: 680 wide at most,
   22 in, the message in the body face at 25 a line, 16 under it the field and "create account" side by side
   (stacked when the field would be under 240), 40 tall, 8 round, 10 apart; a line kept under them for what
   went wrong; 18 under the box). The index's first row, and what Phylactery's ending builds (unlock.js). ── */
.account-slot { margin: 0 0 18px; }
.account-box { max-width: 680px; box-sizing: border-box; border: 1px solid var(--rule); border-radius: 10px; padding: 22px 22px 14px; transform-origin: 50% 50%; }
.account-box p { margin: 0; }
.account-box-message { font-family: var(--font-body); font-size: 1rem; line-height: 1.5625; color: var(--text); letter-spacing: var(--track-body); }
.account-box-form { display: flex; flex-wrap: wrap; gap: 10px; margin-top: 16px; }
.account-box-form input { flex: 1 1 240px; min-width: 0; box-sizing: border-box; height: 40px; padding: 0 12px; border: 1px solid var(--rule);
  border-radius: 8px; background: var(--recess); color: var(--text); font: 0.875rem var(--font-ui); outline: none; }
.account-box-form input::placeholder { color: var(--text-3); opacity: 1; }
.account-box-form input:hover::placeholder { color: var(--text-2); }
.account-box-form input:focus { border-color: var(--link); }
.account-box-form button { flex: none; height: 40px; padding: 0 18px; border: 0; border-radius: 8px; background: var(--link); color: var(--bg);
  font: 700 0.875rem var(--font-ui); cursor: pointer; }
.account-box-form button:hover:not(:disabled) { background: var(--link-hover); }
.account-box-sent { margin-top: 16px; font: 0.875rem var(--font-ui); }
.account-box-sent p:first-child { line-height: 40px; color: var(--text); }
.account-box-again { margin-top: 6px; background: none; border: 0; padding: 0; font: inherit; color: var(--text-2); cursor: pointer; }
.account-box-again:hover { color: var(--link); }
.account-box-note { margin-top: 8px !important; min-height: 16px; font: 0.75rem/16px var(--font-ui); color: var(--text-3); }
.account-box-in { border: 0; padding: 14px 0; font: 0.875rem var(--font-ui); }
.account-box-who { color: var(--text-3); margin-right: 12px; }
/* while the letters build it: there, the right size, unseen (the letters land where its text is) */
.account-box.is-building { border-color: transparent; }
.account-box.is-building > * { opacity: 0; }
.unlock-canvas { position: fixed; left: 0; top: 0; pointer-events: none; z-index: 30; }

/* ── The chat under the account (account.js; the owner: "just below the account information, centered") ── */
.chat { max-width: 560px; margin: 36px auto 0; font-family: var(--font-ui); }
.chat .account-h2 { margin-top: 0; text-align: center; }
.chat-thread { max-height: 60vh; overflow-y: auto; display: flex; flex-direction: column; gap: 10px; padding: 12px; border: 1px solid var(--rule-2); border-radius: 8px; background: var(--recess); }
.chat-empty { margin: 0; text-align: center; font-size: 0.875rem; }
.chat-msg { max-width: 85%; }
.chat-msg.from-me { align-self: flex-end; text-align: right; }
.chat-msg.from-owner { align-self: flex-start; }
.chat-body { display: inline-block; padding: 7px 11px; border-radius: 8px; font-family: var(--font-body); font-size: 0.9375rem; line-height: 1.4; text-align: left; overflow-wrap: anywhere; }
.from-me .chat-body { background: color-mix(in srgb, var(--owner) 16%, var(--panel)); }
.from-owner .chat-body { background: var(--panel); border: 1px solid var(--rule-2); }
.chat-meta { margin-top: 3px; }
.chat-form { display: flex; gap: 8px; margin-top: 10px; }
.chat-form textarea { flex: 1; min-width: 0; resize: vertical; min-height: 2.75rem; background: var(--recess); border: 1px solid var(--rule-2); border-radius: 6px; padding: 8px 10px; color: var(--text); font: 0.9375rem/1.4 var(--font-body); outline: none; }
.chat-form textarea:focus { border-color: var(--link); }
.chat-form button { align-self: flex-end; height: 2.25rem; background: none; border: 1px solid var(--link); border-radius: 6px; padding: 0 14px; color: var(--link); font-weight: 700; cursor: pointer; }
.chat-form button[disabled] { opacity: 0.5; cursor: default; }

/* ── A posted video's views (site.js; canvas.lua draw_views_line): an eye, the count when posted, an arrow, the gain ── */
.video-views { display: flex; align-items: center; gap: 5px; margin: 6px 0 0; color: var(--text-3); cursor: help; width: max-content; }

/* ── The owner's backup warning (owner.js; renderer/health.lua: the meta face, at the top line's right end,
   in its own red: the themes have no warning colour) ── */
.health-warn { margin-left: auto; font-family: var(--font-ui); font-size: 0.75rem; color: #ec685a; white-space: nowrap; }


/* ── The board (/admin; renderer/board.lua, filled by board.js) ───────────────── */
/* The old board was the whole window: a 40 gutter, 36 from the top, 60 under the last line. Every line
   advances by its face's height + 4 (body 16: 22, small 12: 18, ui bold 14: 20, h2 21: 28, h1 28: 36); a
   heading has 28 above it and 4 under it; nested rows sit 10, 24 or 48 in. Its "mono" rows were drawn in
   the body face (the theme had no mono face) with their columns padded by spaces, so spaces are kept (and
   a row too long for a phone wraps). A link keeps its row's colour: the hand cursor is the only cue. */
.page-board { max-width: none; margin: 36px 0 60px; padding: 0 40px; }
.board .ln { margin: 0; white-space: pre-wrap; overflow-wrap: anywhere; }
.board .ln:empty::before { content: '\200b'; }    /* an empty line still takes its line, as the old board's did */
.board .f-body { font-family: var(--font-body); font-size: 1rem; font-weight: 400; line-height: 1.375rem; }
.board .f-small { font-family: var(--font-ui); font-size: 0.75rem; font-weight: 400; line-height: 1.125rem; }
.board .f-bold { font-family: var(--font-ui); font-size: 0.875rem; font-weight: 700; line-height: 1.25rem; }
.board .f-h1 { font-family: var(--font-title); font-size: var(--size-h1); font-weight: var(--weight-title); line-height: calc(var(--size-h1) * 9 / 7); }
.board .f-h2 { font-family: var(--font-title); font-size: var(--size-h2); font-weight: var(--weight-title); line-height: calc(var(--size-h2) * 4 / 3); }
.board .c-text { color: var(--text); }
.board .c-med { color: var(--text-2); }
.board .c-dim { color: var(--text-3); }
.board .c-link { color: var(--link); }
.board .c-hot { color: var(--link-hover); }
.board .c-mark { color: var(--mark); }
.board a, .board a:hover { color: inherit; text-decoration: none; }
.board .tok { background: none; border: 0; padding: 0; margin: 0; font: inherit; letter-spacing: inherit; text-align: inherit; white-space: inherit; color: var(--link); cursor: pointer; }
.board .i10 { margin-left: 0.625rem; }
.board .i24 { margin-left: 1.5rem; }
.board .i48 { margin-left: 3rem; }
/* one line, cut with an ellipsis where it would run out (text_truncate) */
.board .cut { white-space: pre; overflow: hidden; text-overflow: ellipsis; }
.board .err-head { max-width: calc(min(68.75rem, 100% - 2.5rem) - 1.5rem); }
.board .tcut { display: inline-block; max-width: 14.375rem; overflow: hidden; text-overflow: ellipsis; white-space: pre; vertical-align: top; }
.board .tcut-wide { max-width: 32.5rem; }
/* a visit's trail: lines 16 apart, a wrapped line starts with its separator */
.board .trail { line-height: 1rem; margin-bottom: 0.125rem; }
.board .tu { display: inline-block; max-width: 100%; white-space: pre-wrap; overflow-wrap: anywhere; vertical-align: top; }
/* the graph: 120 tall, 34 of it under the columns for the dates and the caption */
.board .chart { position: relative; height: 9.625rem; }
.board .chart > * { position: absolute; display: block; }
.board .chart .t { font-family: var(--font-ui); font-size: 0.75rem; line-height: 0.875rem; color: var(--text-3); white-space: pre; }
.board .chart .tick { transform: translateX(-50%); }
.board .chart .rule { height: 1px; background: var(--text-3); }
.board .chart .bar { background: var(--link); }
.board .chart .bar.hot { background: var(--text); }
.board .chart .guide { width: 1px; background: var(--text-2); }
.board .chart .tip { padding: 0.125rem 0.25rem 0.1875rem; background: var(--text); color: var(--bg); font-family: var(--font-ui); font-size: 0.75rem; line-height: 0.875rem; white-space: pre; pointer-events: none; }
/* the games page's item table: columns at 0 / 150 / 220 / 320 / 430 */
.board .cols-wrap { overflow-x: auto; }
.board .cols { display: grid; grid-template-columns: 9.375rem 4.375rem 6.25rem 6.875rem max-content; white-space: pre; }
/* the chat: a thread opens under its row, his own messages on the right */
.board .chat-thread { max-width: 45rem; }
.board .chat-mine { text-align: right; }
.board .chat-form { display: flex; align-items: flex-end; gap: 8px; margin-top: 0.75rem; }
.board .chat-form textarea { flex: 1; min-width: 0; min-height: 4rem; resize: vertical; padding: 8px 10px; background: var(--recess); border: 1px solid var(--rule-2); border-radius: 6px; outline: none; color: var(--text); font-family: var(--font-body); font-size: 1rem; line-height: 1.375rem; }
.board .chat-form textarea:focus { border-color: var(--link); }
.board .chat-form textarea::placeholder { color: var(--text-3); opacity: 1; }
.board .chat-form button { flex: none; height: 2.5rem; padding: 0 14px; background: none; border: 1px solid var(--link); border-radius: 6px; color: var(--link); font-family: var(--font-ui); font-size: 0.875rem; font-weight: 700; cursor: pointer; }
.board .chat-form button:disabled { opacity: 0.5; cursor: default; }

/* ── Narrow windows ───────────────────────────────────────────────────────────── */
/* no room for the face in the gutter left of the log's column (the old client's rule: it needs 56px there) */
@media (max-width: 1081px) { .turn-avatar { display: none; } }
@media (max-width: 767px) {
  :root { --top-h: 3.25rem; }
  .top { padding: 0 16px; overflow-x: auto; scrollbar-width: none; }
  .top-nav { gap: 0 18px; }
  .top-search { display: none; }
  .page { margin-top: 20px; padding: 0 16px; }
  .page-game { padding: 0; }   /* the game's frame runs edge to edge; the text keeps the phone's gutter */
  .page-game > .crumb, .page-game > .title, .page-game > .prose > :not(.game-frame) { padding-left: 16px; padding-right: 16px; }
  .entries { margin: 0 -16px; }
  /* a narrow row is two lines, as the old client's: the title, then the date and the id */
  .entry { grid-template-columns: auto 1fr auto; grid-template-areas: 'title title kind' 'date id id'; gap: 4px 12px; height: auto; padding: 12px 16px; }
  .entry-date { grid-area: date; }
  .entry-id { grid-area: id; }
  .entry-kind { grid-area: kind; margin-left: 0; }
  .entry-title { grid-area: title; }
  .works-mosaic { grid-template-columns: 1fr; }
  .crumb { flex-direction: column; gap: 4px; }
  .log-models { flex-basis: 100%; margin-left: 0; padding-left: 0; }
  .card-kind { width: auto; margin-right: 16px; }
  .find-who { width: 120px; }
  .find-key { display: none; }
  .turn-right { display: none; }
  dialog.settings { min-width: 0; width: calc(100vw - 32px); }
}
