/* The site's look since the launch (2026-10-28): the board prototype's layout and parts, the same
   under every skin. All colours, the background and the picture come from the skin (snow-ice.css,
   snow.css, two.css and snow.js; the tests area keeps the others), so a VN theme is a small swap:
   colours, background, weather, picture. DotGothic16 at 16px, its own grid size. */
/* Whole pixels (2026-11-05, after a visitor's ask said the letters looked fuzzy): the font's dots are exact pixels at 16
   and 32 px (scripts/sharpen-font.py), but browsers place text to a quarter pixel across, so a line that starts part-way
   into a pixel is smeared again. So the page's column starts on a whole pixel and is an even number of pixels wide, and
   every grid of equal columns is whole even columns with the last one taking the rest (even too, so text centred in a
   cell lands on a whole pixel). Each round() rule comes after the plain one it replaces, which a browser without round()
   keeps. check.mjs checks every public page at several window widths (pixelCheck). */
:root { --page: #1a1a1f; --wall: none; --panel: #24242b; --head: #2e2e36; --head-edge: 0 solid transparent; --title: #ffffff;
        --line: #4a4a55; --dots: #3a3a44; --ink: #ececf0; --mute: #a0a0ab; --accent: #f0d27a; --track: #34343c;
        --field: #15151a; --btn: #2f2f37; --btn-line: #66667a; --tag: #f0d27a; --tag-ink: #111; --accent-ink: #111; --heart: #f19bbd; --heart-hi: #ffe3ee;
        --good: #9be3a6; --fair: #f0d27a; --poor: #f09b7c; --bad: #e46b7d; --shadow: #0a0a14; }
/* The site's own letters of DotGothic16 (Fontworks, SIL Open Font License 1.1): ASCII, Latin-1 and the few others its
   pages write, served from here so the first paint doesn't wait for Google's stylesheet, 30 KB of 123 font faces
   (FINDINGS, *The home page while it loads*). Any other character, Japanese in an ask say, falls to the whole
   DotGothic16 from that stylesheet, at the foot of each page so that nothing waits for it. */
@font-face { font-family: "DotGothic16 Site"; src: url("dot-site.woff2") format("woff2"); font-display: swap; }
* { box-sizing: border-box; }
html { color-scheme: dark; }
body { margin: 0; min-height: 100vh; overflow-x: hidden; color: var(--ink); font: 16px/1.5 "DotGothic16 Site", DotGothic16, "MS Gothic", monospace;
       background-color: var(--page); background-image: var(--wall); background-attachment: fixed; }
a { color: inherit; }
.wrap { position: relative; z-index: 1; max-width: 980px; margin: 0 auto; padding: 22px 16px 10px;
        width: min(980px, round(down, 100%, 2px)); margin: 0 0 0 max(0px, round(down, (100% - 980px) / 2, 1px)); }

/* The picture: the skin's painting, scaled up and cropped, the name over it. */
.banner { position: relative; border: 1px solid var(--line); overflow: hidden; background: var(--panel); }
.banner canvas { display: block; width: 100%; height: 210px; object-fit: cover; object-position: var(--crop, center 60%); }
.banner .name { position: absolute; left: 16px; bottom: 12px; margin: 0; font-size: 16px; font-weight: 400; line-height: 1.25;
                text-shadow: 2px 2px 0 var(--shadow); z-index: 2; }
.banner .name b { display: block; font-size: 32px; font-weight: 400; color: var(--title); }
.banner .clock { position: absolute; right: 12px; top: 8px; text-shadow: 1px 1px 0 var(--shadow); z-index: 2; }

.grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 8px; margin-top: 8px;
        grid-template-columns: repeat(2, round(down, (100% - 16px) / 3, 2px)) 1fr; }
.side { display: grid; gap: 8px; align-content: start; }
/* Home: doorbell, heartbeat and the side column on top, room air wide below (on a phone: doorbell,
   heartbeat, room air, then the side column, which is the order they come in the page). */
.home .air-p { grid-column: 1 / -1; grid-row: 2; }
.home .side { grid-column: 3; grid-row: 1; }
.air-wide { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 2fr); gap: 4px 24px; align-items: start;
            grid-template-columns: round(down, (100% - 24px) / 3, 2px) minmax(0, 1fr); }
.air-wide .spark { height: 64px; margin-top: 0; }
@media (max-width: 860px) {
  .grid { grid-template-columns: 1fr 1fr; grid-template-columns: round(down, (100% - 8px) / 2, 2px) 1fr; }
  .home .air-p, .home .side { grid-row: auto; }
  .home .air-p { grid-column: 1 / -1; }
  .home .side { grid-column: 1 / -1; grid-template-columns: 1fr 1fr; grid-template-columns: round(down, (100% - 8px) / 2, 2px) 1fr; }
  .air-wide { grid-template-columns: 1fr; }
}
/* Home with the ask box (its switch on: the Worker adds .with-ask, src/ask-pages.js): the grid the board
   prototype had with it (commit 06862c7), room air not wide: room air, the doorbell and the heartbeat on
   top, the ask box (two columns) and the side column below. Narrower, it's the grid above with the ask
   box full width before room air; on a phone the page's own order: the doorbell, then the ask box, then
   the heartbeat, room air and the side column (I said, 2026-10-29). */
@media (min-width: 861px) {
  .home.with-ask .air-p { grid-column: 1; grid-row: 1; }
  .home.with-ask .air-wide { grid-template-columns: minmax(0, 1fr); gap: 0; }
  .home.with-ask .air-wide .spark { height: 40px; margin-top: 6px; }
  .home.with-ask .ask-p { grid-column: 1 / span 2; grid-row: 2; }
  .home.with-ask .side { grid-column: 3; grid-row: 2; }
}
@media (max-width: 860px) { .home .ask-p { grid-column: 1 / -1; } }
@media (min-width: 561px) and (max-width: 860px) {
  .home.with-ask .ask-p { order: 1; }
  .home.with-ask .air-p { order: 2; }
  .home.with-ask .side { order: 3; }
}
@media (max-width: 560px) { .grid, .side, .home .side { grid-template-columns: 1fr; } .banner canvas { height: 150px; } }

/* Panels: a 1px frame, a title bar, dotted rows inside. */
.panel { background: var(--panel); border: 1px solid var(--line); padding: 8px 12px 10px; min-width: 0; }
.ph { display: flex; justify-content: space-between; align-items: baseline; gap: 10px; margin: -8px -12px 8px; padding: 3px 12px 3px 10px;
      background: var(--head); border-left: var(--head-edge); border-bottom: 1px solid var(--line); }
.ph b { font-weight: 400; color: var(--title); }
.ph b a { text-decoration: none; }
.ph b a:hover { text-decoration: underline; }
.ph span { color: var(--mute); white-space: nowrap; }
.row { display: flex; justify-content: space-between; gap: 10px; padding: 3px 0; border-bottom: 1px dotted var(--dots); }
.row:last-child { border-bottom: 0; }
.row > span:first-child { color: var(--mute); }
/* (Whole pixels: a value too long for its row wraps and is squeezed to a fraction of a pixel; lined up on the right,
   its lines still end, and so start, on whole pixels.) */
.row > span:last-child:not(:first-child) { text-align: right; }
.log .row { justify-content: flex-start; }
.log .row > span:last-child { text-align: left; }
.log .row > span:first-child { flex: none; width: 54px; }
.mute { color: var(--mute); }
.on { color: var(--good); }
.on::before { content: ""; display: inline-block; width: 8px; height: 8px; margin-right: 6px; background: currentColor; vertical-align: 1px; }
.new { display: inline-block; margin-left: 6px; padding: 0 4px; color: var(--tag-ink); background: var(--tag); line-height: 1.35; }

.big { font-size: 32px; line-height: 1.1; color: var(--title); }
.level { padding: 0 6px; color: var(--accent-ink); background: var(--fair); }
/* Thin bars: CO2 from 400 to 2000 ppm, with marks where the board's light changes. */
.bar { position: relative; height: 4px; margin: 8px 0 6px; background: var(--track); }
.bar i { position: absolute; left: 0; top: 0; bottom: 0; background: var(--fair); }
.bar u { position: absolute; top: -2px; width: 1px; height: 8px; background: var(--mute); }
.spark { display: block; width: 100%; height: 40px; margin-top: 6px; }
.spark .fill { fill: var(--fair); opacity: .14; }
.spark .line { fill: none; stroke: var(--fair); stroke-width: 1; shape-rendering: crispEdges; }

.btn { display: inline-block; padding: 1px 10px; border: 1px solid var(--btn-line); background: var(--btn); color: var(--ink);
       font: inherit; text-decoration: none; cursor: pointer; }
.btn:hover { filter: brightness(1.2); }
.btns { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 8px; }

/* Ouba's wall screen in miniature: the board's own font on black. */
.wall { display: block; width: 100%; max-width: 240px; margin: 2px auto 4px; image-rendering: pixelated; border: 1px solid var(--line); background: #000; }
.cap { text-align: center; color: var(--mute); }

.heart { display: flex; align-items: center; gap: 12px; }
.heart svg.px { width: 36px; height: 32px; shape-rendering: crispEdges; transition: transform .08s; }
.heart svg.px rect { fill: var(--heart); }
.heart svg.px rect.hi { fill: var(--heart-hi); }
.heart svg.px.beat { transform: scale(1.18); }
.hb { display: block; width: 100%; margin-top: 4px; }
.c-grid { stroke: var(--dots); shape-rendering: crispEdges; }
.c-label { fill: var(--mute); font: 12px "DotGothic16 Site", DotGothic16, monospace; }
.c-line { stroke: var(--heart); stroke-width: 1; shape-rendering: crispEdges; }
.c-now { fill: var(--title); }

.ask { display: flex; gap: 6px; margin-bottom: 8px; }
.ask a.field { flex: 1; min-width: 0; padding: 2px 8px; border: 1px solid var(--line); background: var(--field); color: var(--mute); text-decoration: none; }
.qa { padding: 6px 0; border-bottom: 1px dotted var(--dots); }
.qa:last-of-type { border-bottom: 0; }
.qa .q { color: var(--title); }
.qa a.q.drawn { display: block; }
.qa .a { color: var(--accent); }
.qa .a b, .thread .a b { font-weight: 400; }
.qa .m { color: var(--mute); }
.more { display: block; margin-top: 6px; text-align: right; color: var(--mute); }
/* The home page's parts that come from the API a moment after the page: held at about their final size, so nothing
   below them jumps when they arrive. The asks' heights are what three asks took (measured 2026-10-30); another three
   differ a little, which leaves a small jump at worst. */
.btns.wait { visibility: hidden; }
.home [data-heart="wait"] { margin: 0; min-height: 66px; }
.asks-wait { margin: 0; min-height: 500px; }
@media (max-width: 560px) { .asks-wait { min-height: 600px; } }

/* The feedback footer: public/footer.js's, in the page's [data-feedback] slot (its parts carry
   these fb-* classes), and the line about the visit log under it (#visits-note). */
.fbp { margin-top: 8px; }
.fb-open { width: 100%; padding: 6px 12px; background: var(--panel); border: 1px solid var(--line); color: var(--mute); font: inherit; text-align: left; cursor: pointer; }
.fb-open u { color: var(--title); }
.fb-form { margin-top: 6px; padding: 10px 12px; background: var(--panel); border: 1px solid var(--line); }
.fb-kinds { display: flex; flex-wrap: wrap; gap: 6px; }
.fb-kinds button, .fb-send, .fb-again { padding: 1px 10px; border: 1px solid var(--btn-line); background: var(--btn); color: var(--ink); font: inherit; cursor: pointer; }
.fb-kinds button[aria-pressed="true"] { background: var(--accent); color: var(--accent-ink); }
.fb-text, .fb-contact { width: 100%; min-width: 0; padding: 4px 8px; border: 1px solid var(--line); background: var(--field); color: var(--ink); font: inherit; }
.fb-text { display: block; height: 80px; margin: 8px 0 6px; resize: vertical; }
.fb-row { display: flex; gap: 6px; }
.fb-send:disabled { opacity: .5; cursor: default; }
.fb-meta { display: flex; justify-content: space-between; gap: 10px; margin-top: 6px; color: var(--mute); font-size: 12px; }
.fb-done { margin: 6px 0 0; padding: 6px 12px; background: var(--panel); border: 1px solid var(--line); }

.mock, .visits-note { margin: 18px 0 10px; text-align: center; color: #9a9bb4; font: 12px/1.7 ui-monospace, Consolas, monospace; text-shadow: 1px 1px 0 #000; }
.mock a { color: inherit; }
.mock b { color: #fff; font-weight: 400; }

/* ---------------------------------------------------------------- the other pages (same parts) */
[hidden] { display: none !important; }
/* Inner pages show a shorter cut of the skin's picture, the page's name under the site's. */
.banner.short canvas { height: 128px; }
@media (max-width: 560px) { .banner.short canvas { height: 104px; } }

/* The link row under the picture: one cell per part, the page you're on lit like a title bar. */
/* (Held at its final height, one row, or two on a phone: proto.js fills it, and on a slow phone that comes after
   the first paint.) */
/* (Whole pixels: the cells are whole even widths, and a cell's 1px divider comes out of its left padding, so every cell's
   text box is even and its centred name lands on a whole pixel.) */
nav.links { display: grid; grid-template-columns: repeat(5, 1fr); min-height: 32px; margin-top: 8px; border: 1px solid var(--line); background: var(--panel);
            grid-template-columns: repeat(4, round(down, 100% / 5, 2px)) 1fr; }
nav.links a { padding: 3px 6px 3px 5px; text-align: center; text-decoration: none; color: var(--ink); border-left: 1px solid var(--dots); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
nav.links a:first-child { border-left: 0; padding-left: 6px; }
nav.links a:hover { color: var(--title); text-decoration: underline; }
nav.links a[aria-current="page"] { background: var(--head); color: var(--title); }
@media (max-width: 700px) {
  nav.links { grid-template-columns: repeat(3, 1fr); grid-template-columns: repeat(2, round(down, 100% / 3, 2px)) 1fr; min-height: 63px; }
  nav.links a:nth-child(4) { border-left: 0; padding-left: 6px; }
  nav.links a:nth-child(n+4) { border-top: 1px solid var(--dots); }
  nav.links a:nth-child(5) { grid-column: span 2; border-left: 1px solid var(--dots); padding-left: 5px; }
}
/* With the ask box on (the Worker adds .with-ask), six: two rows of three on a phone. */
nav.links.with-ask { grid-template-columns: repeat(6, 1fr); grid-template-columns: repeat(5, round(down, 100% / 6, 2px)) 1fr; }
@media (max-width: 1011px) { nav.links.with-ask .wide { display: none; } }
@media (max-width: 700px) {
  nav.links.with-ask { grid-template-columns: repeat(3, 1fr); grid-template-columns: repeat(2, round(down, 100% / 3, 2px)) 1fr; }
  nav.links.with-ask a:nth-child(5) { grid-column: auto; }
}

/* Layout helpers on the same three-column grid. */
.span-2 { grid-column: span 2; }
.span-3 { grid-column: 1 / -1; }
.stack { display: grid; gap: 8px; align-content: start; }
@media (max-width: 860px) { .span-2 { grid-column: 1 / -1; } }
@media (max-width: 560px) { .span-2, .span-3 { grid-column: auto; } }
.panel p { margin: 6px 0; }
.panel > p:first-of-type { margin-top: 0; }
.lead { color: var(--title); }
.big-msg { padding: 22px 8px 14px; text-align: center; font-size: 20px; color: var(--title); }
.center { text-align: center; }

/* Form parts. */
.text { width: 100%; min-width: 0; padding: 4px 8px; border: 1px solid var(--line); background: var(--field); color: var(--ink); font: inherit; }
textarea.text { display: block; resize: vertical; }
.text::placeholder { color: var(--mute); opacity: .8; }
.f { padding: 6px 0; border-bottom: 1px dotted var(--dots); }
.f:last-child { border-bottom: 0; }
.f > label, .f > .l { display: block; margin-bottom: 4px; color: var(--title); }
.hint { display: block; margin-top: 3px; color: var(--mute); }
.count { float: right; color: var(--mute); }
.check { display: flex; gap: 8px; align-items: baseline; cursor: pointer; }
.check input, .opts input { accent-color: var(--accent); }
.opts { display: flex; flex-wrap: wrap; gap: 6px; }
.opts label { display: inline-flex; align-items: center; gap: 6px; padding: 1px 10px 1px 6px; border: 1px solid var(--btn-line); background: var(--btn); cursor: pointer; }
.opts label:has(input:checked) { background: var(--accent); color: var(--accent-ink); }
.send-row { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 10px; }
.btn.go { padding: 3px 18px; background: var(--accent); color: var(--accent-ink); border-color: var(--title); }
.notice { margin: 0; padding: 6px 10px; border: 1px dashed var(--line); color: var(--mute); }
.notice b { color: var(--ink); font-weight: 400; }

/* Segmented switches: the tune maker's and the drawing tool's simple / advanced. */
.seg, .d-mode { display: inline-flex; }
.seg button, .d-mode button { padding: 1px 10px; border: 1px solid var(--btn-line); background: var(--btn); color: var(--ink); font: inherit; cursor: pointer; }
.seg button + button, .d-mode button + button { border-left: 0; }
.seg button[aria-pressed="true"], .d-mode button[aria-pressed="true"] { background: var(--accent); color: var(--accent-ink); }

/* The note with its live preview, and the drawing tool (public/tool/tool.js builds the tool). */
.note-split { display: grid; grid-template-columns: 1fr 1fr; gap: 12px; align-items: start; }
@media (max-width: 700px) { .note-split { grid-template-columns: 1fr; } }
.screen { display: block; width: 100%; max-width: 360px; image-rendering: pixelated; border: 1px solid var(--line); background: #000; }
.d { display: grid; gap: 6px; min-width: 0; }
/* The canvas fills its view; zoomed in, it's bigger and slides about inside it. Pixels stay square:
   the view is sized inside its border, so at its widest the doorbell's canvas shows at exactly 2x and
   the ask box's at 1x, with no stray rows or columns from rounding. */
.d-view { position: relative; box-sizing: content-box; width: calc(100% - 2px); max-width: 480px; overflow: hidden; border: 1px solid var(--line); background: var(--field);
          touch-action: none; cursor: crosshair; user-select: none; -webkit-user-select: none; }
.d-canvas { position: absolute; left: 0; top: 0; display: block; width: 100%; height: 100%; image-rendering: pixelated; }
.d-over { position: absolute; inset: 0; width: 100%; height: 100%; pointer-events: none; }
.d-view.grab { cursor: grab; }
.d-view.panning { cursor: grabbing; }
.d-bar { display: flex; flex-wrap: wrap; align-items: center; gap: 4px 10px; }
.d-note, .d-zoomed { color: var(--accent); }
/* "zoomed in 2x" on the canvas for a moment when the zoom changes; the pen goes straight through it. */
.d-zoompop { position: absolute; left: 4px; top: 4px; padding: 0 6px; background: var(--tag); color: var(--tag-ink); pointer-events: none; opacity: 0; transition: opacity .3s; }
.d-zoompop.showing { opacity: .9; transition: none; }
.d-warn { margin: 0; padding: 4px 8px; border: 1px dashed var(--tag); }
.d-tools { display: flex; flex-wrap: wrap; gap: 4px; align-items: center; }
.d-tools button, .d-zoomed button { padding: 0 8px; border: 1px solid var(--btn-line); background: var(--btn); color: var(--ink); font: inherit; cursor: pointer; }
.d-tools button[aria-pressed="true"] { background: var(--accent); color: var(--accent-ink); }
.d-tools button:disabled { opacity: .45; cursor: default; }
.d-adv { padding-top: 4px; border-top: 1px dotted var(--dots); }
.d-zoom { display: inline-flex; }
.d-zoom button + button { border-left: 0; }
.d-size { display: inline-flex; align-items: center; gap: 6px; color: var(--mute); }
.d-size input { width: 90px; accent-color: var(--accent); }
/* The patterns, stamps or text box for the tool in hand. */
.d-sub { padding-left: 8px; border-left: 2px solid var(--accent); }
.d-tools .d-chip { display: inline-grid; place-items: center; width: 30px; height: 26px; padding: 0; }
.d-chip canvas { width: 20px; height: 20px; object-fit: contain; image-rendering: pixelated; }
.d-text { max-width: 320px; }
/* Layers, top first: a thumbnail and name to pick one, and hide / show. */
.d-layers { padding: 6px 8px; border: 1px solid var(--line); background: var(--field); }
.d-list { list-style: none; margin: 0 0 6px; padding: 0; }
.d-lop { margin-bottom: 6px; } /* the layer's own opacity (2026-11-06), between the list and its buttons */
.d-layer { display: flex; align-items: center; gap: 6px; padding: 2px 0; border-bottom: 1px dotted var(--dots); }
.d-layer:last-child { border-bottom: 0; }
.d-layer button { padding: 0 8px; border: 1px solid var(--btn-line); background: var(--btn); color: var(--ink); font: inherit; cursor: pointer; }
.d-layer .d-pick { flex: 1; min-width: 0; display: flex; align-items: center; gap: 8px; text-align: left; border-color: transparent; background: transparent; }
.d-layer[aria-current="true"] .d-pick { border-color: var(--accent); color: var(--title); }
.d-layer.off .d-pick { opacity: .55; }
.d-thumb { flex: none; width: 48px; height: auto; border: 1px solid var(--line); background: var(--panel); image-rendering: pixelated; }
.d-colors { display: flex; flex-wrap: wrap; align-items: center; gap: 3px; }
.d-colors button { width: 20px; height: 20px; padding: 0; border: 1px solid var(--line); cursor: pointer; }
.d-colors button[aria-pressed="true"] { outline: 2px solid var(--title); outline-offset: 1px; }
.d-colors .d-any { width: 30px; height: 22px; padding: 0 2px; border: 1px solid var(--line); background: var(--btn); cursor: pointer; }
.d-help { margin: 0; color: var(--mute); }

/* The tune maker: a piano roll, one tone at a time. */
.tune { margin-top: 8px; padding: 8px 10px; border: 1px solid var(--line); background: var(--field); }
.t-bar { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 8px; margin-bottom: 8px; }
.t-tools { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; margin-bottom: 8px; }
.t-shift { display: inline-flex; align-items: center; gap: 4px; color: var(--mute); }
.btn[aria-pressed="true"] { background: var(--accent); color: var(--accent-ink); }
.t-speed { display: inline-flex; align-items: center; gap: 6px; color: var(--mute); }
.t-speed input { width: 120px; accent-color: var(--accent); }
.t-warn { margin: 0 0 8px; padding: 4px 8px; border: 1px dashed var(--tag); }
.t-scroll { overflow-x: auto; overscroll-behavior-x: contain; scrollbar-color: var(--line) transparent; }
.t-grid { --lab: 40px; position: relative; width: calc(var(--lab) + var(--cw) * var(--steps)); user-select: none; -webkit-user-select: none; }
.t-row { display: flex; height: var(--rh); }
.t-lab { position: sticky; left: 0; z-index: 2; flex: none; width: var(--lab); padding-right: 6px; text-align: right; font-size: 12px;
         line-height: var(--rh); color: var(--mute); background: var(--field); }
.t-row.c .t-lab { color: var(--title); }
.t-lane { position: relative; flex: none; width: calc(var(--cw) * var(--steps)); touch-action: pan-y; cursor: pointer; border-bottom: 1px solid var(--dots);
          background-image: linear-gradient(to right, var(--dots) 1px, transparent 1px), linear-gradient(to right, var(--line) 1px, transparent 1px),
                          linear-gradient(to right, var(--tag) 1px, transparent 1px);
          background-size: var(--cw) 100%, calc(var(--cw) * 4) 100%, calc(var(--cw) * 16) 100%; }
.t-row:first-child .t-lane { border-top: 1px solid var(--dots); }
.t-row.sharp .t-lane { background-color: rgba(0, 0, 0, .25); }
.t-row.sharp .t-lab { opacity: .75; }
.t-note { position: absolute; top: 1px; bottom: 1px; background: var(--accent); border: 1px solid var(--title); box-sizing: border-box; }
.t-note.arp { background-image: repeating-linear-gradient(135deg, transparent 0 3px, rgba(0, 0, 0, .35) 3px 5px); }
.t-bars { position: relative; height: 24px; margin-top: 4px; }
.t-copy { position: absolute; top: 0; padding: 1px 8px; border: 1px solid var(--btn-line); background: var(--btn); color: var(--ink); font: inherit; cursor: pointer; white-space: nowrap; }
.t-copy:hover { filter: brightness(1.2); }
.t-note.held { z-index: 1; outline: 1px solid var(--title); }
.t-head { position: absolute; top: 0; bottom: 0; width: var(--cw); background: rgba(255, 255, 255, .16); pointer-events: none; z-index: 3; }
.t-foot { display: flex; flex-wrap: wrap; justify-content: space-between; align-items: center; gap: 8px; margin-top: 8px; }
.t-info, .t-help { color: var(--mute); }
.t-help { margin: 6px 0 0; }

/* Charts (proto.js draws them). */
.chart { display: block; width: 100%; touch-action: pan-y; }
.c-area { fill: var(--accent); opacity: .12; }
.c-ref { stroke: var(--fair); stroke-dasharray: 3 3; shape-rendering: crispEdges; }
.c-cursor { stroke: var(--mute); shape-rendering: crispEdges; }
.c-dot { fill: var(--title); }
.c-tip { fill: var(--title); font: 12px "DotGothic16 Site", DotGothic16, monospace; }
.chart .c-line { stroke: var(--accent); }
.chart.co2 .c-line { stroke: var(--fair); }
.chart.co2 .c-area { fill: var(--fair); }
.ladder .row span:first-child::before { content: ""; display: inline-block; width: 10px; height: 10px; margin-right: 8px; background: var(--c); }

/* Readings in a row of three. */
.readings { display: grid; grid-template-columns: repeat(3, 1fr); gap: 8px; }
.readings > div { padding: 4px 8px 6px; border: 1px solid var(--dots); background: var(--field); }
.readings small { display: block; color: var(--mute); }
@media (max-width: 560px) { .readings { grid-template-columns: 1fr; } }

/* Thumbnails of what you've sent, and drawings in asks. */
.thumbs { display: grid; grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); gap: 10px; }
.thumbs figure { margin: 0; }
.thumbs canvas, .pic { display: block; width: 100%; max-width: 240px; border: 1px solid var(--line); image-rendering: pixelated; }
.thumbs figcaption { margin-top: 3px; color: var(--mute); }
.pic { margin: 6px 0; max-width: 200px; }
/* A drawing in a list (the home page's ask box, more asks): small, its pixels kept hard. */
.pic.mini { max-width: 160px; margin: 4px 0; }
a.rowlink .pic.mini { max-width: 96px; margin: 0; }

/* Threads (the once-over, 2026-10-29): each ask and ouba's answer together in one box, the boxes apart,
   no indent for follow-ups. The ask's row has who and when on the left; where it stands (and, on the site,
   "take it off the site") on the right. ouba's answer sits under it with a bar down its side. */
.post { margin-top: 12px; padding: 8px 10px 10px; border: 1px solid var(--line); background: var(--field); }
.post:first-child { margin-top: 0; }
.post .who { display: flex; flex-wrap: wrap; justify-content: space-between; align-items: center; gap: 4px 10px; color: var(--mute); }
.post .who b { font-weight: 400; color: var(--title); }
.post .who .acts { display: flex; flex-wrap: wrap; align-items: center; justify-content: flex-end; gap: 6px; }
.post .who .acts .btn { padding: 0 8px; }
.post .body { margin-top: 4px; white-space: pre-line; } /* an ask's or an answer's line breaks show as written (2026-11-03) */
.post .reply { margin-top: 10px; padding: 0 0 0 10px; border-left: 3px solid var(--accent); }
.post .reply .body { color: var(--accent); }
.st { padding: 0 6px; border: 1px solid var(--line); color: var(--mute); white-space: nowrap; }
.st.posted { border-color: var(--good); color: var(--good); }
.st.private { border-color: var(--accent); color: var(--accent); }
.st.waiting { border-style: dashed; }
.st.new { border-color: var(--tag); color: var(--tag-ink); background: var(--tag); }
/* Past asks (asks.js, listItem): the whole thread opens with a click anywhere on it, each part in the thread page's
   box. Since the likes (2026-11-06) its one link is the first ask's "anon asked", stretched over the whole box by its
   ::after, and the hearts sit above that (a button can't go inside a link). Hovering, or the link's focus, lights
   its boxes' edges and fills; pressing it, their edges. */
.item { position: relative; display: block; margin-top: 12px; color: inherit; text-decoration: none; }
.item:first-child { margin-top: 0; }
.item .post { margin-top: 4px; }
.item .post:first-child { margin-top: 0; }
.item a.open { color: inherit; text-decoration: none; }
.item a.open::after { content: ""; position: absolute; inset: 0; }
.item a.open:focus-visible { outline: none; }
.item a.open:focus-visible::after { outline: 2px solid var(--accent); outline-offset: 2px; }
.item:hover .post, .item:has(a.open:focus-visible) .post { border-color: var(--title); background: var(--head); }
.item:has(a.open:active) .post { border-color: var(--accent); }
.item .who .when { color: var(--mute); }
#more .item .pic.mini { max-width: 96px; }
/* A thread of more than one part is one frame around its boxes; "N more in this thread" is a dashed line between
   them, and "newest · nov 6" on its newest part says why it's where it is (a visitor's report, 2026-11-06). */
.item.thread { padding: 4px; border: 1px solid var(--line); background: var(--page); }
.item.thread:hover, .item.thread:has(a.open:focus-visible) { border-color: var(--title); }
.item .gap { margin-top: 4px; padding: 2px 10px; border: 1px dashed var(--line); color: var(--mute); text-align: center; }
.item:hover .gap, .item:has(a.open:focus-visible) .gap { border-color: var(--title); color: var(--title); }
.item .who .newest { color: var(--accent); }
/* On a heart, the box isn't what a tap does, so it stays unlit (a phone keeps "hover" where it was tapped). */
.item:has(.like:hover) .post { border-color: var(--line); background: var(--field); }
.item.thread:has(.like:hover) { border-color: var(--line); }
.item:has(.like:hover) .gap { border-color: var(--line); color: var(--mute); }
/* The like on ouba's answer (asks.js, likeButton(); 2026-11-06): the pixel heart, 7 by 6 at 2 px a dot, and how many,
   at the right end of his row; an outline until this browser likes it, then filled. As tall as the row's text, so
   nothing beside it moves off a whole pixel. Above a list's stretched link. */
.like { position: relative; z-index: 1; display: inline-flex; align-items: center; gap: 4px; margin: 0; padding: 0 4px;
        border: 0; background: none; color: var(--mute); font: inherit; cursor: pointer; }
.like svg { display: block; width: 14px; height: 12px; shape-rendering: crispEdges; }
.like svg rect.o { fill: var(--mute); }
.like svg rect.f { fill: transparent; }
.like:hover svg rect.o, .like:focus-visible svg rect.o { fill: var(--heart); }
.like.liked { color: var(--heart); }
.like.liked svg rect { fill: var(--heart); }
.like .n:empty { display: none; }
.like:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }
.post .said { margin: 6px 0 0; }
.post .said .btn { margin-left: 4px; }
/* "ouba answered you" on the home page's ask panel. */
a.answered { display: block; margin: 4px 0 6px; padding: 3px 10px; border: 1px solid var(--tag); background: var(--tag); color: var(--tag-ink); text-decoration: none; }
a.answered[hidden] { display: none; }
a.answered:hover { filter: brightness(1.1); }
/* The confirm window ("take it off the site"): the .dlg window, small. */
.dlg.ask-confirm { width: min(92vw, 380px); padding: 12px; }
.ask-confirm-q { margin: 0 0 4px; color: var(--title); }
.ask-confirm .btns { justify-content: flex-end; }
a.rowlink { display: flex; justify-content: space-between; align-items: baseline; gap: 10px; padding: 6px 0; border-bottom: 1px dotted var(--dots); text-decoration: none; }
a.rowlink:last-child { border-bottom: 0; }
a.rowlink:hover .q { text-decoration: underline; }
a.rowlink .q { color: var(--title); }

/* The private link, big, to copy or screenshot. */
.link-big { display: flex; flex-wrap: wrap; align-items: center; justify-content: center; gap: 10px; margin: 8px 0; padding: 14px 10px;
            border: 1px solid var(--title); background: var(--field); }
.link-big code { font: 24px/1.2 "DotGothic16 Site", DotGothic16, monospace; color: var(--title); overflow-wrap: anywhere; }
.addr { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 8px; }
.addr code { font: inherit; color: var(--title); overflow-wrap: anywhere; }

/* The heartbeat page: the same heart, bigger. */
.heart.large svg.px { width: 72px; height: 64px; }
.heart.large .big { font-size: 48px; }

/* Small fixes found on the shots. */
.send-row .btn.go { margin-left: auto; }
.ph { flex-wrap: wrap; }
.ph b { white-space: nowrap; }
/* On a phone a long line in a title bar ("sensor offline · last reading oct 28, 5:14 pm ET" on room
   air) wraps inside the bar instead of running off the panel's edge (found at the launch, 2026-10-28). */
@media (max-width: 560px) { .ph span { white-space: normal; min-width: 0; } }
.num .row { justify-content: flex-start; }
.num .row > span:first-child { flex: none; width: 22px; }
.num .row > span:last-child { text-align: left; }
.readings small { font-size: 16px; }
@media (max-width: 700px) { nav.links .wide { display: none; } }

/* The working prototype (2026-10-27): every made-up ask carries this mark; what the server said
   after a send; the heart while offline; a part taken off the site; a fake ask's doodle. */
.fake { display: inline-block; padding: 0 5px; border: 1px dashed var(--poor); color: var(--poor); line-height: 1.3; font-size: 13px; vertical-align: 1px; }
.mock .fake { font-size: inherit; }
.say { margin: 8px 0 0; padding: 4px 10px; border-left: 2px solid var(--tag); color: var(--title); white-space: pre-line; }
.fb-error { margin: 6px 0 0; color: var(--bad); }
.fb-count.over { color: var(--bad); }
.heart svg.px.off rect { fill: var(--mute); }
.st.off { border-style: dotted; }
.pic.doodle { background: #fff; }
.btn:disabled { opacity: .5; cursor: default; filter: none; }

/* The caption under the room air chart. */
.chart-cap { margin: 4px 0 0; color: var(--mute); font-size: 13px; }

/* The window for a sent drawing: replay, save as PNG or GIF (mine-window.js). */
.dlg { width: min(92vw, 720px); max-width: none; padding: 8px; border: 1px solid var(--line); background: var(--panel); color: var(--ink); font: inherit; }
.dlg::backdrop { background: rgba(0, 0, 0, .65); }
.dlg canvas { display: block; width: 100%; aspect-ratio: 240 / 135; image-rendering: pixelated; background: #000; border: 1px solid var(--line); }
.dlg .bar-row { display: flex; flex-wrap: wrap; gap: 6px 8px; align-items: center; margin-top: 8px; }
.dlg .bar-row > span { margin-right: auto; color: var(--mute); }
.dlg .say { margin: 6px 0 0; }
.thumbs .open { display: block; width: 100%; padding: 0; border: 0; background: none; cursor: pointer; color: inherit; font: inherit; }
.thumbs .tune-tile .open { display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 2px; aspect-ratio: 240 / 135; border: 1px solid var(--line); }
.thumbs .tune-tile .open:hover { border-color: var(--accent); }
.thumbs .tune-tile .mark { font-size: 2.2em; line-height: 1; color: var(--accent); }
.thumbs .tune-tile .len { color: var(--mute); }
.st:empty { display: none; }
/* A tile's tag sits on its own line above the time and wraps inside the tile: a long one ("waits for
   the next opening") ran into the tile beside it (reported 2026-11-03). */
.thumbs figcaption .st { display: table; margin-bottom: 3px; white-space: normal; }
.thumbs .open:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
