/* Palette and type from HL-SG-001: paper, ink, graphite, drafting blue, one orange per view. */
:root {
  --paper: #F7F5F0; --sheet: #FFFFFF; --ink: #16222E; --graphite: #4A5868;
  --blue: #2D5B8E; --orange: #E8590C;
  /* #E8590C is 3.29:1 on paper, which fails AA for the small mono labels that use it most.
     The accent keeps its colour for rules, fills and badges; text takes the darker one. */
  --orange-text: #B84400; --hair: #D8D3C8; --hair-2: #EDEAE2; --field: #B9C2CC;
  --sans: Archivo, "Helvetica Neue", Arial, sans-serif;
  --serif: "Source Serif 4", Georgia, serif;
  --mono: "IBM Plex Mono", ui-monospace, SFMono-Regular, Menlo, monospace;
}
* { box-sizing: border-box; }
.visually-hidden { position: absolute; width: 1px; height: 1px; margin: -1px; padding: 0;
  overflow: hidden; clip: rect(0 0 0 0); clip-path: inset(50%); white-space: nowrap; border: 0; }
[hidden] { display: none !important; } /* .btn sets display and would otherwise beat the attribute */
html, body { margin: 0; background: var(--paper); color: var(--ink); font-family: var(--serif); font-size: 16.5px; line-height: 1.6; }
a { color: var(--blue); text-decoration: none; border-bottom: 1px solid transparent; }
a:hover { color: var(--orange); border-bottom-color: var(--orange); }
h1, h2, h3, b { font-family: var(--sans); letter-spacing: -0.01em; }
.label, .status, .plate, .who, .rfoot, .eyebrow { font-family: var(--mono); font-size: 11px; letter-spacing: 0.12em; text-transform: uppercase; color: var(--graphite); }

/* Full height, so the composer sits at the bottom of the window rather than halfway up
   it while the thread is short. The thread takes the slack; everything else keeps its
   own height. Not applied inside the embed, where the frame's height is whatever the
   content measures and stretching to the viewport would inflate it. */
.sheet { max-width: 1100px; margin: 0 auto; padding: 0 24px 40px; }
/* Standalone, the sheet fills the window so the composer sits at the bottom of it rather
   than halfway up. Embedded, it must not: inside a frame 100vh is the frame's own height,
   so stretching to it makes the page as tall as the frame, the posted height comes back a
   few pixels larger for the padding, and the frame grows on every tick until it hits the
   parent's clamp. MEASURED 2026-09-07, and it filled the page. The embed hugs its content
   instead, and the parent sizes the frame to it, which puts the composer at the bottom
   because there is nothing under it. */
/* The app shell. One scrolling region, a composer that never moves, and a shell that is
   exactly as tall as the visible window. `dvh` follows the browser's own chrome, and the
   viewport meta asks the keyboard to resize the layout rather than cover it; the script
   handles iOS versions that ignore that. Page scrolling with a sticky composer was the
   arrangement that put the composer in the middle of a phone screen. */
html:not(.embed), html:not(.embed) body { height: var(--shell-h, 100dvh); overflow: hidden; }
html:not(.embed) .sheet { display: flex; flex-direction: column; height: var(--shell-h, 100dvh); padding-bottom: 0; }
html:not(.embed) .scroll {
  flex: 1 1 auto; min-height: 0; overflow-y: auto; overscroll-behavior: contain;
  -webkit-overflow-scrolling: touch;
}
html:not(.embed) .ask { flex: none; position: static; box-shadow: 0 -14px 20px -14px rgba(22, 34, 46, .22); }
html.embed .scroll { display: contents; }

/* `fill` is the embed given a box to fill rather than a page to grow in: the frame owns
   a dialog, so the sheet takes the frame's full height, the thread scrolls inside it and
   the composer rests on the bottom edge instead of floating up under a short thread.
   Percentages, not `vh`: inside a frame `vh` is the viewport, not the frame. */
html.fill, html.fill body { height: 100%; overflow: hidden; }
html.fill .sheet { display: flex; flex-direction: column; height: 100%; padding-bottom: 0; }
html.fill .trace { flex: 1 1 auto; min-height: 0; overflow-y: auto; overscroll-behavior: contain; }
html.fill .ask { flex: none; padding: 14px 0 max(14px, env(safe-area-inset-bottom)); background: var(--paper); }
/* Nothing has been asked yet, so the thread is one short block adrift at the top of a tall
   box with the composer far below it. Centred, the same emptiness reads as a starting
   point. It goes back to the top the moment there is a conversation to read. */
html.fill .trace:has(> .empty) { justify-content: center; }
html.fill .empty { padding-bottom: 4px; }
.head { display: flex; justify-content: space-between; align-items: baseline; padding: 18px 0 10px; border-bottom: 2px solid var(--ink); gap: 16px; }
.head .l, .head .r { display: flex; gap: 20px; align-items: baseline; }
.brand { font-family: var(--sans); font-weight: 800; font-size: 17px; color: var(--ink); border: 0; }
.plate { color: var(--ink); font-weight: 600; }

.hero { padding: 48px 0 20px; }
.eyebrow { color: var(--orange-text); margin: 0 0 14px; }
h1 { font-size: clamp(34px, 5vw, 60px); line-height: 1; margin: 0 0 16px; }
.lede { font-size: 20px; font-weight: 600; margin: 0; max-width: 34em; }

.btn { display: inline-block; font-family: var(--sans); font-weight: 600; font-size: 14px; padding: 11px 20px; cursor: pointer;
  background: var(--ink); color: var(--paper); border: 1px solid var(--ink); border-radius: 0; }
/* Guarded: a touch screen has no hover, but it fakes one on tap and leaves it stuck
   there. MEASURED 2026-09-08: the Ask button sat blue on a phone after the first tap. */
@media (hover: hover) {
  .btn:hover { background: var(--blue); border-color: var(--blue); color: var(--paper); }
}
.btn:disabled { opacity: .45; cursor: progress; }
.btn--ghost { background: transparent; color: var(--ink); }
@media (hover: hover) {
  .btn--ghost:hover { background: transparent; border-color: var(--orange); color: var(--orange); }
}
.btn--bare { background: none; border: 0; color: var(--blue); padding: 0; font-size: 13px; cursor: pointer; }
@media (hover: hover) { .btn--bare:hover { color: var(--orange); } }

/* The composer sits under the thread and stays put while the thread scrolls past it. */
.ask { padding: 10px 0; border-top: 1px solid var(--ink); position: sticky; bottom: 0;
  background: var(--paper); z-index: 3; box-shadow: 0 -14px 20px -14px rgba(22,34,46,.22); }
.ask form { display: grid; grid-template-columns: 46px minmax(0, 1fr) auto; gap: 10px; align-items: stretch; }
.ask input[type=text] { font-family: var(--serif); font-size: 17px; padding: 10px 14px; border: 1px solid var(--field); border-radius: 0; background: var(--sheet); color: var(--ink); min-width: 0; }
.ask input[type=text]:focus { border-color: var(--orange); }
:focus-visible { outline: 2px solid var(--blue); outline-offset: 2px; }
.mic { min-height: 44px; border: 1px solid var(--ink); background: var(--sheet); color: var(--ink); cursor: pointer; border-radius: 0; display: grid; place-items: center; }
.mic[aria-pressed="true"] { background: var(--orange); border-color: var(--orange); color: var(--paper); animation: pulse 1.4s ease-in-out infinite; }
.mic:disabled { opacity: .35; cursor: not-allowed; }
@keyframes pulse { 0%,100% { opacity: 1 } 50% { opacity: .55 } }
.undercomposer { display: flex; justify-content: space-between; align-items: center; gap: 16px; margin-top: 8px; flex-wrap: wrap; }
.status { margin: 0; min-height: 1.3em; }
.status.working::after { content: ""; display: inline-block; width: 5px; height: 5px; margin-left: 7px; border-radius: 50%; background: var(--orange); animation: pulse 1s ease-in-out infinite; vertical-align: middle; }
.opts { display: flex; gap: 18px; align-items: center; }
.openfull { border: 0; color: var(--blue); display: none; }
.embed .openfull { display: inline; }

.gate { margin: 16px 0; border: 1px solid var(--hair); border-left: 3px solid var(--orange); background: var(--sheet); padding: 16px 20px; }
.gate b { display: block; font-size: 18px; margin-bottom: 6px; }
.gate p { margin: 0 0 12px; color: var(--graphite); }

/* Oldest at the top, newest at the bottom, the way a conversation reads. */
.trace { margin: 8px 0 0; display: flex; flex-direction: column; gap: 16px; }
html:not(.embed) .trace { flex: 1 1 auto; }
.empty { padding: 12px 0 24px; }
.empty .emptylede { margin: 10px 0 20px; color: var(--graphite); max-width: 46em; }
.chips { display: flex; gap: 10px; flex-wrap: wrap; }
.chip { font-family: var(--serif); font-size: 14.5px; padding: 10px 14px; min-height: 44px; cursor: pointer; text-align: left;
  background: var(--sheet); color: var(--ink); border: 1px solid var(--hair); border-radius: 0; }
.chip:hover { border-color: var(--orange); color: var(--orange); }
.chip em { font-family: var(--mono); font-style: normal; font-size: 9.5px; letter-spacing: .1em; text-transform: uppercase; color: var(--orange-text); margin-left: 7px; }

.turn { border-top: 1px solid var(--hair); padding-top: 14px; }
.you { font-family: var(--sans); font-weight: 700; font-size: 18px; margin: 0 0 10px; }
.you .label { margin-right: 10px; color: var(--blue); }
.said { margin: 12px 0 0; font-size: 18px; line-height: 1.55; max-width: 46em; }
.said .label { display: block; margin-bottom: 5px; }
.said .md p { margin: 0 0 8px; }
.said .md p:last-child { margin-bottom: 0; }

/* Markdown, rendered rather than printed. The record keeps the shape a skill asked for. */
.md h4 { font-family: var(--sans); font-size: 15px; margin: 12px 0 6px; }
.md h4:first-child { margin-top: 0; }
.md ul, .md ol { margin: 6px 0 8px; padding-left: 20px; }
.md li { margin: 3px 0; }
.md code { font-family: var(--mono); font-size: .88em; background: var(--paper); border: 1px solid var(--hair); padding: 0 4px; }
.md pre { margin: 8px 0; font-family: var(--mono); font-size: 12px; line-height: 1.6; white-space: pre-wrap;
  word-break: break-word; background: var(--paper); border: 1px solid var(--hair); padding: 10px 12px; overflow-x: auto; }
.md pre code { background: none; border: 0; padding: 0; }
.md table { border-collapse: collapse; margin: 8px 0; font-size: 14px; display: block; overflow-x: auto; }
.md th, .md td { border: 1px solid var(--hair); padding: 5px 10px; text-align: left; vertical-align: top; }
.md th { font-family: var(--sans); font-size: 12px; background: var(--paper); }
.err { color: var(--orange-text); font-family: var(--mono); font-size: 12.5px; margin: 8px 0 0; }

/* The reasoning, while it is being written. Quieter than the answer on purpose: it is
   work in progress, and it folds away once the answer arrives. */
details.think { margin: 8px 0 0; border-left: 2px solid var(--field); padding: 2px 0 2px 12px; }
details.think summary { cursor: pointer; font-family: var(--mono); font-size: 10.5px; letter-spacing: .12em;
  text-transform: uppercase; color: var(--graphite); }
details.think summary:hover { color: var(--orange); }
details.think[open] summary { color: var(--orange-text); }
.thinktext { margin: 6px 0 2px; font-size: 14.5px; line-height: 1.55; color: var(--graphite); max-width: 46em; white-space: pre-wrap; }

/* What a skill requires an answer to close with. Kept
   in the shape the skill specifies rather than prettified into prose. */
.record { margin: 12px 0 0; border-left: 2px solid var(--blue); padding: 4px 0 4px 14px; }
.record .label { color: var(--blue); }
.record--unchecked { border-left-color: var(--orange); }
.record--unchecked > .label { color: var(--orange-text); }
.record .unchecked { margin: 6px 0 0; font-size: 13.5px; line-height: 1.5; color: var(--graphite); }
.record .unchecked .label { color: var(--orange-text); margin-right: 8px; }
.missing { margin: 10px 0 0; padding: 8px 12px; border-left: 2px solid var(--orange); background: var(--paper);
  font-size: 13.5px; line-height: 1.5; color: var(--graphite); }
.missing .label { color: var(--orange-text); margin-right: 8px; }
.record > pre { margin: 8px 0 0; font-family: var(--mono); font-size: 12px; line-height: 1.65;
  white-space: pre-wrap; word-break: break-word; color: var(--ink); background: var(--paper);
  border: 1px solid var(--hair); padding: 10px 12px; overflow-x: auto; max-height: 520px; }

.call { margin: 8px 0 0; border: 1px solid var(--ink); background: var(--sheet); }
.call .rhead { background: var(--ink); color: var(--paper); padding: 8px 14px; display: flex; gap: 12px; align-items: baseline; flex-wrap: wrap; }
.call .rhead .label { color: var(--orange); } /* on ink, where the lighter accent reads */
.call .rhead code { font-family: var(--mono); font-size: 12.5px; color: var(--paper); word-break: break-word; }
.call .rbody { padding: 12px 14px; }
.call .rbody > b { display: block; font-size: 16px; margin-bottom: 8px; }
.call .pending { color: var(--graphite); font-family: var(--mono); font-size: 11px; letter-spacing: .1em; }
.call .pending::after { content: ""; display: inline-block; width: 5px; height: 5px; margin-left: 7px; border-radius: 50%; background: var(--orange); animation: pulse 1s ease-in-out infinite; vertical-align: middle; }

.grid { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); border: 1px solid var(--hair); margin: 0 0 8px; }
.grid > div { padding: 8px 12px; border-right: 1px solid var(--hair-2); min-width: 0; }
.grid > div:last-child { border-right: 0; }
.grid b { display: block; font-size: 19px; font-variant-numeric: tabular-nums; overflow-wrap: anywhere; }
.grid .label { font-size: 9.5px; }

.refuse { border-left: 3px solid var(--orange); padding: 8px 12px; margin: 8px 0; background: var(--paper); }
.refuse .label { color: var(--orange-text); }
.refuse p { margin: 4px 0 0; font-size: 14.5px; color: var(--graphite); }
.rfoot { display: flex; gap: 16px; flex-wrap: wrap; padding: 8px 14px; background: var(--paper); border-top: 1px solid var(--hair); font-size: 9.5px; }
details.raw { margin: 8px 14px 12px; }
details.raw summary { cursor: pointer; font-family: var(--mono); font-size: 10.5px; letter-spacing: .1em; text-transform: uppercase; color: var(--blue); }
details.raw summary:hover { color: var(--orange); }
details.raw pre { margin: 8px 0 0; font-family: var(--mono); font-size: 11.5px; line-height: 1.5; background: var(--paper); border: 1px solid var(--hair); padding: 10px; overflow: auto; max-height: 320px; }
.note { font-size: 13.5px; color: var(--graphite); margin: 6px 0 0; }

.foot { margin-top: 24px; padding-top: 14px; border-top: 2px solid var(--ink); display: flex; justify-content: space-between; gap: 20px; flex-wrap: wrap;
  font-family: var(--mono); font-size: 10px; letter-spacing: .1em; color: var(--graphite); }

/* --- embedded in the site: no chrome, no page scroll of its own ------------------ */
.embed .head, .embed .hero, .embed .foot { display: none; }
.embed, .embed body, .embed .sheet { background: transparent; }
/* Gutters that grow with the box. A flat 16px inside a thousand-pixel dialog reads as a
   page pressed against its own frame, which is what made it feel airless. */
.embed .sheet { padding: 0 clamp(18px, 3.4vw, 44px) 8px; max-width: none; }
.embed .trace { min-height: 0; padding-top: clamp(14px, 2.2vw, 26px); gap: clamp(16px, 2vw, 24px); }
.embed .empty { padding: 4px 0 18px; }
.embed .ask { border-top: 1px solid var(--hair); position: static; box-shadow: none; }

@media (max-width: 640px) {
  .ask form { grid-template-columns: 46px 1fr; }
  .ask form #send { grid-column: 1 / -1; }
  .grid { grid-template-columns: 1fr 1fr; }
  .head { flex-direction: column; align-items: stretch; gap: 8px; }
}

/* The ask, under the composer, after an answer has landed. Not a banner: it appears
   once the reader has seen the thing work, which is the only moment it is a question
   they are already asking. */
.ownnote { margin: 14px 0 0; padding-top: 12px; border-top: 1px solid var(--hair);
  font-size: 14.5px; line-height: 1.6; color: var(--graphite); display: flex;
  flex-wrap: wrap; align-items: center; gap: 10px; }
.ownnote[hidden] { display: none; }
.ownnote .label { color: var(--orange-text); }
.btn--own { background: var(--orange); border-color: var(--orange); color: var(--ink);
  font-weight: 700; margin-left: auto; }
@media (hover: hover) {
  .btn--own:hover { background: var(--ink); border-color: var(--ink); color: var(--paper); }
}
@media (max-width: 640px) { .btn--own { margin-left: 0; width: 100%; text-align: center; } }

/* A record the client assembled is still a record, and is marked as one that the answer
   did not close with. Same block, different rule down the side. */
.record--assembled { border-left: 3px solid var(--blue); }

/* A record produced by the check this client ran after the answer. The verdict came from
   the world, so it is ruled in the accent rather than the blue of an assembled one. */
.record--verified { border-left: 3px solid var(--orange); }

/* The workings, folded. Quiet by default: a line of small type the eye can skip, which
   opens into the record, the verdicts and the receipts for anyone who wants them. */
.workings { margin: 10px 0 0; border-top: 1px solid var(--hair); padding-top: 8px; }
.workings > summary { cursor: pointer; font-family: var(--mono); font-size: 10.5px;
  letter-spacing: .1em; text-transform: uppercase; color: var(--graphite); list-style: none; }
.workings > summary::-webkit-details-marker { display: none; }
.workings > summary::before { content: "▸ "; color: var(--blue); }
.workings[open] > summary::before { content: "▾ "; }
.workings > summary:hover { color: var(--orange-text); }
.workings .record { margin-top: 10px; }

/* The exact call, inside a card whose header now reads as work rather than as an API. */
.callname { font-family: var(--sans); font-weight: 700; font-size: 15px; color: var(--paper); }
.exact { padding: 6px 14px 10px; background: var(--ink); }
.exact > summary { cursor: pointer; font-family: var(--mono); font-size: 9.5px;
  letter-spacing: .1em; color: var(--field); list-style: none; }
.exact > summary::-webkit-details-marker { display: none; }
.exact > summary::before { content: "▸ "; }
.exact[open] > summary::before { content: "▾ "; }
.exact code { display: block; margin-top: 6px; font-family: var(--mono); font-size: 11.5px;
  color: var(--paper); word-break: break-word; }

/* The steps inside the workings: a short numbered list of what was done, with the
   verdict beside the ones that returned one. */
.workings .steps { margin: 10px 0 0; padding-left: 20px; font-size: 14px; line-height: 1.65; color: var(--graphite); }
.workings .steps li { margin: 2px 0; }
.workings .steps b { font-family: var(--sans); font-weight: 700; color: var(--ink); }
.workings .stepreceipt { font-family: var(--mono); font-size: 10.5px; letter-spacing: .06em;
  text-transform: uppercase; color: var(--field); margin-left: 8px; }

/* More detail, inside the workings: the payloads, each behind its own line, under a
   sentence that says why anybody would open one. */
.workings .moredetails { margin: 14px 0 6px; font-size: 14px; line-height: 1.6; color: var(--graphite); }
.workings .moredetails .label { display: block; color: var(--orange-text); margin-bottom: 4px; }
.workings .payload { margin: 6px 0; border-top: 1px solid var(--hair-2); padding-top: 6px; }
.workings .payload > summary { cursor: pointer; font-family: var(--mono); font-size: 10.5px;
  letter-spacing: .08em; text-transform: uppercase; color: var(--blue); list-style: none; }
.workings .payload > summary::-webkit-details-marker { display: none; }
.workings .payload > summary::before { content: "▸ "; }
.workings .payload[open] > summary::before { content: "▾ "; }
.workings .payload .note { margin: 8px 0 6px; }
.workings .payload pre { margin: 0; font-family: var(--mono); font-size: 11.5px; line-height: 1.5;
  background: var(--paper); border: 1px solid var(--hair); padding: 10px; overflow: auto; max-height: 340px; }

/* --- the evidence rail ------------------------------------------------------------
   Beside the answer on a wide screen, over it on a narrow one. Either way the thread
   keeps its place: checking the work should not feel like leaving the conversation. */
.evidence { margin: 10px 0 0; display: flex; align-items: stretch; gap: 10px; flex-wrap: wrap; }
.evidence .evidencebtn { flex: 1 1 20em; }
.sharebtn {
  font-family: var(--mono); font-size: 10.5px; letter-spacing: .1em; text-transform: uppercase;
  background: transparent; border: 1px solid var(--field); color: var(--blue);
  padding: 8px 14px; min-height: 40px; cursor: pointer; white-space: nowrap;
}
@media (hover: hover) { .sharebtn:hover { border-color: var(--orange); color: var(--orange-text); } }
.sharebtn:focus-visible { outline: 2px solid var(--blue); outline-offset: 2px; }
@media (max-width: 640px) { .sharebtn { width: 100%; min-height: 46px; } }
.evidencebtn {
  font-family: var(--mono); font-size: 10.5px; letter-spacing: .1em; text-transform: uppercase;
  background: transparent; border: 0; border-top: 1px solid var(--hair); width: 100%;
  text-align: left; padding: 8px 0 0; color: var(--blue); cursor: pointer;
}
@media (hover: hover) { .evidencebtn:hover { color: var(--orange-text); } }
.evidencebtn:focus-visible { outline: 2px solid var(--blue); outline-offset: 2px; }

.rail {
  position: fixed; top: 0; right: 0; bottom: 0; width: min(460px, 92vw); z-index: 40;
  background: var(--sheet); border-left: 1px solid var(--ink); display: flex;
  flex-direction: column; box-shadow: -18px 0 40px -30px rgba(22, 34, 46, .6);
}
.rail[hidden] { display: none; }
.railhead { flex: none; display: flex; align-items: center; justify-content: space-between;
  gap: 12px; padding: 12px 16px; border-bottom: 1px solid var(--ink); background: var(--paper); }
.railhead .label { margin: 0; color: var(--orange-text); }
.closerail { font-family: var(--mono); font-size: 10.5px; letter-spacing: .1em; text-transform: uppercase;
  background: transparent; border: 1px solid var(--ink); color: var(--ink); min-height: 40px;
  padding: 0 12px; cursor: pointer; }
@media (hover: hover) { .closerail:hover { background: var(--ink); color: var(--paper); } }
.railq { flex: none; margin: 0; padding: 12px 16px 0; font-family: var(--sans); font-weight: 700;
  font-size: 15px; line-height: 1.35; }
.railbody { flex: 1 1 auto; min-height: 0; overflow-y: auto; padding: 12px 16px 24px; overscroll-behavior: contain; }
.railbody .workings { border: 0; padding: 0; }
.railbody .steps { padding-left: 18px; }
.railbody pre { max-height: none; }

/* Wide enough to sit beside the conversation: the sheet gives up the space rather than
   the rail covering the answer somebody is checking. */
@media (min-width: 900px) {
  html.rail-open .sheet { padding-right: calc(min(460px, 92vw) + 24px); }
}

/* The share control, at the top of the rail: somebody who opened the evidence is the
   person most likely to want to send it. */
.sharerow { display: flex; align-items: center; gap: 14px; flex-wrap: wrap;
  margin: 0 0 14px; padding-bottom: 12px; border-bottom: 1px solid var(--hair); }
.sharerow .openshare { font-family: var(--mono); font-size: 10.5px; letter-spacing: .1em;
  text-transform: uppercase; color: var(--blue); border: 0; }
@media (hover: hover) { .sharerow .openshare:hover { color: var(--orange-text); } }

/* --- the phone ---------------------------------------------------------------------
   MEASURED 2026-09-08 on a phone: the hero took the whole first screen before anything
   could be asked, the sticky composer sat on top of the line that opens the evidence,
   and that line was a two-line run of small mono type with no target to hit. */
@media (max-width: 640px) {
  /* The hero introduces; it does not need a screen to do it. */
  .hero { padding: 20px 0 12px; }
  h1 { font-size: 30px; margin: 0 0 10px; }
  .lede { font-size: 16.5px; font-weight: 600; line-height: 1.5; }

  /* The composer is the bottom row of the shell; it needs the home indicator's room. */
  html:not(.embed) .ask { padding-bottom: max(10px, env(safe-area-inset-bottom)); }

  /* The line that opens the evidence is the second most important control on the page,
     so it gets a target rather than a text link squeezed under a rule. */
  .evidencebtn {
    border: 1px solid var(--field); border-top: 1px solid var(--field);
    padding: 12px 14px; min-height: 46px; background: var(--sheet);
    line-height: 1.4; white-space: normal;
  }

  /* The rail takes the screen, with room for the notch and the home indicator. */
  .rail { width: 100%; border-left: 0; }
  .railhead { padding-top: max(12px, env(safe-area-inset-top)); }
  .railbody { padding-bottom: max(24px, env(safe-area-inset-bottom)); }

  /* Four columns of figures is two columns of figures on a phone. */
  .grid { grid-template-columns: 1fr 1fr; }
  .grid b { font-size: 17px; }

  /* The step header wraps rather than pushing the card sideways. */
  .call .rhead { gap: 6px; }
  .callname { font-size: 14.5px; }
}

/* A short phone in landscape has no room for a hero at all once the keyboard is up. */
@media (max-height: 520px) and (max-width: 900px) {
  .hero { padding: 12px 0 8px; }
  .hero .lede { display: none; }
}

/* --- still working -----------------------------------------------------------------
   The phase, said inside the turn rather than only in the ten-pixel status line at the
   bottom of the screen. On Pro a turn runs thirteen to thirty-five seconds, and after
   the first world card lands the thread looks finished. This sits at the end of the
   turn, where the answer is about to appear, until the answer replaces it. */
.pulse {
  display: flex; align-items: center; gap: 12px;
  margin: 14px 0 4px; padding: 12px 0;
  font-family: var(--mono); font-size: 11px; letter-spacing: .1em;
  text-transform: uppercase; color: var(--orange-text);
  border-top: 1px solid var(--hair);
}
.pulse .dots { display: inline-flex; gap: 5px; flex: none; }
.pulse .dots i {
  width: 6px; height: 6px; border-radius: 50%; background: var(--orange);
  animation: pulsedot 1.1s ease-in-out infinite;
}
.pulse .dots i:nth-child(2) { animation-delay: .18s; }
.pulse .dots i:nth-child(3) { animation-delay: .36s; }
.pulse .phase { flex: 1 1 auto; min-width: 0; }
/* The elapsed count reads as progress rather than as a hang. Empty under five seconds. */
.pulse .secs { flex: none; color: var(--graphite); font-variant-numeric: tabular-nums; }
.pulse .secs:empty { display: none; }

@keyframes pulsedot {
  0%, 100% { opacity: .22; transform: translateY(0); }
  50%      { opacity: 1;   transform: translateY(-3px); }
}
/* Motion is the signal, so without it the signal has to be the colour staying on. */
@media (prefers-reduced-motion: reduce) {
  .pulse .dots i { animation: none; opacity: 1; }
}

/* --- the orientation, said out loud --------------------------------------------------
   Loading the skill and asking the world how to use itself is what makes the rest
   trustworthy, and it used to be folded away with the checkers. Quieter than a numbered
   step, because it is not an answer from the world; visible, because it is the reason
   the answer can be believed. */
.using {
  margin: 10px 0; padding-left: 12px; border-left: 2px solid var(--hair);
  font-size: 14px; line-height: 1.55; color: var(--graphite);
}
.using .label { display: block; color: var(--blue); margin-bottom: 2px; }

/* --- ask something else --------------------------------------------------------------
   The samples were an empty state and disappeared on the first question, so the only
   way back to them was a reload. They now live at the end of the thread. */
.again { margin: var(--s4, 28px) 0 8px; padding-top: 16px; border-top: 1px solid var(--hair); }
.again > .label { display: block; margin-bottom: 10px; color: var(--graphite); }

/* --- a figure that came from nowhere --------------------------------------------------
   The client audits every number in the answer against the payloads the turn received.
   Anything the world did not serve, and no checker returned entailed, is named here at
   the top of the answer rather than left for the reader to catch. */
.unserved {
  margin: 0 0 14px; padding: 12px 14px;
  border: 1px solid var(--orange); border-left-width: 3px;
  background: var(--sheet); font-size: 14.5px; line-height: 1.55;
}
.unserved .label { display: block; color: var(--orange-text); margin-bottom: 4px; }

/* --- what the checker thought -------------------------------------------------------
   The verdicts used to live only in the workings, one fold down, which is not where
   anybody reads an answer. A refused, unreadable or not_entailed verdict on a sentence
   the answer rests on belongs beside the answer. */
.unchecked-warn {
  margin: 0 0 14px; padding: 12px 14px;
  border: 1px solid var(--hair); border-left: 3px solid var(--blue);
  background: var(--sheet); font-size: 14.5px; line-height: 1.55;
}
.unchecked-warn .label { display: block; color: var(--blue); margin-bottom: 4px; }

/* --- what the world returned ---------------------------------------------------------
   Shown when nothing the answer rests on was licensed. Deciding in code whether prose
   agrees with a verdict is the wordlist trap; putting the verdict next to the answer is
   not, and a reader spots a contradiction no pattern of ours would catch. */
.servedverdict {
  margin: 14px 0 0; padding: 12px 14px;
  border: 1px solid var(--hair); border-left: 3px solid var(--orange);
  background: var(--sheet); font-size: 14.5px; line-height: 1.55;
}
.servedverdict .label { display: block; color: var(--orange-text); margin-bottom: 6px; }
.servedverdict p { margin: 0 0 6px; }
.servedverdict b { font-family: var(--mono); font-size: 13px; }
.servedverdict .vhint { margin: 8px 0 0; color: var(--graphite); font-size: 13.5px; }

/* --- a goal, not a question ----------------------------------------------------------
   The demo's first ask should look like work rather than a lookup: these two chips carry
   a job somebody is actually paid to do, and they read wider than the code questions
   because a goal is a sentence and a code question is four words. */
.chip--goal {
  border-color: var(--ink);
  background: var(--sheet);
  font-weight: 600;
}
.chip--goal em {
  font-style: normal;
  color: var(--orange-text);
  font-family: var(--mono);
  font-size: 10px;
  letter-spacing: .1em;
  text-transform: uppercase;
  margin-left: 8px;
}

/* --- the chart -----------------------------------------------------------------------
   Inline SVG, drawn from figures the world served. Bars start at zero and there is no
   axis break: a chart that does not start at zero is a way of making a small difference
   look large, which on this page would be the same failure as an unserved figure. */
.chart { margin: 0 0 18px; padding: 0; }
.chart figcaption { display: block; color: var(--graphite); margin-bottom: 10px; }
.chart svg { width: 100%; height: auto; overflow: visible; }
.chart .clabel { font-family: var(--mono); font-size: 12px; fill: var(--ink); }
.chart .cval { font-family: var(--mono); font-size: 12px; fill: var(--graphite); }
.chart .cbar { fill: var(--orange); }
@media (max-width: 600px) { .chart .clabel, .chart .cval { font-size: 11px; } }

/* The agent's own note under a chart, and the figures the audit would not let it draw. */
.chart .cnote { margin: 10px 0 0; font-size: 14px; line-height: 1.55; color: var(--graphite); }
.chart .cdropped { margin: 6px 0 0; font-size: 13.5px; color: var(--orange-text); }
