/* Sess public pages: one design system for sess.si and docs.sess.si.
   System fonts only; no remote assets. Light and dark themes: the default follows
   prefers-color-scheme without JavaScript; site.js may set html[data-theme] from a stored choice.
   Every text/background pair meets WCAG 2.2 AA in both themes. No animation, except the landing
   hero device's one bounded run (design language §7 exception; assets/hero.js and "The hero
   device" below). */

/* ------------------------------------------------------------------ tokens */

/* The Sess token roles (packages/design-tokens src/roles.ts, D-L4) are not declared here: every
   page loads the shared sheet assets/sess.css first (design-tokens SITE_CHROME_CSS: the roles on
   :root in the light, system-dark and chosen-dark blocks, then the shared header). This sheet
   declares only its own properties: layout widths and the colours no role covers yet (the draft
   and planned cue and the PUT/PATCH badge). */

:root {
  /* Site only: layout */
  --header-h: 3.5rem;
  /* §5: 44rem, and never more than 68 characters of the text that uses it. */
  --measure: min(44rem, 68ch);
  --site-max: 72rem;
  --docs-max: 90rem;

  /* Site only: light colours */
  --draft-bg: #fff7e2;
  --draft-line: #c99a1b;
  --draft-ink: #5c4000;
  --put-bg: #fff3e1;
  --put-ink: #774100;

  /* The landing's display ink (founder 2026-10-24 21:45Z): the hero's headline and its line
     beneath, and every chapter headline, in the body's ink: #1d1d1f in light, never #000, and
     #f5f5f7 in dark (the --text role in each theme). */
  --display-ink: var(--text);

  /* The landing's device frames, per theme (founder 2026-10-24 21:40Z): the bezel's body and the
     rim drawn around it by .demo-phone and .demo-tablet; dark keeps today's values exactly. Light
     (founder 2026-10-29 item 5: "match the dark bezel's contrast against its background; one
     value, applied to the phone and the tablet"): one neutral grey, body and rim alike as dark's
     are, #e8e8ed (the light control fill's value), 1.18:1 against the light canvas #fbfbfd the
     chapters' frames sit on, as dark's #1d1d1f is 1.17:1 against the dark canvas #0b0b0c
     (landing-rhythm.test.ts). One accepted exception: the hero phone at 1280 px and wider sits on
     the white surface, light contrast 1.221 against dark's 1.074, a 0.147 difference (accepted
     by the founder 2026-10-29 03:33Z). */
  --frame-body: #e8e8ed;
  --frame-rim: #e8e8ed;
}

/* Dark theme: by system preference unless the reader chose light, or by explicit choice. */
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    --draft-bg: #2a2310;
    --draft-line: #a68629;
    --draft-ink: #f2d892;
    --put-bg: #2f2511;
    --put-ink: #f1c477;
    --frame-body: #1d1d1f;
    --frame-rim: #1d1d1f;
  }
}

:root[data-theme="dark"] {
  --draft-bg: #2a2310;
  --draft-line: #a68629;
  --draft-ink: #f2d892;
  --put-bg: #2f2511;
  --put-ink: #f1c477;
  --frame-body: #1d1d1f;
  --frame-rim: #1d1d1f;
}

/* ------------------------------------------------------------------ base */

*,
*::before,
*::after {
  box-sizing: border-box;
}

html {
  -webkit-text-size-adjust: 100%;
  text-size-adjust: 100%;
  background: var(--surface);
}

body {
  margin: 0;
  font-family: var(--font);
  font-size: var(--type-base);
  line-height: 1.65;
  color: var(--text);
  background: var(--surface);
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
  /* A long unbroken word (an identifier in prose) wraps instead of widening the page. */
  overflow-wrap: break-word;
  /* Design language v1.1 §5 Measure (founder amendment, #385): body and prose avoid a lone last
     word; headings and leads balance their lines (below). */
  text-wrap: pretty;
}

h1,
h2,
h3,
h4,
.lede,
.section-lede {
  text-wrap: balance;
}

/* §5 Weights: a heading is never the browser's bold (700); an h1 with no weight of its own
   (/feedback's) and a stage's headline (also inside the docs prose) are at the heading weight. */
h1,
.stage .stage-title {
  font-weight: var(--weight-heading);
}

a {
  color: var(--accent);
  text-decoration-thickness: 1px;
  text-underline-offset: 0.2em;
}

a:hover {
  text-decoration-thickness: 2px;
}

:focus-visible {
  outline: 2px solid var(--focus);
  outline-offset: 2px;
  border-radius: 3px;
}

main:focus {
  outline: none;
}

/* Anchored targets clear the sticky header. */
[id] {
  scroll-margin-top: calc(var(--header-h) + var(--space-8));
}

.visually-hidden {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
  border: 0;
}

.sprite {
  position: absolute;
  width: 0;
  height: 0;
  overflow: hidden;
}

.skip-link {
  position: absolute;
  left: var(--space-6);
  top: -10rem;
  z-index: 50;
  padding: var(--space-4) var(--space-8);
  background: var(--action);
  color: var(--on-action);
  border-radius: var(--radius-sm);
}

.skip-link:focus {
  top: var(--space-6);
}

code,
pre,
kbd {
  font-family: var(--mono);
}

:not(pre) > code {
  padding: 0.1em 0.35em;
  font-size: 0.875em;
  background: var(--surface-2);
  border: 1px solid var(--border);
  border-radius: 5px;
  overflow-wrap: break-word;
}

/* Short tokens in tables stay on one line (the table region scrolls if it must). */
td code {
  white-space: nowrap;
}

[hidden] {
  display: none;
}

/* ------------------------------------------------------------------ header */

/* The header is the shared Sess header (packages/design-tokens src/header.ts, founder 2026-10-18
   06:55Z): its bar, lockup, links and narrow-screen rules come from assets/sess.css, the same
   rules the console inlines. Only the site's own items are styled here. */

/* The OUTLINE master's large uses (founder 2026-10-20 17:53Z): its lines are about 7 units of its
   1254 grid, about 0.84 px at the footer's 108 px, so the same path is thickened by a non-scaling
   stroke in currentColor with round joins to a visible line of about 1.5 px: 1.5 - 0.84 = 0.66 px
   (design-tokens OUTLINE_STROKE.footer; tested to agree). The email lockup's oracle
   (scripts/email-lockup.ts) reads this rule. The FILLED mark (header) is never
   stroked (sess.css svg.brand-mark). */
.footer-logo {
  stroke: currentColor;
  stroke-width: 0.66px;
  stroke-linejoin: round;
}

.primary-nav .nav-search {
  margin-left: auto;
}

.search-link {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  padding: 0.3rem 0.75rem;
  border: 1px solid var(--border);
  border-radius: 999px;
  min-width: 9rem;
}

/* With "Use cases" in the row (roadmap 1.26) the full row needs about 1193 px in the system font
   on Apple devices, 9 px more than the 74rem (1184 px) breakpoint. Just above the breakpoint the
   Search pill keeps its content width instead of its 9rem minimum, so the row stays one line from
   1184 px without moving the breakpoint; from 76rem (1216 px) it is unchanged. */
@media (min-width: 74rem) and (max-width: 75.99rem) {
  .search-link {
    min-width: 0;
  }
}

.icon {
  width: 0.875rem;
  height: 0.875rem;
}

.primary-nav a.button-primary {
  color: var(--on-action);
}

/* The mobile header's search button and Menu (below 74rem only; see "small screens"). */
.mobile-search,
.mobile-menu {
  display: none;
}

/* "Sign in": a text link beside the primary button (founder 2026-10-18). */
.primary-nav .nav-signin a {
  color: var(--text);
}

.theme-toggle {
  position: relative;
  min-width: 4.25rem;
  padding: 0.3rem 0.7rem;
  border: 1px solid var(--border);
  border-radius: 999px;
  background: var(--surface);
  color: var(--muted);
  font: inherit;
  font-size: var(--type-sm);
  cursor: pointer;
}

.theme-toggle:hover {
  color: var(--text);
}

/* ------------------------------------------------------------------ buttons and badges */

.button {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  padding: 0.45rem 0.95rem;
  border: 1px solid transparent;
  border-radius: var(--radius);
  /* A <button class="button"> takes the page's face, not the browser's button face (§5). */
  font: inherit;
  font-size: var(--type-sm);
  font-weight: 600;
  line-height: 1.4;
  text-decoration: none;
}

/* The buttons of the Design Language v1.1 (DOCS/design/language.md §4 and §8), as the token
   sheets draw them (packages/design-tokens src/action-button.ts): the primary is Sess Blue, flat
   (no gradient, no inner highlight, no shadow), with its hover and pressed fills; the secondary is
   a control-fill fill (the founder's amendment) with a text label and no border, the same in every
   state. The focus ring is the shared :focus-visible rule above. */
.button-primary {
  background: var(--action);
  border-color: var(--action);
  color: var(--on-action);
}

.button-primary:hover {
  background: var(--action-hover);
  border-color: var(--action-hover);
}

.button-primary:active {
  background: var(--action-pressed);
  border-color: var(--action-pressed);
}

.button-secondary,
.button-secondary:hover,
.button-secondary:active {
  background: var(--control-fill);
  color: var(--text);
  border-color: var(--control-fill);
}

.button-lg {
  padding: 0.7rem 1.3rem;
  font-size: var(--type-base);
}

/* §8 Button and §11: the header's theme pill and its primary keep their look and the 56 px
   header, inside a 44 px pointer target (as the account button, header.ts): a box 44 px tall,
   centred on the control and as wide as it, covering nothing else of the row. */
.primary-nav .button {
  position: relative;
}

.theme-toggle::before,
.primary-nav .button::before {
  content: "";
  position: absolute;
  inset: calc(50% - var(--control-height) / 2) 0;
}

.draft-badge,
.planned-badge {
  display: inline-block;
  padding: 0 0.45em;
  border: 1px solid var(--draft-line);
  border-radius: 5px;
  background: var(--draft-bg);
  color: var(--draft-ink);
  font-size: var(--type-xs);
  font-weight: 600;
  line-height: 1.6;
  white-space: normal;
}

.draft {
  margin: var(--space-12) 0;
  padding: var(--space-8) var(--space-8) var(--space-8) var(--space-12);
  border: 1px solid var(--border);
  border-left: 3px solid var(--draft-line);
  border-radius: var(--radius-sm);
  background: var(--surface-2);
}

.draft > :last-child {
  margin-bottom: 0;
}

.draft .draft-label {
  margin-top: 0;
  color: var(--draft-ink);
}

.callout {
  margin: var(--space-12) 0;
  padding: var(--space-8) var(--space-12);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: var(--surface-2);
}

.callout > :first-child {
  margin-top: 0;
}

.callout > :last-child {
  margin-bottom: 0;
}

/* ------------------------------------------------------------------ footer */

/* The footer (design language §8 Footer, founder 2026-10-19 20:21Z-20:37Z; landing spec
   DOCS/design/landing/), on the site and the docs alike: muted, small, generous top space; the
   lockup and the four link blocks under one top hairline. No fine print (the "Sess is in
   preview…" line was removed by the founder 2026-10-26 00:10Z; Terms states the no-SLA position).
   - From 60rem: one row of five columns (the lockup's 1.2fr, then four 1fr), 32 px apart. The
     lockup is stacked and centred in its column: the wordmark 108 px wide (the visible width of the
     1.9rem wordmark with its .34em tracking on the system font) and above it the mark, the header's
     own SVG drawn as a square exactly as wide (108 px), so its stroke and bar keep the header
     mark's proportions; 18 px between them.
   - Below 60rem: the link blocks in two columns, then under a hairline the lockup inline and
     centred, the mark as tall as the wordmark (108 px x 12/91, about 14.24 px; founder 2026-10-20
     ~02:50Z, decision 3) 12 px before it. The DOM order is the same at both widths (the lockup first):
     placement is CSS order only. */
.site-footer {
  margin-top: var(--space-48);
  border-top: 1px solid var(--border);
  padding: 64px var(--space-12) 40px;
  font-size: var(--type-md);
}

.footer-inner {
  display: grid;
  grid-template-columns: minmax(0, 1.2fr) repeat(4, minmax(0, 1fr));
  align-items: start;
  gap: 32px;
  max-width: var(--site-max);
  margin: 0 auto;
}

/* The columns sit directly in the row on wide screens. */
.footer-grid {
  display: contents;
}

.footer-brand {
  min-width: 0;
  color: var(--text);
}

/* At every width (founder 2026-10-21 02:14Z item 7): the email lockup's drawing (scripts/
   email-lockup.ts: the mark 101 px, 12 px, its letters 101 px wide) at the footer's 108 px: the
   OUTLINE master's mark over its own SESS letters, both crops 108 px wide on one centre line,
   108 x 12 / 101 px apart, in the full text colour, thickened by the .footer-logo stroke. The
   mark is 108 px at 390 px too, above the size rule's 48 px, so the phone shows the same stacked
   lockup. Centred in its column on the nearest whole pixel so the drawing stays sharp. */
.footer-brand .footer-lockup {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: calc(108px * 12 / 101);
  width: 108px;
  margin: 0 0 0 round(nearest, calc((100% - 108px) / 2), 1px);
}

.footer-lockup svg.footer-logo {
  flex: none;
  width: 108px;
  height: 108px;
}

.footer-lockup svg.footer-word {
  height: calc(108px * 152 / 958);
}

/* The final small line under the stacked logo (founder 2026-10-31 00:18Z and 00:20Z): plain text
   "© {build year} Sess", no mark or icon beside it, in the muted role at caption size (the
   console footer's own: var(--muted), var(--type-xs)), centred on the lockup's own 108 px centre
   line (a flex row, so a wider line at large text overflows both sides evenly). */
.footer-brand .footer-legal {
  display: flex;
  justify-content: center;
  width: 108px;
  margin: 16px 0 0 round(nearest, calc((100% - 108px) / 2), 1px);
  color: var(--muted);
  font-size: var(--type-xs);
  white-space: nowrap;
}

.footer-grid h2 {
  margin: 0 0 10px;
  font-size: var(--type-md);
  font-weight: 600;
  color: var(--text);
}

.footer-grid ul {
  margin: 0;
  padding: 0;
  list-style: none;
}

.footer-grid li {
  margin: 6px 0;
  color: var(--text-2);
}

/* In the footer a draft is a quiet note, not a highlighted block. */
.footer-grid .draft-badge {
  display: block;
  margin-top: 0.1rem;
  padding: 0;
  border: 0;
  background: none;
  color: var(--muted);
  font-size: 0.6875rem;
  font-weight: 500;
  line-height: 1.4;
}

/* The sidebar's "API key" cue on guides that need one (draft until accounts ship). */
.nav-note {
  margin-left: 0.35rem;
  padding: 0 0.35rem;
  border: 1px solid var(--control);
  border-radius: 999px;
  color: var(--muted);
  font-size: 0.6875rem;
  font-weight: 500;
  white-space: nowrap;
}

.footer-grid a {
  color: var(--text-2);
  text-decoration: none;
}

.footer-grid a:hover {
  color: var(--text);
  text-decoration: underline;
}

@media (max-width: 59.99rem) {
  .footer-inner {
    grid-template-columns: minmax(0, 1fr);
    gap: 24px;
  }

  .footer-grid {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 32px;
  }

  .footer-inner .footer-brand {
    order: 2;
    padding-top: 24px;
    border-top: 1px solid var(--border);
  }
}

/* ------------------------------------------------------------------ product page */

/* The page grid (design language §9a; founder 2026-10-18 ~22:35Z layout pass): one content width,
   72rem, centred, with the size class's gutter on both sides (16, 24, 32 and 40 px), shared by the
   header, every section and the footer, so their edges line up. Sections are 96 px apart from
   medium up and 64 px on compact screens (§6): each section's padding is half of that. Declared on
   html (the token roles' :root block stays the only one, design-tokens surfaces test). */
html {
  --gutter: 1rem;
  --section-space: var(--space-16);
}

@media (min-width: 37.5rem) {
  html {
    --gutter: 1.5rem;
    --section-space: var(--space-24);
  }
}

@media (min-width: 64rem) {
  html {
    --gutter: 2rem;
  }
}

@media (min-width: 90rem) {
  html {
    --gutter: 2.5rem;
  }
}

.site-main {
  display: block;
  /* Nothing in the product page scrolls it sideways; with large text, anything wider than the
     viewport is clipped at its edge rather than scrolling the page. */
  overflow-x: clip;
}

/* The page as a column (founder 2026-11-03 00:58Z, addendum 01:17Z: "The footer rule is
   site-wide, set in the shared public page shell, not per page"; it began on /verify's desktop,
   founder 2026-10-23 16:15Z). On every public page, the site's and the docs', at every width, the
   main area grows to fill the viewport and the footer sits at its bottom, so /try, its run and
   result pages, /verify and the 404 keep the footer in the same place. The column has a minimum
   height only, so a page taller than the viewport is laid out as before. Static: the column is
   laid out before first paint, and every short page's first paint waits for its whole footer
   (layout.ts waitsForFooter and renderBlocking, FOOTER_END_ID): a footer at the viewport's bottom
   painted half-parsed would grow upwards as the rest arrived. So nothing shifts on load. Screens
   only: a printed page is not a viewport. */
@media screen {
  body:has(> .site-main),
  body:has(> .docs-layout) {
    display: flex;
    flex-direction: column;
    min-height: 100vh;
    /* biome-ignore lint/suspicious/noDuplicateProperties: 100vh is the fallback where dvh is unknown. */
    min-height: 100dvh;
  }

  body > .site-main,
  body > .docs-layout {
    flex: 1 0 auto;
  }

  /* The docs layout is centred by auto margins, which in a column would shrink it to its
     content: it keeps the full width up to its cap, as in normal flow. */
  body > .docs-layout {
    /* biome-ignore-start lint/suspicious/noDuplicateProperties: each engine takes the one it knows. */
    width: -webkit-fill-available;
    width: -moz-available;
    width: stretch;
    /* biome-ignore-end lint/suspicious/noDuplicateProperties: each engine takes the one it knows. */
  }
}

.section {
  max-width: calc(var(--site-max) + 2 * var(--gutter));
  margin: 0 auto;
  padding: var(--section-space) var(--gutter);
}

/* A full-width tinted band whose content lines up with the other sections. */
.band {
  max-width: none;
  padding-inline: max(var(--gutter), calc((100% - var(--site-max)) / 2));
  background: var(--canvas);
  border-block: 1px solid var(--border);
}

/* The site's header and footer on the same grid as the sections (the shared header keeps its own
   wider bar on the docs). */
.app-site .site-header > .bar {
  max-width: calc(var(--site-max) + 2 * var(--gutter));
  padding-inline: var(--gutter);
}

.app-site .site-footer {
  margin-top: var(--section-space);
  padding-inline: var(--gutter);
}

/* The hero (landing spec DOCS/design/landing/; design language §9 Landing hero, founder approved
   2026-10-19 20:20Z): the copy and the device as one composition.
   - Compact: one column, the copy, then the device block centred under it.
   - From 60em of the page's width (960 px at the default text size, and proportionally wider with
     enlarged text, so text at 200% gets the one-column hero where every line wraps: a container
     query in em, no script measuring fonts): two columns on the page grid, the copy
     minmax(0, 1fr) and the device 372 px, 56 px apart, both centred vertically. The copy carries,
     under its last line, as much space as the controls take under the phone (16 + 44 + 12 + 44 px,
     from the same tokens), so its centre is the phone body's centre.
   The header-to-hero space is the spec's: 40 px below 60rem, 48 px from it (founder 2026-10-20
   ~02:50Z, decision 3); the hero-to-section space is the sections' own. */
.hero {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  align-items: start;
  row-gap: var(--space-24);
  padding-top: var(--space-20);
  padding-bottom: var(--section-space);
}

.hero-copy {
  min-width: 0;
  max-width: 42rem;
}

@media (min-width: 60rem) {
  .hero {
    padding-top: var(--space-24);
  }
}

.site-main:has(> .hero) {
  container: landing / inline-size;
}

@container landing (min-width: 60em) {
  .hero {
    --hero-controls-height: calc(var(--space-8) + 2.75rem + var(--space-6) + var(--control-height));
    grid-template-columns: minmax(0, 1fr) 372px;
    column-gap: 56px;
    align-items: center;
  }

  .hero-copy {
    padding-bottom: var(--hero-controls-height);
  }
}

/* The hero device (founder 2026-10-17 16:53Z and ~17:08Z; the real flow, 2026-10-18 ~22:45Z): one
   shared site component (scripts/hero.ts heroDevice). The Your receipts spec's phone (founder
   2026-10-19 ~11:40 Pacific; DOCS/design/your-receipts "Exact values"), one frame in both themes,
   with the mockups' status bar, shows the /try journey's three real
   pages, rendered at build time by the runtime's own renderer and styled by the human page's own
   sheet, scoped under .hero-page (assets/hero.css): question 1, question 2 and the completed page.
   Nothing in the screen is drawn here except the phone's own chrome (the run's tap indicator and
   the select picker, assets/hero.js) and the status bar; nothing at the bottom edge (no home
   indicator: the mockups draw none, founder 2026-10-19 ~12:15 Pacific).

   One viewport: the screen is an iPhone 16's, 393:852. Each page is laid out in a real phone
   viewport 390 CSS px wide at the page's own root size, below the 44 px status bar
   (.hero-viewport, 390 px wide and as tall as the 393:852 screen at that width), and the viewport
   is scaled to the screen as a whole (--hero-scale), so every frame has the real page's widths and
   padding at that viewport. The frames leave the human page's "Powered by Sess" footer out (real
   pages keep it) and the device has no caption under it (founder 2026-10-20 ~02:50Z, decision 1):
   the controls follow the phone.

   Each frame scrolls its page: natively on touch screens and under reduced motion (the platform's
   own momentum; it chains to the page at its ends); with a fine pointer, assets/hero.js scrolls it
   under the wheel with momentum and a rubber band (no mouse drag). The frames are aria-hidden,
   each page is inert, the scrollers are never tab stops, and the device has one text
   alternative. The device is not a link: "Try it" under it is the one control, and a completed
   mouse click on the screen follows it (founder 2026-10-21 04:57Z).

   Under the device, the step tabs (one radio group: Ask, Answer, Receipt) choose the frame shown,
   with a 280 ms crossfade (design language §7), and Play/Pause controls the run (assets/hero.js:
   once on load, about 12 s, never looping; the §7 hero device exception). Without the script the
   tabs still switch the frames. Under reduced motion the device shows stills only. */
/* One phone frame on the whole landing (founder 2026-10-24 20:25Z: every phone frame shares one
   rendered width and bezel, matched to chapter 2's): the hero's device and every chapter's phone
   (.chapter-device: The exchange, Your receipts below 960 px) take their screen scale from this one
   rule, and their bezel from the one .demo-phone. The tablet keeps its own frame (.demo-tablet).
   - the screen: the 390 px viewport at this scale: 0.76 stacked, 0.70 on the smallest phones, and
     from the landing's 60em the 372 px column, (372 - 2 x 7) / 390, inside the phone's 7 px bezel
     (6 px padding, 1 px border);
   - the viewport's height: the 393:852 screen at the viewport's 390 px width;
   - the status bar's height, in the viewport's px. */
.hero-demo,
.chapter-device {
  --hero-scale: 0.76;
  --hero-viewport-height: calc(390px * 852 / 393);
  --hero-status-bar: 44px;
}

@media (max-width: 23.74rem) {
  .hero-demo,
  .chapter-device {
    --hero-scale: 0.7;
  }
}

@container landing (min-width: 60em) {
  .hero-demo,
  .chapter-device {
    --hero-scale: 0.9179;
  }
}

.hero-demo {
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-self: center;
  /* As wide as the device, or as its controls where they need more (the device centred over). */
  min-width: 0;
}

/* The device is exactly as wide as the phone: the screen (390 px at --hero-scale) inside 6 px of
   padding and the 1 px border, in both themes (founder 2026-10-21 01:30Z, item 1: the light
   rim's extra 0.5 px is an inset ring inside the border, so it takes no layout). The screen is
   the same size in both themes and every browser. */
.demo-device {
  position: relative;
  width: max-content;
}

/* A mouse over the screen (founder 2026-10-21 04:57Z, amending the 2026-10-20 ~02:50Z decision 1):
   assets/hero.js marks the device clickable, and a completed click there follows "Try it". The
   screen shows the pointer cursor and a small stationary cue, the signed "Try it" with an arrow
   (the screen's data-hero-cue), at its bottom centre. The cue is drawn inside the aria-hidden
   device, takes no pointer and no layout, and appears and goes at once (no transition, no
   animation). No drag, no grab cursor; the bezel keeps the default cursor. */
.demo-device.hero-clickable .demo-screen {
  cursor: pointer;
}

.demo-device.hero-clickable .demo-screen::after {
  content: attr(data-hero-cue);
  position: absolute;
  bottom: 16px;
  left: 50%;
  z-index: 4;
  padding: 6px 12px;
  border-radius: 999px;
  color: var(--canvas);
  background: var(--text);
  font-family: var(--font);
  font-size: 13px;
  font-weight: 600;
  line-height: 1.2;
  white-space: nowrap;
  transform: translateX(-50%);
  pointer-events: none;
}

.demo-art {
  position: relative;
  display: block;
}

/* The device (founder 2026-10-19 ~11:40 Pacific, replacing the theme-dependent frame): the Your
   receipts mockups' phone (DOCS/design/your-receipts "Exact values"): the bezel 6 px of #1d1d1f,
   40 px corners, one 1 px light inner edge; the screen's 34 px corners clip the page's canvas.
   Light theme (founder 2026-10-20 17:50Z, item 10; DOCS/design/landing device row): an outer rim,
   so the frame reads as a metal edge around the bezel, with the spec's drop shadow and a soft
   contact shadow; no image, no blur filter. The edge is 1.5 px of the rim colour in every browser
   (founder 2026-10-21 01:30Z, item 1): a 1 px border, which Chromium and Safari both draw whole,
   plus a 0.5 px inset ring of the rim colour inside it, listed first so it draws over the 1 px
   light inner edge. Dark keeps the shipped frame exactly: a 1 px #1d1d1f border and the inner
   edge only. The body and the rim are the theme's frame tokens (--frame-body, --frame-rim; in
   light one grey since founder 2026-10-29 item 5, above). */
.demo-phone {
  padding: 6px;
  border: 1px solid var(--frame-rim);
  border-radius: 40px;
  background: var(--frame-body);
  box-shadow:
    inset 0 0 0 0.5px var(--frame-rim),
    inset 0 0 0 1px rgba(255, 255, 255, 0.16),
    0 30px 60px -30px rgba(10, 20, 40, 0.35),
    0 2px 6px rgba(10, 20, 40, 0.08);
}

@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) .demo-phone {
    box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.16);
  }
}

:root[data-theme="dark"] .demo-phone {
  box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.16);
}

.demo-screen {
  position: relative;
  overflow: hidden;
  width: calc(390px * var(--hero-scale));
  height: calc(var(--hero-viewport-height) * var(--hero-scale));
  border-radius: 34px;
  background: var(--canvas);
  /* The screen's own clip, so the scaled viewport never shows past the rounded corners. */
  isolation: isolate;
}

.hero-viewport {
  position: absolute;
  top: 0;
  left: 0;
  width: 390px;
  height: var(--hero-viewport-height);
  transform: scale(var(--hero-scale));
  transform-origin: 0 0;
}

/* The status bar as the mockups draw it: "9:41" and three dots, 44 px tall, 18 px in from each
   side, semibold 14 px in the page's text colour on its canvas. Decorative; the pages lie below. */
.demo-status {
  position: absolute;
  top: 0;
  right: 0;
  left: 0;
  z-index: 3;
  display: flex;
  align-items: center;
  justify-content: space-between;
  height: var(--hero-status-bar);
  padding: 0 18px;
  color: var(--text);
  background: var(--canvas);
  font-family: var(--font);
  font-size: 14px;
  font-weight: 600;
  line-height: 1;
  pointer-events: none;
}

/* A frame: the viewport's scroller around one inert page. Only the frame shown takes the pointer;
   the others are hidden once their crossfade ends. Scrollbars are the phone's, so none is drawn.
   overscroll-behavior stays at its default, so a scroll at the page's end chains to the landing. */
.hero-frame {
  position: absolute;
  inset: var(--hero-status-bar) 0 0;
  overflow-x: hidden;
  overflow-y: auto;
  scrollbar-width: none;
  outline: none;
  opacity: 0;
  visibility: hidden;
  transition:
    opacity 280ms cubic-bezier(0.2, 0, 0, 1),
    visibility 0s linear 280ms;
}

.hero-frame::-webkit-scrollbar {
  display: none;
}

/* The frame shown follows the one checked step (the run checks them as it goes). */
.hero-demo:has(input[value="ask"]:checked) .hero-frame-ask,
.hero-demo:has(input[value="answer"]:checked) .hero-frame-answer,
.hero-demo:has(input[value="receipt"]:checked) .hero-frame-receipt {
  opacity: 1;
  visibility: visible;
  transition:
    opacity 280ms cubic-bezier(0.2, 0, 0, 1),
    visibility 0s;
}

/* With a fine pointer the script scrolls the frame (momentum and a rubber band), not the browser. */
.hero-demo.hero-js-scroll .hero-frame {
  overflow-y: hidden;
}

/* The page fills the viewport at least, as a page fills a browser. */
.hero-demo .hero-frame > .hero-page {
  min-height: 100%;
}

/* The Receipt frame starts at "Your plan" (founder 2026-10-21 21:15Z; assets/hero.js). The frames
   leave the real page's "Powered by Sess" footer out, so the completed page keeps that room at its
   end: enough for the plan to reach the top once the receipt card makes the page scroll. A page
   that fits the screen (no receipt card) still does not scroll. */
.hero-demo .hero-frame-receipt > .hero-page {
  padding-bottom: 48px;
}

/* The run's tap indicator: a soft circle the size of a fingertip (44 px in the viewport) where the
   person taps, as a screen recording shows touches. assets/hero.js places and animates it
   (transform and opacity only). */
.hero-tap {
  position: absolute;
  top: 0;
  left: 0;
  z-index: 2;
  width: 44px;
  height: 44px;
  margin: -22px 0 0 -22px;
  border-radius: 50%;
  background: color-mix(in srgb, var(--text) 22%, transparent);
  box-shadow: 0 0 0 1px color-mix(in srgb, var(--text) 18%, transparent);
  opacity: 0;
  pointer-events: none;
}

/* The phone's select picker (the iPhone's menu for a select, drawn as the system's own chrome over
   the real page): a rounded menu of the select's real options, a checkmark on the chosen one, over
   a light scrim. Its rows wrap, so no option is ever cut short. assets/hero.js fills, places and
   animates it. */
.hero-picker {
  position: absolute;
  inset: 0;
  z-index: 1;
  pointer-events: none;
}

.hero-picker[hidden] {
  display: none;
}

.hero-picker-scrim {
  position: absolute;
  inset: 0;
  background: color-mix(in srgb, var(--canvas) 30%, transparent);
}

.hero-picker-menu {
  position: absolute;
  overflow: hidden;
  width: 280px;
  max-height: 396px;
  border-radius: 14px;
  background: var(--surface);
  box-shadow:
    0 0 0 1px var(--border),
    0 8px 24px rgb(0 0 0 / 0.08),
    0 2px 6px rgb(0 0 0 / 0.05);
  color: var(--text);
  font-family: var(--font);
  font-size: 17px;
  line-height: 22px;
  transform-origin: 50% 0;
}

.hero-picker-list {
  margin: 0;
  padding: 0;
  list-style: none;
}

.hero-picker-list li {
  position: relative;
  min-height: 44px;
  padding: 11px 16px 11px 40px;
  border-top: 1px solid var(--border);
}

.hero-picker-list li:first-child {
  border-top: 0;
}

/* The chosen option's checkmark, drawn (no glyph or icon font): a short stroke and a long one. */
.hero-picker-list li.hero-picker-checked::before {
  content: "";
  position: absolute;
  top: 15px;
  left: 17px;
  width: 6px;
  height: 11px;
  border: solid currentColor;
  border-width: 0 2px 2px 0;
  rotate: 45deg;
}

.hero-picker-list li.hero-picker-pressed {
  background: var(--control-fill);
}

@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) .hero-picker-menu {
    background: var(--surface-2);
    box-shadow: 0 0 0 1px var(--border);
  }
}

:root[data-theme="dark"] .hero-picker-menu {
  background: var(--surface-2);
  box-shadow: 0 0 0 1px var(--border);
}

/* The controls under the device (founder 2026-10-19 ~00:10Z and ~01:25Z): one block, centred on
   the device's centre line (the device block is a column centred on the phone, at least as wide as
   the switch from 768 px), 16 px under the phone (no caption between them, founder 2026-10-20
   ~02:50Z, decision 1), as wide as the switch:
   - row 1, the step switch alone (Ask, Answer, Receipt): a quiet segmented control, one rounded
     track with the chosen step raised on it, three equal segments (each the widest label's width),
     labels centred;
   - row 2, 12 px under the switch: two equal slots that together are the switch's width, so they
     split exactly on the phone's centre line; Play/Pause and Try it each centred in its slot. Play
     and Pause share one button as wide as the wider label, so nothing moves when it changes. */
.hero-controls {
  position: relative;
  display: grid;
  width: max-content;
  max-width: calc(100vw - 2 * var(--space-8));
  margin: var(--space-8) 0 0;
}

.hero-steps {
  display: grid;
  grid-auto-columns: 1fr;
  grid-auto-flow: column;
  gap: 2px;
  min-width: 0;
  margin: 0;
  padding: var(--space-2);
  border: 0;
  border-radius: var(--radius);
  background: var(--control-fill);
}

/* Each native radio lies over its whole label, drawn as nothing (appearance none, transparent), so
   a click or tap anywhere on the label chooses it and native radio keyboard behaviour stays:
   arrow keys move through the group. The label draws the state; its ring shows for keyboard focus
   only, one ring (design language §8). */
.hero-step {
  position: relative;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 2.75rem;
  min-height: calc(2.75rem - 2 * var(--space-2));
  padding: 0 var(--space-8);
  border-radius: calc(var(--radius) - var(--space-2));
  color: var(--text-2);
  font-size: var(--type-sm);
  font-weight: 500;
  line-height: 1.2;
  transition:
    background-color 120ms cubic-bezier(0.2, 0, 0, 1),
    color 120ms cubic-bezier(0.2, 0, 0, 1);
}

/* The 44 px target: the radio reaches past the label to the track's edges. */
.hero-step input {
  position: absolute;
  inset: calc(-1 * var(--space-2)) 0;
  width: 100%;
  height: calc(100% + 2 * var(--space-2));
  margin: 0;
  background: transparent;
  appearance: none;
  outline: none;
  cursor: pointer;
}

.hero-step:has(input:checked) {
  color: var(--text);
  background-color: var(--surface);
  box-shadow:
    0 1px 2px rgb(0 0 0 / 0.06),
    0 1px 1px rgb(0 0 0 / 0.04);
}

.hero-step:has(input:focus-visible) {
  outline: var(--focus-width) solid var(--focus);
  outline-offset: var(--focus-offset);
}

/* Row 2: two equal columns, each as wide as the wider of the two (the grid's 1fr columns in a
   container sized to its content). Without the script Play stays hidden and Try it is alone. */
.hero-links {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  margin: var(--space-6) 0 0;
}

/* Without the script Play stays hidden, and Try it takes the whole row, centred. */
.hero-links:has(> .hero-play[hidden]) {
  grid-template-columns: minmax(0, 1fr);
}

/* Play/Pause and Try it: tertiary actions (design language §8: accent label, no fill), each with a
   44 px target, the label centred in its column, and the shared focus ring. */
.hero-play,
.hero-try a {
  display: inline-grid;
  place-items: center;
  min-width: 2.75rem;
  min-height: var(--control-height);
  padding: 0 var(--space-6);
  color: var(--accent);
  font: inherit;
  font-size: var(--type-sm);
  font-weight: 500;
  text-decoration: none;
}

.hero-play {
  justify-self: center;
  border: 0;
  border-radius: var(--radius-sm);
  background: transparent;
  cursor: pointer;
}

.hero-play[hidden] {
  display: none;
}

/* One slot for Play and Pause: both labels are laid in the same cell, hidden, so the slot is the
   wider label's width whichever shows; the label shown sits over them. */
.hero-play::before,
.hero-play::after {
  grid-area: 1 / 1;
  visibility: hidden;
}

.hero-play::before {
  content: attr(data-play);
}

.hero-play::after {
  content: attr(data-pause);
}

.hero-play-label {
  grid-area: 1 / 1;
}

/* Underlined on hover where the pointer really hovers (a tap leaves no underline behind). */
@media (hover: hover) {
  .hero-play:hover .hero-play-label,
  .hero-try a:hover {
    text-decoration: underline;
  }
}

/* "Try it" (founder 2026-10-18 ~22:40Z): the visible link to /try, or the quickstart where /try is
   off (the device is not a link; a mouse click on its screen follows this one, 2026-10-21 04:57Z). */
.hero-try {
  display: grid;
  justify-items: center;
}

/* Reduced motion (design language §7): stills only. Steps switch at once and nothing moves. */
@media (prefers-reduced-motion: reduce) {
  .hero-frame,
  .hero-demo:has(input[value="ask"]:checked) .hero-frame-ask,
  .hero-demo:has(input[value="answer"]:checked) .hero-frame-answer,
  .hero-demo:has(input[value="receipt"]:checked) .hero-frame-receipt,
  .hero-step {
    transition-duration: 0s;
    transition-delay: 0s;
  }
}

/* The eyebrow (design language §5, founder amendment 2026-10-19 20:07Z): one short line above a
   section headline, the hero included: caption size, 600, uppercase, +0.06em, muted, 14 px above
   the headline. */
.eyebrow,
.section-eyebrow {
  margin: 0 0 14px;
  font-size: var(--type-xs);
  font-weight: 600;
  line-height: 1.4;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--muted);
}

/* The landing hero's type (§5 Scale, Landing hero only; §9 Landing hero): the headline at the hero
   token clamp(3rem, 1.5rem + 5.3vw, 5.75rem), 700, -0.03em, leading 1.02 (3rem on compact
   screens); its second line 2.375rem (1.375rem compact); the lead 1.5625rem; the supporting line
   1.125rem; the note .9375rem. */
.hero h1 {
  margin: 0 0 var(--space-16);
  color: var(--display-ink);
  font-family: var(--font);
  font-size: clamp(3rem, 1.5rem + 5.3vw, 5.75rem);
  font-weight: 700;
  line-height: 1.02;
  letter-spacing: -0.03em;
  text-wrap: balance;
}

.lede {
  max-width: var(--measure);
  margin: 0;
  font-size: var(--type-lg);
  line-height: 1.55;
  color: var(--text-2);
}

.hero .lede {
  max-width: 36rem;
  font-size: 1.5625rem;
  line-height: 1.45;
}

.supporting {
  margin: 14px 0 0;
  color: var(--muted);
}

.hero .supporting {
  font-size: var(--type-lg);
}

/* The two-line hero heading: each line is a block, so the break holds at every width. */
.hero-line {
  display: block;
}

/* The creed heading, two tiers in one <h1> (founder 2026-10-18): "Life transacts." at the hero
   display size, then "You decide. We sign. You keep." on one smaller line where it fits. Each
   beat carries a non-breaking space, so a line wraps only between beats. */
.hero h1.hero-creed {
  /* 32 px between the headline block and the lead (founder 2026-10-18: "space-4" on the 8 px
     step scale; here --space-N is N/8 rem, so 32 px is --space-16). */
  margin-bottom: var(--space-16);
  text-wrap: wrap;
}

.hero-creed .hero-tier-2 {
  margin-top: var(--space-8);
  font-size: 2.375rem;
  font-weight: 600;
  line-height: 1.2;
  letter-spacing: -0.02em;
  color: var(--display-ink);
  text-wrap: balance;
}

.hero-note {
  margin: var(--space-12) 0 0;
  font-size: var(--type-md);
  color: var(--muted);
}

/* The note is one link to "Add Sess to your agent" (founder 2026-10-31 03:33Z): it reads as the
   muted note, never underlined or blue; hover only darkens it to the body ink (the breadcrumbs'
   quiet link, without their underline), and keyboard focus draws the shared :focus-visible ring. */
.hero-note-link {
  color: inherit;
  text-decoration: none;
}

.hero-note-link:hover {
  color: var(--text);
  text-decoration: none;
}

/* Its end, "any agent that speaks HTTPS.", stays on one line, and the lines fill greedily (not the
   body's pretty wrapping, which would carry "and" down): the sentence wraps just before it. */
.hero-note {
  text-wrap: wrap;
}

.hero-note-tail {
  white-space: nowrap;
}

/* Calls to action stack below 768 px, one per row (founder 2026-10-23 21:15Z item 3): one
   column as wide as the widest label, so the buttons share one width and one left edge. */
.actions {
  display: grid;
  grid-template-columns: minmax(0, max-content);
  gap: var(--space-6);
  margin: var(--space-16) 0 0;
}

.actions .button {
  justify-content: center;
}

.hero .actions {
  margin-top: 36px;
}

.actions .button {
  max-width: 100%;
  padding: 0.7rem 1.3rem;
  font-size: 1.0625rem;
  /* A one-word label wider than a phone with enlarged text wraps inside its button. */
  overflow-wrap: anywhere;
}

/* Compact screens (below 60rem, the spec's compact layout): the headline at 3rem, the line beneath
   at 1.375rem, and the hero's two calls to action stacked at the column's full width, so their
   edges line up with each other and with the copy. */
@media (max-width: 59.99rem) {
  .hero h1 {
    font-size: 3rem;
  }

  .hero-creed .hero-tier-2 {
    font-size: 1.375rem;
  }

  .hero .actions {
    grid-template-columns: minmax(0, 1fr);
  }
}

/* From 768 px (founder 2026-10-23 23:30Z): the primary button with the second action beside it as
   a text link on one row (accent, underline on hover; language.md §8 Link), its 44 px target
   kept. Below 768 px both stay stacked buttons in source order (above). */
@media (min-width: 48rem) {
  .actions,
  .hero .actions {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--space-6);
  }

  .actions .button-secondary,
  .actions .button-secondary:hover,
  .actions .button-secondary:active {
    min-height: 44px;
    padding: 0 0.25rem;
    background: none;
    border-color: transparent;
    color: var(--accent);
  }

  .actions .button-secondary:hover {
    text-decoration: underline;
    text-decoration-thickness: 2px;
  }
}

/* The stacked tablet hero, from 48em to the two columns (iPad portrait, 768 and 810 px; founder
   2026-10-27 00:40Z): the copy and its lead take the content width rather than the two-column
   line length (42rem and 36rem above), and the device block comes 32 px under the copy rather than
   48, centred (.hero-demo). Phones below 48em and the two-column hero from 60em are untouched. In
   em of the page's width, as the two-column query, so enlarged text keeps the compact hero.
   After the hero's type, so the lead's measure here wins over its default. Portrait touch
   screens only (founder: "iPhone, landscape and desktop unchanged"): an iPhone in landscape
   (844 to 932 px) is not portrait, and a desktop window of the same size, however tall, has a
   fine primary pointer, so both keep the compact hero. An iPad with a trackpad attached may report
   a fine pointer; it then keeps the compact hero too, as before this rule, deliberately: the rule
   never reaches a desktop. */
@media (orientation: portrait) and (pointer: coarse) {
  @container landing (min-width: 48em) and (max-width: 59.99em) {
    .hero {
      row-gap: var(--space-16);
    }

    .hero-copy,
    .hero .lede {
      max-width: none;
    }

    /* Balanced, the lead's three lines would each stay as short as at 36rem; filled, they run to
       the content width. */
    .hero .lede {
      text-wrap: pretty;
    }
  }
}

.section h2 {
  margin: 0 0 var(--space-12);
  font-family: var(--font);
  font-size: var(--type-display);
  font-weight: 650;
  line-height: 1.2;
  letter-spacing: -0.02em;
}

.steps {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 15rem), 1fr));
  gap: var(--space-8);
  margin: 0;
  padding: 0;
  list-style: none;
  counter-reset: step;
}

.steps > li {
  counter-increment: step;
  padding: var(--space-12);
  border: 1px solid var(--card-edge);
  border-radius: var(--radius-lg);
  background: var(--surface);
}

.steps > li::before {
  content: counter(step, decimal-leading-zero);
  display: block;
  margin-bottom: var(--space-6);
  font-family: var(--mono);
  font-size: var(--type-sm);
  color: var(--muted);
}

.steps h3,
.card h3 {
  margin: 0 0 var(--space-4);
  font-size: var(--type-lg);
  font-weight: 600;
  letter-spacing: -0.01em;
}

.steps p,
.card p {
  margin: var(--space-4) 0;
  color: var(--text-2);
}

/* Card grids (design language §9a "Card grids", founder 2026-10-18 06:30Z and 06:32Z): no row is
   ever partly filled. A grid takes the largest column count, up to its size class's cap, that
   divides its card count, else one column: caps 1 on compact (< 600px), 2 on medium (600-1023px),
   3 on expanded (1024-1439px) and 4 on wide (>= 1440px). A grid holds 1, 2, 3, 4, 6 or 8 cards
   (the build check refuses 5, 7 and 9 or more), so:
     2 cards: 1 / 2 / 2 / 2      3 cards: 1 / 1 / 3 / 3      4 cards: 1 / 2 / 2 / 4
     6 cards: 1 / 2 / 3 / 3      8 cards: 1 / 2 / 2 / 4      (compact / medium / expanded / wide)
   The card count is read by the grid itself (:has with :nth-child on the last card), so every
   .cards grid follows the rule with no script and no per-page class. Tracks are minmax(0, 1fr):
   a long word wraps inside its card instead of widening the page; the grid keeps its section's
   width cap. */
.cards {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: var(--space-8);
  margin: 0;
  padding: 0;
  list-style: none;
}

@media (min-width: 37.5rem) {
  /* Medium: two columns for an even count. */
  .cards:has(> :last-child:nth-child(2n)) {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}

@media (min-width: 64rem) {
  /* Expanded: three columns when three divides the count (an even count keeps two). */
  .cards:has(> :last-child:nth-child(3n)) {
    grid-template-columns: repeat(3, minmax(0, 1fr));
  }
}

@media (min-width: 90rem) {
  /* Wide: four columns when four divides the count. */
  .cards:has(> :last-child:nth-child(4n)) {
    grid-template-columns: repeat(4, minmax(0, 1fr));
  }
}

/* Separation from the background (founder 2026-10-23 01:00Z; design language §4): every card and
   tile on the page (the quickstart steps, cards, the "How it works" disclosure, the docs pager,
   the plan groups, the feedback card, the code blocks) is separated from it by its surface and
   one 1 px --card-edge, never by a shadow. Inputs keep their boxes; tables keep their hairlines; notices
   and callouts keep their own edge. */
.card {
  padding: var(--space-12);
  border: 1px solid var(--card-edge);
  border-radius: var(--radius-lg);
  background: var(--surface);
}

/* §8: a card's inset is 24, 16 on compact screens. */
@media (max-width: 37.49rem) {
  .card {
    padding: var(--space-8);
  }
}

/* A card in a grid takes no list spacing (the docs prose spaces `li + li`), so the cards of one row
   share a top edge; the grid gap spaces them. */
.cards > .card {
  margin: 0;
}

.card ul {
  margin: var(--space-4) 0 0;
  padding-left: 1.1rem;
  color: var(--text-2);
}

.card li + li {
  margin-top: var(--space-4);
}

.card p:last-child,
.card ul:last-child {
  margin-bottom: 0;
}

/* A card's heading link. :where() keeps it at the specificity of the other link rules (one class,
   one element), so later link rules never sit below it in specificity. */
.card :where(h3) a {
  color: var(--text);
  text-decoration: none;
}

.card :where(h3) a:hover {
  text-decoration: underline;
}

.planned {
  margin: var(--space-16) 0 0;
  color: var(--muted);
}

.section-lede {
  max-width: var(--measure);
  margin: 0;
  font-size: var(--type-lg);
  color: var(--text-2);
}

/* A one- or two-line lead spans the content it introduces (§5 Measure, #385); multi-line prose
   keeps the measure. */
.section-lede.section-lede-span {
  max-width: none;
}

.card .status {
  margin: var(--space-6) 0 var(--space-4);
}

.card .note {
  font-size: var(--type-sm);
  color: var(--muted);
}

/* "How it works" and other advanced detail, one click away (details/summary, no script). §8: a
   card (radius 14); its summary and body inset 24 sideways, 16 on compact screens; the summary row
   keeps its 44 px control height. */
.advanced {
  margin: var(--space-8) 0;
  border: 1px solid var(--card-edge);
  border-radius: var(--radius-lg);
  background: var(--surface);
}

.advanced > summary {
  min-height: var(--control-height);
  padding: var(--space-6) var(--space-12);
  font-weight: 600;
  color: var(--text);
  cursor: pointer;
}

.advanced:where([open]) > summary {
  border-bottom: 1px solid var(--border);
}

.advanced > :not(summary) {
  margin: var(--space-8) var(--space-12);
}

@media (max-width: 37.49rem) {
  .advanced > summary {
    padding-inline: var(--space-8);
  }

  .advanced > :not(summary) {
    margin-inline: var(--space-8);
  }
}

/* §5: multi-line prose is at most 68 characters wide (a narrower rule of its own still applies,
   and a one- or two-line lead that spans its section keeps its own wider rule). */
main p {
  max-inline-size: 68ch;
}

/* The landing's signed one-line notes keep their width (DOCS/design/landing .note: no max-width;
   on one line from about 1024 px): the §5 cap is for multi-line prose, not a signed single line.
   The hero's note, since founder 2026-10-31 03:33Z, may wrap once at the hero copy's own width. */
.hero-note,
.chapter-note {
  max-inline-size: none;
}

/* ------------------------------------------------------------------ docs layout */

.docs-layout {
  max-width: var(--docs-max);
  margin: 0 auto;
  padding: 0 var(--space-12);
}

.docs-nav {
  margin: var(--space-8) 0 0;
  border: 1px solid var(--border);
  border-radius: var(--radius);
}

.docs-nav > summary {
  padding: var(--space-6) var(--space-8);
  font-size: var(--type-sm);
  font-weight: 600;
  cursor: pointer;
}

.docs-nav nav {
  padding: 0 var(--space-8) var(--space-8);
}

.docs-nav ul {
  margin: 0;
  padding: 0;
  list-style: none;
}

.docs-nav ul ul {
  margin: var(--space-2) 0 var(--space-12);
}

.docs-nav a {
  display: block;
  padding: 0.3rem 0.6rem;
  border-radius: var(--radius-sm);
  font-size: var(--type-sm);
  color: var(--muted);
  text-decoration: none;
}

.docs-nav a:hover {
  color: var(--text);
  background: var(--surface-2);
}

.docs-nav a[aria-current="page"] {
  color: var(--text);
  background: var(--surface-2);
  font-weight: 600;
}

.nav-group {
  display: block;
  margin: var(--space-8) 0 var(--space-2);
  padding: 0 0.6rem;
  font-size: var(--type-xs);
  font-weight: 600;
  color: var(--muted);
}

.docs-main {
  display: block;
  min-width: 0;
  padding: var(--space-16) 0 0;
  /* One content column (founder 2026-11-03 06:30Z item 12a): prose, tables and code blocks share
     one width of about 780 px and one left edge, on every docs page; nothing runs wider: a code
     block's frame scrolls sideways inside itself, and a table wider than the column (four columns
     on a phone) inside its own region at the column's width, as before. The page's measure is that
     column (the article, previous and next, the useful row), the API reference's wide article
     included. */
  --measure: 48.75rem;
}

.docs-main > .prose-wide {
  max-width: var(--measure);
}

/* Inside the column, paragraphs, list items, the lead and the plan grid take its whole width
   instead of their own 68ch cap, so their edges are the tables' and code blocks' edges. */
.docs-main .prose p,
.docs-main .prose li,
.docs-main .prose .lede,
.docs-main .plan-grid {
  max-width: none;
  max-inline-size: none;
}

.docs-toc {
  display: none;
}

@media (min-width: 60rem) {
  .docs-layout {
    display: grid;
    grid-template-columns: 15rem minmax(0, 1fr);
    gap: var(--space-24);
  }

  /* The scrolling nav clips at its padding box: 4 px of inline padding holds the links' 2 px
     focus ring and its 2 px offset (§8 Focus), and the margin takes it back, so the links stay
     where the column draws them. */
  .docs-nav {
    position: sticky;
    top: var(--header-h);
    align-self: start;
    max-height: calc(100vh - var(--header-h));
    overflow-y: auto;
    margin: 0 calc(-1 * var(--space-2));
    padding: var(--space-12) var(--space-2);
    border: 0;
    border-radius: 0;
  }

  .docs-nav[open] > summary {
    display: none;
  }

  .docs-nav nav {
    padding: 0;
  }

  .docs-nav .nav-group:first-child {
    margin-top: 0;
  }
}

/* The page outline beside the column from 1440 only (founder 2026-11-03 18:35Z flag 4): at 1280 the
   column keeps its whole 780 px beside the menu, and "On this page" is the inline disclosure. */
@media (min-width: 90rem) {
  .docs-layout {
    grid-template-columns: 15rem minmax(0, 1fr) 13rem;
  }

  .docs-toc {
    display: block;
    position: sticky;
    top: var(--header-h);
    align-self: start;
    max-height: calc(100vh - var(--header-h));
    overflow-y: auto;
    padding: var(--space-16) 0;
  }

  .toc-inline {
    display: none;
  }
}

/* The docs page shell's gutters per §9a size class: 16 compact and 24 medium (above), 32 expanded,
   40 wide. Above the 90rem layout width the layout is centred. */
@media (min-width: 64rem) {
  .docs-layout {
    padding: 0 var(--space-16);
  }
}

@media (min-width: 90rem) {
  .docs-layout {
    padding: 0 var(--space-20);
  }
}

.page-toc {
  font-size: var(--type-sm);
}

.toc-title {
  margin: 0 0 var(--space-4);
  font-size: var(--type-xs);
  font-weight: 600;
  color: var(--muted);
}

.toc-list {
  margin: 0;
  padding: 0;
  list-style: none;
}

.toc-list a {
  display: block;
  padding: 0.2rem 0 0.2rem var(--space-6);
  border-left: 1px solid var(--border);
  color: var(--muted);
  text-decoration: none;
}

.toc-list a:hover {
  color: var(--text);
  border-left-color: var(--text);
}

.toc-inline {
  margin: var(--space-12) 0;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  font-size: var(--type-sm);
}

.toc-inline > summary {
  padding: var(--space-6) var(--space-8);
  font-weight: 600;
  cursor: pointer;
}

.toc-inline nav {
  padding: 0 var(--space-8) var(--space-8);
}

/* Set by theme.js before first paint on narrow screens: the docs menu stays collapsed until
   site.js (or theme.js's DOMContentLoaded fallback) closes the details element, which is open
   by default for readers without JS. */
.docs-nav-pending .docs-nav > nav {
  display: none;
}

.breadcrumbs ol {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-4);
  margin: 0 0 var(--space-8);
  padding: 0;
  list-style: none;
  font-size: var(--type-sm);
  color: var(--muted);
}

.breadcrumbs li + li::before {
  content: "/";
  margin-right: var(--space-4);
  color: var(--control);
}

.breadcrumbs a {
  color: var(--muted);
  text-decoration: none;
}

.breadcrumbs a:hover {
  color: var(--text);
  text-decoration: underline;
}

.breadcrumbs [aria-current="page"] {
  color: var(--text);
}

.pager {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: var(--space-8);
  max-width: var(--measure);
  margin: var(--space-32) 0 0;
  padding-top: var(--space-12);
  border-top: 1px solid var(--border);
}

.pager a {
  display: flex;
  flex-direction: column;
  gap: 0.15rem;
  padding: var(--space-8);
  border: 1px solid var(--card-edge);
  border-radius: var(--radius);
  background: var(--surface);
  text-decoration: none;
}

.pager a:hover {
  border-color: var(--control);
}

.pager-next {
  text-align: right;
  grid-column: 2;
}

.pager-label {
  font-size: var(--type-xs);
  color: var(--muted);
}

/* Previous and next sit side by side from 352 px up, each half the row (founder 2026-11-02): the
   grid stretches both cards to the taller one's height. A title wraps to at most two lines and
   ends in an ellipsis only if it is longer, and a long word breaks, so a long title or enlarged
   text never widens the page. */
/* Below 22rem (narrower than 352 px, e.g. 320 px) two half-width cards leave a title under seven
   characters a line, so "Sess documentation" would break mid-word: the cards stack there, each
   the full row, Next under Previous and still right-aligned. 390 px and up stay side by side. */
@media (max-width: 21.99rem) {
  .pager {
    grid-template-columns: minmax(0, 1fr);
  }

  .pager-next {
    grid-column: 1;
  }
}

.pager-title {
  display: -webkit-box;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 2;
  overflow: hidden;
  overflow-wrap: break-word;
  color: var(--text);
  font-weight: 600;
}

/* The docs pages' footer row (founder 2026-10-22 03:30Z): "Was this page useful? Yes / No", in
   the page flow under previous/next (no slide-up, modal or toast). No opens a short note under
   the row (details/summary, no script). After a post the runtime returns to the page at an outcome
   anchor; :target shows that line beside the question in place of Yes and No (founder 2026-10-31
   20:50Z, as the in-place line below). */
.page-feedback {
  max-width: var(--measure);
  margin: var(--space-16) 0 0;
  padding-top: var(--space-8);
  border-top: 1px solid var(--border);
}

/* The question and the thumbs share a centre line. An answer's line sits 12 px after the
   question, as before; the thumbs' group is drawn 8 px back into that gap, so the first glyph
   (12 px inside its target) sits 16 px after the question's last word. */
.page-feedback-row {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-2) var(--space-6);
  min-block-size: 2.75rem;
}

.page-feedback-question {
  margin: 0;
  color: var(--text-2);
  font-size: var(--type-sm);
}

/* Yes and No: one unit that never splits; when it does not fit beside the question it wraps under
   it whole. */
.page-feedback-answers {
  display: flex;
  flex-wrap: nowrap;
  align-items: center;
  gap: 0;
  margin-inline-start: calc(-1 * var(--space-4));
}

.page-feedback-yes,
.page-feedback-no {
  margin: 0;
}

/* Yes and No (founder 2026-11-02 02:41Z): icon-only thumbs, the 20 px glyph centred in a 44 px
   target, in the muted text colour. On hover the text colour on the control fill, as the icon
   set's copy button (copy-button.ts); the focus ring is the shared :focus-visible rule. The
   chosen one is drawn filled in the text colour: No while its note is open, and the pressed one
   (while pressed, and while its answer is being sent in place: site.js marks the form). */
.page-feedback-thumb {
  position: relative;
  display: flex;
  align-items: center;
  justify-content: center;
  box-sizing: border-box;
  inline-size: 2.75rem;
  block-size: 2.75rem;
  margin: 0;
  padding: 0;
  border: 0;
  border-radius: var(--radius);
  background: none;
  color: var(--muted);
  font: inherit;
  list-style: none;
  cursor: pointer;
}

.page-feedback-thumb::-webkit-details-marker {
  display: none;
}

.page-feedback-glyph {
  display: block;
  flex: none;
}

@media (hover: hover) {
  .page-feedback-thumb:hover {
    background: var(--control-fill);
    color: var(--text);
  }
}

.page-feedback-thumb:active,
.page-feedback-yes[data-sending] > .page-feedback-thumb,
.page-feedback-no[open] > .page-feedback-thumb {
  color: var(--text);
}

/* The line drawing at rest; the solid one (layout.ts thumbGlyph) for the chosen thumb. */
.page-feedback-glyph-solid {
  display: none;
}

.page-feedback-thumb:active .page-feedback-glyph-line,
.page-feedback-yes[data-sending] > .page-feedback-thumb .page-feedback-glyph-line,
.page-feedback-no[open] > .page-feedback-thumb .page-feedback-glyph-line {
  display: none;
}

.page-feedback-thumb:active .page-feedback-glyph-solid,
.page-feedback-yes[data-sending] > .page-feedback-thumb .page-feedback-glyph-solid,
.page-feedback-no[open] > .page-feedback-thumb .page-feedback-glyph-solid {
  display: inline;
}

.page-feedback-note .button {
  min-height: 2.75rem;
  font: inherit;
  font-size: var(--type-sm);
  font-weight: 600;
  cursor: pointer;
}

/* The note follows the row and shows while No is open; the buttons stay where they were. */
.page-feedback-note {
  display: none;
}

/* Sent in place (site.js; the status line's rules follow the outcome lines below). */
.page-feedback-answered .page-feedback-answers,
.page-feedback-answered .page-feedback-note {
  display: none;
}

/* The note (founder 2026-11-02 02:43Z): the label above a two-line box (rows="2"), the box's
   edges on the text column's (the section is the column), the privacy line under the box, small
   and muted, as its description, then Send, a small secondary (never the primary, never full
   width), its right edge on the box's. The box is the site's field (the /feedback form's: the
   control boundary, 3:1, on the surface); the focus ring is the shared :focus-visible rule at the
   box's own radius. The same at every width. */
.page-feedback:has(.page-feedback-no[open]) .page-feedback-note {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: var(--space-4);
  margin: var(--space-4) 0 0;
}

.page-feedback-note > label {
  color: var(--text-2);
  font-size: var(--type-sm);
}

.page-feedback-note > textarea {
  display: block;
  box-sizing: border-box;
  inline-size: 100%;
  margin: 0;
  padding: var(--space-4) var(--space-6);
  border: var(--border-width) solid var(--control);
  border-radius: var(--radius);
  background: var(--surface);
  color: var(--text);
  font: inherit;
  font-size: var(--type-base);
  line-height: var(--leading-body);
  resize: none;
}

/* Two lines at first, then the box grows with the note (`field-sizing`, as the /feedback form's
   message), so it needs no resize handle; where that is not supported, rows="2" and a scroll. */
@supports (field-sizing: content) {
  .page-feedback-note > textarea {
    field-sizing: content;
    min-block-size: calc(2lh + 2 * var(--space-4) + 2 * var(--border-width));
  }
}

.page-feedback-note > textarea:focus-visible {
  border-radius: var(--radius);
}

.page-feedback-privacy {
  max-inline-size: none;
  margin: 0;
  font-size: var(--type-xs);
  color: var(--muted);
}

.page-feedback-note > .button {
  justify-self: end;
  justify-content: center;
}

.page-feedback-outcome {
  display: none;
  margin: 0;
  font-size: var(--type-sm);
  color: var(--text);
}

.page-feedback-outcome:target {
  display: block;
}

/* The line takes the programmatic focus so a screen reader announces it; it is not a control, so
   it draws no focus ring (every control keeps the :focus-visible ring). */
.page-feedback-outcome:focus,
.page-feedback-outcome:focus-visible {
  outline: none;
}

.page-feedback:has(.page-feedback-outcome:target) .page-feedback-answers,
.page-feedback:has(.page-feedback-outcome:target) .page-feedback-note {
  display: none;
}

/* Sent in place (site.js, founder 2026-10-29 F30): Yes and No, the note and any outcome line give
   way to the status line beside the question, which is empty until then; site.js closes No, so
   the note's :has rule no longer shows it. Like an outcome line it takes the focus but is not a
   control, so it draws no ring. */
.page-feedback-done {
  margin: 0;
  font-size: var(--type-sm);
  color: var(--text);
}

.page-feedback-done:focus,
.page-feedback-done:focus-visible {
  outline: none;
}

.page-feedback-answered .page-feedback-outcome {
  display: none;
}

/* ------------------------------------------------------------------ prose */

.prose {
  max-width: var(--measure);
  color: var(--text-2);
}

.prose-wide {
  max-width: 68rem;
}

/* §5: multi-line prose keeps a 68ch measure, also in the wider reference column. */
.prose p,
.prose li {
  max-width: 68ch;
}

/* A system page's stage (the docs 404) is centred in the content area, not in the reading
   measure: 68ch follows the system's face, so a start-aligned measure column would put the stage
   off centre wherever 68ch is narrower than the column (Roboto, Helvetica). The stage keeps its
   own 30rem measure (stage.ts). */
.prose:has(> .stage) {
  max-width: none;
}

.prose h1,
.prose h2,
.prose h3,
.prose h4,
.prose strong {
  color: var(--text);
}

.prose h1 {
  margin: 0 0 var(--space-8);
  font-family: var(--font);
  font-size: var(--type-display);
  font-weight: 650;
  line-height: 1.15;
  letter-spacing: -0.025em;
}

.prose h2 {
  margin: var(--space-24) 0 var(--space-6);
  font-size: var(--type-xl);
  font-weight: 600;
  line-height: 1.3;
  letter-spacing: -0.015em;
  scroll-margin-top: calc(var(--header-h) + var(--space-8));
}

.prose h3 {
  margin: var(--space-16) 0 var(--space-4);
  font-size: var(--type-lg);
  font-weight: 600;
  scroll-margin-top: calc(var(--header-h) + var(--space-8));
}

.prose h4 {
  margin: var(--space-12) 0 var(--space-4);
  font-size: var(--type-base);
  font-weight: 600;
  scroll-margin-top: calc(var(--header-h) + var(--space-8));
}

.heading-link {
  color: inherit;
  text-decoration: none;
}

.heading-link:hover {
  text-decoration: underline;
  text-decoration-color: var(--control);
}

/* A page's lead takes the width of the body text under it (founder 2026-11-02 19:52Z): the body
   paragraphs' 68ch at --type-base (1rem) is 68ch / 1.125 at the lead's --type-lg (1.125rem), and
   the prose column caps both alike. It fills its lines like the body text (pretty, not balance:
   balancing a two- or three-line lead pulled every line in to about half the column). */
.prose .lede {
  max-width: calc(68ch / 1.125);
  font-size: var(--type-lg);
  color: var(--muted);
  text-wrap: pretty;
}

/* The privacy policy and terms (founder 2026-10-19): the effective date under the lede. */
.legal-effective {
  color: var(--muted);
  font-size: var(--type-sm);
}

.prose li + li {
  margin-top: var(--space-2);
}

.prose table,
.section table {
  width: 100%;
  border-collapse: collapse;
  font-size: var(--type-sm);
}

caption {
  padding-bottom: var(--space-4);
  text-align: left;
  font-weight: 600;
  color: var(--text);
}

th,
td {
  padding: 0.55rem 0.75rem;
  border-bottom: 1px solid var(--border);
  text-align: left;
  vertical-align: top;
}

th {
  font-weight: 600;
  color: var(--text);
  background: var(--surface-2);
}

/* The plan grid (founder 2026-10-21 20:25Z; scripts/plan-grid.ts), on Pricing and Limits, at the
   prose measure. From medium widths (600 px) a table: a label column and one column per plan,
   hairline rows, no boxes, no bullets, values only, and a last row, "Plan", with one plain link
   per plan. On compact widths the same values as four stacked label/value groups in the form 2
   field-family grouped-rows style (design-tokens renderer-rows.ts): an inset card, radius 14,
   rows at least 48 px, 16 px in from its edges, hairlines inset 16 px from the start, the muted
   label at the start and the value at the end, the value going under the label when the two do
   not fit. Exactly one of the two is displayed. Logical properties only (RTL mirrors). */
.plan-grid {
  max-width: 68ch;
  margin: var(--space-8) 0;
}

.prose .plan-table {
  width: 100%;
  border-collapse: collapse;
  font-size: var(--type-base);
  font-variant-numeric: tabular-nums;
}

.plan-table th,
.plan-table td {
  padding: var(--space-6) var(--space-4);
  border-bottom: var(--border-width) solid var(--border);
  background: none;
  text-align: start;
  vertical-align: top;
  overflow-wrap: anywhere;
}

.plan-table :is(th, td):first-child {
  padding-inline-start: 0;
}

.plan-table :is(th, td):last-child {
  padding-inline-end: 0;
}

.plan-table thead :is(th, td) {
  padding-top: 0;
  font-weight: 600;
  color: var(--text);
  /* A plan name breaks only when it alone overflows, so its column keeps it whole ("Enterprise"). */
  overflow-wrap: break-word;
}

.plan-table tbody th {
  font-weight: 400;
  color: var(--muted);
}

.plan-table td {
  color: var(--text);
}

/* The Plan row (founder 2026-11-02 19:40Z): the last row of the table and of each stacked group,
   one plain link per plan ("Sign up", "Upgrade", "Talk to us"), as Enterprise's price is; no
   hairline under the table's last row. Each link is a 44 px target: block padding grows the hit
   area, not the line. */
.plan-table tbody tr:last-child :is(th, td) {
  padding-bottom: 0;
  border-bottom: 0;
}

.plan-grid a {
  padding-block: 0.875rem;
}

/* In the table the values, the prices ("$29") and the Plan row's links each stay on one line
   (founder 2026-10-30 16:58Z: the price reads as the console writes it) wherever the grid is at
   least 66ch of its own text wide. The grid's cap is 68ch, so a full-measure grid qualifies in any
   font; narrower (a medium window, the Limits block, text at 200 %) they wrap as any cell does, so
   the row labels never break inside a word and nothing scrolls sideways. */
.plan-grid {
  container-type: inline-size;
}

@container (min-width: 66ch) {
  .plan-table tbody td {
    white-space: nowrap;
  }
}

.plan-stack {
  display: none;
}

.plan-group + .plan-group {
  margin-top: var(--space-10);
}

.prose .plan-group h3 {
  margin: 0 0 var(--space-4);
  font-size: var(--type-base);
}

.plan-group dl {
  margin: 0;
  background: var(--surface-2);
  border: 1px solid var(--card-edge);
  border-radius: var(--radius-lg);
  font-variant-numeric: tabular-nums;
}

.plan-row {
  position: relative;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  column-gap: var(--space-8);
  min-block-size: 3rem;
  padding: var(--space-2) var(--space-8);
}

.plan-row + .plan-row::before {
  content: "";
  position: absolute;
  inset-block-start: 0;
  inset-inline-start: var(--space-8);
  inset-inline-end: 0;
  border-top: var(--border-width) solid var(--border);
}

.plan-row dt {
  padding: var(--space-4) 0;
  color: var(--muted);
}

.plan-row dd {
  margin: 0;
  padding: var(--space-4) 0;
  color: var(--text);
  text-align: end;
}

@media (max-width: 37.49rem) {
  .plan-table {
    display: none;
  }

  .plan-stack {
    display: block;
  }
}

/* The links under the grid are 44 px targets: inline padding grows the hit area, not the line. */
.prose .plan-note a {
  padding-block: 0.875rem;
}

@media (forced-colors: active) {
  .plan-group dl {
    border: 1px solid CanvasText;
  }

  .plan-row + .plan-row::before {
    border-top-color: CanvasText;
  }
}

.table-wrap {
  max-width: 100%;
  overflow-x: auto;
  margin: var(--space-8) 0;
  border: 1px solid var(--border);
  border-radius: var(--radius);
}

.table-wrap table {
  margin: 0;
}

.table-wrap caption {
  padding: var(--space-6) 0.75rem var(--space-4);
}

.table-wrap tr:last-child td {
  border-bottom: 0;
}

/* sess.si/use-cases (roadmap 1.26; founder 2026-10-30 18:30Z; row anatomy signed 2026-11-01
   04:32Z): one table on the console Sessions list's standard (#876, #912; @sess/design-tokens
   console-sheet.ts), from the shared tokens. From 600 px a table in one card (the console's
   .table-wrap: surface, radius-lg; the edge is the §4 card-edge), columns about 24 / 30 / 46:
   column headers small, strong and muted on surface-2 (space-5 by space-8), cells space-6 by
   space-8 with hairline rows, the last row without one (26 / 36 / 38 from 1024 px, below). Below 600 px (the site's compact
   breakpoint, as the plan grid's) each row is a card: surface, the 1 px card-edge, radius-lg,
   inset space-6 by space-8 (the Sessions compact row's 11 by 14 px on the 8 px grid), space-6
   apart; the column headers are visually hidden and stay for assistive technology, the cells show
   their labels ("On the page", "The agent receives"; aria-hidden, since the headers name them),
   and the one table stays a table to assistive technology, as the console Sessions list's compact
   rows do (use-cases.spec.ts reads its roles at 390 px). The JSON is the one shared code block
   (CODE_BLOCK_RULES); this sheet sets only its outer margin. Logical properties only. */
.use-case-wrap {
  margin: var(--space-12) 0 0;
}

@media (min-width: 37.5rem) {
  .use-case-wrap {
    background: var(--surface);
    border: var(--border-width) solid var(--card-edge);
    border-radius: var(--radius-lg);
    overflow: hidden;
  }
}

.prose .use-case-table {
  margin: 0;
  table-layout: fixed;
  font-size: var(--type-md);
}

.use-case-table col.use-case-name {
  inline-size: 24%;
}

.use-case-table col.use-case-page {
  inline-size: 30%;
}

.use-case-table thead th {
  padding: var(--space-5) var(--space-8);
  background: var(--surface-2);
  color: var(--muted);
  font-size: var(--type-xs);
  font-weight: var(--weight-strong);
  text-align: start;
}

.use-case-table tbody :is(th, td) {
  padding: var(--space-6) var(--space-8);
  background: none;
  color: var(--text-2);
  font-weight: 400;
  text-align: start;
  overflow-wrap: break-word;
}

.use-case-table tbody th strong {
  display: block;
  color: var(--text);
  font-weight: var(--weight-strong);
}

.use-case-line {
  display: block;
  margin-block-start: var(--space-2);
  color: var(--muted);
}

.use-case-table tbody tr:last-child :is(th, td) {
  border-bottom: 0;
}

.prose .use-case-table ol {
  margin: 0;
  padding-inline-start: var(--space-10);
}

.prose .use-case-table li + li {
  margin-block-start: var(--space-3);
}

.use-case-label {
  display: none;
}

.use-case-table figure.result {
  margin: 0;
}

/* No "response.data" caption on any row (founder 2026-11-03 18:42Z fix 12): the column header
   names it once, and in a phone's card the label "What the agent receives" does; the block starts
   at the top of its cell, level with the first step. Only hidden: the shared block is otherwise
   unchanged (code-blocks.ts hidesResultCaption). */
.use-case-table figure.result > figcaption {
  display: none;
}

/* With the caption gone, its grid row leaves no gap above the frame. */
.use-case-table figure.result {
  row-gap: 0;
}

/* The header's code part: the mono face at the header's caption size, no chip. */
.use-case-table thead .use-case-head-code code {
  padding: 0;
  background: none;
  border: 0;
  font-family: var(--mono);
  font-size: var(--type-xs);
  font-weight: 400;
}

/* A code block in a cell keeps the shared frame's wrapping, not the short-token rule above. */
.use-case-table pre > code {
  white-space: inherit;
}

/* A JSON line too long for the column (the approval's "reply") wraps under its own text, not at
   column 0: every line the JSON starts sits where it is written, and only a wrapped continuation
   is indented (CSS Text 3 `hanging each-line`). This page's blocks only; the shared frame is
   unchanged for every other caller. */
.use-case-table figure.result > pre {
  text-indent: 4ch hanging each-line;
}

.prose :is(.use-case-ref, .use-case-see) {
  margin: var(--space-2) 0 0;
  font-size: var(--type-sm);
}

/* The reference link and "See the page" (a link to the row's frame, not a button) are 44 px
   targets. */
.prose :is(.use-case-ref, .use-case-see) a {
  display: inline-flex;
  align-items: center;
  min-block-size: 2.75rem;
}

@media (max-width: 37.49rem) {
  .use-case-table,
  .use-case-table tbody,
  .use-case-table tr,
  .use-case-table th,
  .use-case-table td {
    display: block;
    inline-size: auto;
  }

  .use-case-table colgroup {
    display: none;
  }

  .use-case-table thead {
    position: absolute;
    inline-size: 1px;
    block-size: 1px;
    overflow: hidden;
    clip-path: inset(50%);
    white-space: nowrap;
  }

  .use-case-table tbody tr {
    margin: 0 0 var(--space-6);
    padding: var(--space-6) var(--space-8);
    background: var(--surface);
    border: var(--border-width) solid var(--card-edge);
    border-radius: var(--radius-lg);
  }

  .use-case-table tbody :is(th, td) {
    padding: 0;
    border: 0;
  }

  .use-case-table tbody td {
    padding-block-start: var(--space-8);
  }

  .use-case-table tbody th strong {
    font-size: var(--type-base);
  }

  .use-case-label {
    display: block;
    margin-block-end: var(--space-4);
    color: var(--muted);
    font-size: var(--type-xs);
    font-weight: var(--weight-strong);
  }
}

/* From 1024 px the table takes the wider measure, so no case title, step or JSON line wraps
   where the landing's do not (founder 2026-11-01); the heading and the lede keep the reading
   measure. The longest lines need a 26 / 36 / 38 split of about 64rem (the questionnaire's
   title, its second step and the approval's "reply" line, with the cells' padding and the shared
   frame's), so the measure is 66rem; at 1024 px the content area is 60rem and the longest
   lines still wrap. The prose column keeps its measure, so the heading and the lede are
   unchanged; the table's card extends past it to the section's content width at most (the
   section is the query container, 100cqi its content box). */
@media (min-width: 64rem) {
  .use-cases {
    container-type: inline-size;
  }

  .use-case-wrap {
    inline-size: min(66rem, 100cqi);
  }

  .use-case-table col.use-case-name {
    inline-size: 26%;
  }

  .use-case-table col.use-case-page {
    inline-size: 36%;
  }
}

@media (forced-colors: active) {
  .use-case-wrap,
  .use-case-table tbody tr {
    border-color: CanvasText;
  }
}

/* Code blocks (figure.code, figure.result: the caption above the frame, the copy button inside
   the frame's top right corner) are the one shared block of @sess/design-tokens copy-button.ts
   (CODE_BLOCK_RULES, in assets/sess.css). Code wraps long lines instead of scrolling sideways:
   overlay scrollbars (phones, macOS) show no cue that a line continues, so its end looked cut off;
   the copy button copies the unwrapped text. This sheet adds no frame or placement rules of its
   own (scripts/code-blocks.ts codeSheetProblems). */

/* The docs picture of how the person's page looks (Concepts; founder 2026-10-21 05:50Z item 9). */
figure.page-looks {
  margin: var(--space-8) 0;
}

figure.page-looks img {
  display: block;
  max-width: 100%;
  height: auto;
}

dl.facts {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: var(--space-4);
  margin: var(--space-8) 0;
}

dl.facts > div {
  display: grid;
  grid-template-columns: minmax(8rem, 12rem) minmax(0, 1fr);
  gap: var(--space-6);
}

dl.facts dt {
  font-weight: 600;
  color: var(--text);
}

dl.facts dd {
  margin: 0;
  overflow-wrap: anywhere;
}

@media (max-width: 30rem) {
  dl.facts > div {
    grid-template-columns: minmax(0, 1fr);
    gap: 0;
  }
}

/* ------------------------------------------------------------------ language tabs */

.tabs {
  margin: var(--space-8) 0;
}

/* One row that never wraps (founder 2026-10-31 00:18Z): on one line at desktop widths; on a phone
   it scrolls sideways inside its own box, never the page. A fieldset's default min-content width
   would push the page wider, hence min-inline-size: 0. site.js keeps the checked tab in view. */
.tab-list {
  display: flex;
  flex-wrap: nowrap;
  gap: var(--space-2);
  min-inline-size: 0;
  margin: 0;
  padding: 0;
  border: 0;
  border-bottom: 1px solid var(--border);
  overflow-x: auto;
  overflow-y: hidden;
  overscroll-behavior-x: contain;
  scrollbar-width: thin;
}

@media (prefers-reduced-motion: no-preference) {
  .tab-list {
    scroll-behavior: smooth;
  }
}

.tab {
  flex: none;
  white-space: nowrap;
  position: relative;
  display: inline-block;
  padding: var(--space-4) var(--space-6);
  border-bottom: 2px solid transparent;
  font-size: var(--type-sm);
  color: var(--muted);
  cursor: pointer;
}

/* The radio covers its label: visible, clickable and focusable, with no appearance of its own. */
.tab input {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  margin: 0;
  appearance: none;
  background: transparent;
  border: 0;
  cursor: pointer;
}

.tab input:focus-visible {
  outline: none;
}

.tab:has(input:focus-visible) {
  outline: 2px solid var(--focus);
  outline-offset: -2px;
  border-radius: var(--radius-sm);
}

.tab:has(input:checked) {
  color: var(--text);
  border-bottom-color: var(--text);
  font-weight: 600;
}

/* A host tab: the maker's logo (20 px tall, its own colours, unchanged) beside the host's name.
   The light file shows in the light theme and the dark file in the dark theme (the site's theme
   choice, else the system's). */
.tab-host {
  display: inline-flex;
  align-items: center;
  gap: var(--space-4);
}

.tab-logo {
  flex: none;
  width: auto;
  height: 20px;
}

.tab-logo-dark {
  display: none;
}

/* The page's closing line about product names and logos (founder 2026-10-18). */
.host-owners {
  margin-top: var(--space-24);
  font-size: var(--type-sm);
  color: var(--muted);
}

@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) .tab-logo-light {
    display: none;
  }

  :root:not([data-theme="light"]) .tab-logo-dark {
    display: inline;
  }
}

:root[data-theme="dark"] .tab-logo-light {
  display: none;
}

:root[data-theme="dark"] .tab-logo-dark {
  display: inline;
}

.tab-panel {
  display: none;
}

/* Up to twelve tabs (build.ts MAX_LABELLED_TABS); the legend is the tab list's first child. */
.tabs:has(.tab:nth-child(2) input:checked) .tab-panel:nth-child(1),
.tabs:has(.tab:nth-child(3) input:checked) .tab-panel:nth-child(2),
.tabs:has(.tab:nth-child(4) input:checked) .tab-panel:nth-child(3),
.tabs:has(.tab:nth-child(5) input:checked) .tab-panel:nth-child(4),
.tabs:has(.tab:nth-child(6) input:checked) .tab-panel:nth-child(5),
.tabs:has(.tab:nth-child(7) input:checked) .tab-panel:nth-child(6),
.tabs:has(.tab:nth-child(8) input:checked) .tab-panel:nth-child(7),
.tabs:has(.tab:nth-child(9) input:checked) .tab-panel:nth-child(8),
.tabs:has(.tab:nth-child(10) input:checked) .tab-panel:nth-child(9),
.tabs:has(.tab:nth-child(11) input:checked) .tab-panel:nth-child(10),
.tabs:has(.tab:nth-child(12) input:checked) .tab-panel:nth-child(11),
.tabs:has(.tab:nth-child(13) input:checked) .tab-panel:nth-child(12) {
  display: block;
}

@supports not selector(:has(*)) {
  .tab-panel {
    display: block;
  }
}

/* ------------------------------------------------------------------ add Sess to your agent */

/* One status per host, from the dated host matrix (apps/site/src/hosts.ts). "Not yet available"
   uses the draft colours; the other statuses are quiet outlined labels. */
.status-badge {
  display: inline-block;
  padding: 0 0.45em;
  border: 1px solid var(--control);
  border-radius: 5px;
  color: var(--text);
  font-size: var(--type-xs);
  font-weight: 600;
  line-height: 1.6;
}

.status-badge[data-status="not-yet-available"] {
  border-color: var(--draft-line);
  background: var(--draft-bg);
  color: var(--draft-ink);
}

.host-status {
  margin: var(--space-8) 0;
  color: var(--text-2);
}

.host-steps {
  display: grid;
  /* minmax(0, …): a long command scrolls inside its code block, never the page. */
  grid-template-columns: minmax(0, 1fr);
  gap: var(--space-6);
  padding-left: 1.2rem;
}

.host-note {
  color: var(--muted);
  font-size: var(--type-sm);
}

/* ------------------------------------------------------------------ API reference */

/* Long paths may break at any character on narrow screens; the badge column stays fixed. */
.op-list code {
  min-width: 0;
  background: none;
  border: 0;
  padding: 0;
  overflow-wrap: anywhere;
}

.operation,
.schema {
  margin: var(--space-24) 0;
  padding-top: var(--space-16);
  border-top: 1px solid var(--border);
}

@media (max-width: 37.49rem) {
  .operation,
  .schema {
    margin: var(--space-16) 0;
    padding-top: var(--space-8);
  }
}

.operation h3,
.schema h3 {
  margin-top: 0;
  font-size: var(--type-lg);
  overflow-wrap: anywhere;
}

.operation h3 code,
.schema h3 code {
  font-size: 0.95em;
  background: none;
  border: 0;
  padding: 0;
}

.operation-id {
  margin-top: 0;
  font-size: var(--type-sm);
  color: var(--muted);
}

/* An operation is one column, in its skeleton's order (founder 2026-11-03 06:30Z item 12a-b): the
   summary, What it does, Authentication, the parameters, Request body, Responses, Examples, then
   Advanced (details.advanced, closed). The summary reads as the operation's lead. */
.operation .op-summary {
  font-size: var(--type-lg);
  color: var(--text);
}

.op-does {
  padding-inline-start: var(--space-12);
}

/* A long example shows its first 12 lines with a soft fade and "Show all · N lines" (founder
   2026-11-03 06:30Z item 12d; site.js sets data-collapsed and adds the control, so without
   JavaScript the whole block shows). The frame keeps its own sideways scroll; only its height is
   capped: 12 lines of 1.6 plus its padding and border (CODE_BLOCK_RULES). */
figure.code[data-collapsed] > pre {
  max-height: calc(12 * 1.6em + 2 * var(--space-8) + 2 * var(--border-width));
  overflow-y: hidden;
  -webkit-mask-image: linear-gradient(to bottom, #000 calc(100% - 4.8em), transparent);
  mask-image: linear-gradient(to bottom, #000 calc(100% - 4.8em), transparent);
}

/* The control under the frame: a quiet text button, 44 px tall, at the frame's start edge. */
button.code-toggle {
  justify-self: start;
  min-height: var(--control-height);
  margin: 0;
  padding: 0 var(--space-2);
  font: inherit;
  font-size: var(--type-sm);
  font-weight: var(--weight-strong);
  color: var(--accent);
  background: none;
  border: 0;
  border-radius: var(--radius-sm);
  cursor: pointer;
}

button.code-toggle:hover {
  text-decoration: underline;
}

button.code-toggle:focus-visible {
  outline: var(--focus-width) solid var(--focus);
  outline-offset: var(--focus-offset);
}

.method {
  display: inline-block;
  min-width: 3.6em;
  margin-right: 0.35em;
  padding: 0.05em 0.45em;
  border-radius: 5px;
  font-family: var(--mono);
  font-size: 0.75rem;
  font-weight: 700;
  letter-spacing: 0.02em;
  text-align: center;
  vertical-align: 0.15em;
  background: var(--surface-2);
  color: var(--text);
}

.method-get {
  background: var(--success-soft);
  color: var(--success);
}

.method-post {
  background: var(--accent-soft);
  color: var(--accent);
}

.method-patch,
.method-put {
  background: var(--put-bg);
  color: var(--put-ink);
}

.method-delete {
  background: var(--danger-soft);
  color: var(--danger);
}

/* The operation index: one column, fixed-width method badges, paths aligned. */
.op-list {
  margin: var(--space-8) 0;
  padding: 0;
  list-style: none;
  border: 1px solid var(--border);
  border-radius: var(--radius);
}

.op-list li + li {
  margin: 0;
  border-top: 1px solid var(--border);
}

.op-list a {
  display: flex;
  align-items: baseline;
  gap: var(--space-6);
  padding: 0.45rem var(--space-8);
  color: var(--text);
  text-decoration: none;
}

.op-list a:hover {
  background: var(--surface-2);
}

.op-list .method {
  flex: none;
  width: 6.5ch;
  min-width: 0;
  margin: 0;
}

.op-list a:hover code {
  text-decoration: underline;
}

.props {
  margin: var(--space-4) 0;
  padding: 0;
  list-style: none;
}

.props > .prop {
  padding: var(--space-4) 0;
  border-bottom: 1px solid var(--border);
}

.prop-head {
  margin: 0;
}

.prop-name {
  font-weight: 600;
  color: var(--text);
}

.prop-type {
  font-size: var(--type-sm);
  color: var(--muted);
}

.prop p {
  margin: 0.2rem 0;
  font-size: var(--type-sm);
}

.req,
.opt {
  font-size: var(--type-xs);
  font-weight: 600;
}

.req {
  color: var(--danger);
}

.opt {
  color: var(--muted);
}

.constraints,
.schema-type {
  margin: 0.25rem 0;
  font-size: var(--type-sm);
  color: var(--muted);
}

.nested {
  margin: var(--space-4) 0 0 0.2rem;
  padding-left: var(--space-8);
  border-left: 1px solid var(--border);
}

.body-schema {
  margin: var(--space-4) 0 var(--space-8);
}

.hash {
  overflow-wrap: anywhere;
}

/* ------------------------------------------------------------------ search */

.search-list {
  padding-left: 1.1rem;
}

.search-list p {
  margin: 0.1rem 0 var(--space-4);
  color: var(--muted);
  font-size: var(--type-sm);
}

[data-search-mount] label {
  display: block;
  font-weight: 600;
  color: var(--text);
}

[data-search-mount] input {
  width: 100%;
  max-width: 28rem;
  margin: var(--space-4) 0;
  padding: 0.55rem 0.8rem;
  border: 1px solid var(--control);
  border-radius: var(--radius);
  background: var(--surface);
  color: var(--text);
  font: inherit;
}

/* ------------------------------------------------------------------ small screens */

/* The site header's Menu layout, below 74rem (founder 2026-10-26 22:40Z: raised from 60rem, so
   that tablets in landscape, 1024 px and up to 1183 px, get the Menu rather than a two-line bar).
   The full row of links, with Console, the theme switch, Sign in and Get started, needs about
   1179 px in the system font on Apple devices (1140 px in CI's Linux fonts), so it starts at the
   next whole rem, 74rem (1184 px). Only the header's rules are here; the rest of the small-screen
   layout (the footer, the docs and the spacing below) stays at 60rem. */
@media (max-width: 73.99rem) {
  /* One row (founder 2026-10-17 ~22:13Z): the logo on the left, a search button and a Menu on the
     right. Menu is a CSS-only disclosure (details/summary) that opens a full-width panel: Product,
     Docs, API reference, Pricing and Get started (or Console, signed in), then the Theme row, the
     console account menu's Auto | Light | Dark, a form that works without JavaScript (founder
     2026-10-31 03:48Z). The header scrolls away on narrow screens. */
  .site-header {
    position: relative;
  }

  /* One row that never wraps, as in the console (the shared header, #415): with very large text
     (200% at 320 px) the wordmark shrinks before Search or Menu would leave the row. The shared
     header's narrow-screen rule (a scrolling row of links) gives way to the Menu. */
  .site-header > .bar {
    flex-wrap: nowrap;
    gap: var(--space-4);
  }

  /* The lockup's 40 px row centred on the 44 px Search and Menu targets (2 px, whole pixels). */
  .site-header > .bar > .brand {
    align-self: center;
  }

  .site-header .primary-nav,
  .bar > .theme-slot {
    display: none;
  }

  .mobile-search {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    flex: none;
    width: var(--control-height);
    height: var(--control-height);
    margin-left: auto;
    border: 1px solid var(--border);
    border-radius: var(--radius-sm);
    color: var(--text);
  }

  .mobile-search .icon {
    width: 1.125rem;
    height: 1.125rem;
  }

  .mobile-menu {
    display: block;
    flex: none;
  }

  .mobile-menu > summary {
    display: inline-flex;
    align-items: center;
    min-height: var(--control-height);
    padding: 0 var(--space-6);
    border: 1px solid var(--control);
    border-radius: var(--radius-sm);
    color: var(--text);
    font-size: var(--type-sm);
    font-weight: 600;
    list-style: none;
    cursor: pointer;
  }

  .mobile-menu > summary::-webkit-details-marker {
    display: none;
  }

  .mobile-menu[open] > summary {
    border-color: var(--text);
  }

  .mobile-panel {
    position: absolute;
    top: 100%;
    left: 0;
    right: 0;
    z-index: 30;
    padding: var(--space-4) var(--space-8) var(--space-12);
    background: var(--surface);
    border-bottom: 1px solid var(--border);
  }

  .mobile-panel ul {
    margin: 0;
    padding: 0;
    list-style: none;
  }

  .mobile-panel li a:not(.button) {
    display: block;
    padding: var(--space-5) 0;
    border-bottom: 1px solid var(--border);
    color: var(--text);
    text-decoration: none;
  }

  .mobile-panel li a[aria-current="page"] {
    font-weight: 600;
  }

  .mobile-panel .mobile-cta {
    margin-top: var(--space-8);
  }

  .mobile-panel .mobile-cta .button {
    display: flex;
    justify-content: center;
    min-height: var(--control-height);
  }

  /* The Theme row (founder 2026-10-31 03:48Z): the console account menu's row and segmented
     control (@sess/design-tokens THEME_ROW_RULES, in the chrome sheet), the last row of the
     Menu's list, after Get started (or Console), with the list's 1 px separator above it. */
  .mobile-panel .menu-theme {
    margin-top: var(--space-8);
    padding: var(--space-5) 0 0;
    border-top: 1px solid var(--border);
  }
}

@media (max-width: 59.99rem) {
  /* Spacing: the page heading starts 24 px below the header (on docs pages the documentation menu
     comes first, 24 px below it); form controls are full width. */
  .section:first-child:not(.hero) {
    padding-top: var(--space-12);
  }

  .docs-nav {
    margin-top: var(--space-12);
  }

  input:not([type="checkbox"], [type="radio"], [type="file"]),
  select,
  textarea {
    width: 100%;
    max-width: 100%;
    box-sizing: border-box;
  }
}

@media (max-width: 40rem) {
  .search-link {
    min-width: 0;
  }

  .docs-layout {
    padding: 0 var(--space-8);
  }
}

/* ------------------------------------------------------------------ feedback (founder 2026-10-17) */
/* The /feedback page's form, filled in by the runtime (apps/api feedback.ts, @sess/app feedback.ts):
   plain HTML on the site's tokens; works without script. One 35rem column (about 560px), 24px
   between groups and 8px from label to control. The type is a segmented bar drawn by the labels of
   real radios (:checked + label, :focus-visible + label); the fieldset and legend keep the grouping.
   At the console Send feedback page's standard (founder 2026-10-31 21:20Z; #913, @sess/design-tokens
   CONSOLE_RULES): one column, the intro then the form on the page with no card around it; the
   segmented type with a soft border and soft dividers, the chosen segment filled; the message five
   lines at first, growing with the text; the count hidden until 1,800 characters (feedback.js);
   the primary button at the start of its row. */

.section.feedback-page {
  padding-top: var(--space-24);
}

.feedback-layout {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: var(--space-16);
  max-width: 35rem;
}

.feedback-intro h1 {
  margin: 0 0 var(--space-6);
}

.feedback-lead {
  margin: 0 0 var(--space-12);
  font-size: var(--type-lg);
  line-height: 1.55;
  color: var(--text-2);
}

/* The intro's one line (founder 2026-10-22), in place of "What happens next" and its list. */
.feedback-page .feedback-note {
  margin: 0 0 var(--space-12);
  color: var(--text-2);
}

.feedback-links {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-4) var(--space-12);
  margin: 0;
  font-size: var(--type-sm);
}

.feedback-links a {
  color: var(--muted);
}

.feedback-plain .feedback-form > :last-child {
  margin-bottom: 0;
}

.feedback-page .fb-card-title {
  margin: 0 0 var(--space-6);
  font-size: var(--type-lg);
  letter-spacing: 0;
}

.feedback-account {
  margin: 0 0 var(--space-12);
  font-size: var(--type-sm);
  color: var(--muted);
  overflow-wrap: anywhere;
}

.fb-actions {
  display: flex;
  justify-content: flex-start;
}

.fb-group {
  min-width: 0;
  margin: 0 0 var(--space-12);
  padding: 0;
  border: 0;
}

.fb-group > label,
.fb-group > legend {
  display: block;
  margin: 0 0 var(--space-4);
  padding: 0;
  font-size: var(--type-md);
  font-weight: var(--weight-strong);
  color: var(--text);
}

.feedback-form textarea,
.feedback-form input[type="email"] {
  display: block;
  width: 100%;
  min-height: var(--control-height);
  margin: 0;
  padding: var(--space-4) var(--space-6);
  border: var(--border-width) solid var(--control);
  border-radius: var(--radius);
  background: var(--surface);
  color: var(--text);
  font: inherit;
}

.feedback-form textarea {
  height: 10rem;
  min-height: 10rem;
  resize: vertical;
}

/* The message field (the console's .fb-area): five lines at first, then it grows with the text
   (`field-sizing`; where it is not supported, five lines and the resize handle). Its border stays
   the control border (3:1, WCAG 1.4.11). */
.feedback-form textarea.fb-area {
  height: auto;
  min-height: calc(5 * 1.5em + 2 * var(--space-6) + 2px);
  padding: var(--space-6) var(--space-8);
  field-sizing: content;
}

@supports (min-height: 1lh) {
  .feedback-form textarea.fb-area {
    min-height: calc(5lh + 2 * var(--space-6) + 2px);
  }
}

.feedback-form [aria-invalid="true"] {
  border-color: var(--danger);
}

.fb-count {
  margin: var(--space-3) 0 0;
  text-align: right;
  font-size: var(--type-sm);
  color: var(--muted);
}

.fb-count.over {
  color: var(--danger);
  font-weight: var(--weight-strong);
}

.segmented {
  display: flex;
  width: 100%;
  min-height: var(--control-height);
  overflow: hidden;
  border: var(--border-width) solid var(--border);
  border-radius: var(--radius);
  background: var(--surface);
}

.segmented .segment-input {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: 0;
  padding: 0;
  opacity: 0;
  pointer-events: none;
}

.segment {
  display: flex;
  flex: 1 1 0;
  align-items: center;
  justify-content: center;
  min-width: 0;
  margin: 0;
  padding: 0 var(--space-4);
  border-left: var(--border-width) solid var(--border);
  color: var(--text);
  font-size: var(--type-md);
  font-weight: var(--weight-strong);
  text-align: center;
  cursor: pointer;
}

.segment-input:first-child + .segment {
  border-left: 0;
}

.segment:hover {
  background: var(--surface-2);
}

.segment-input:checked + .segment {
  background: var(--action);
  color: var(--on-action);
}

.segment-input:focus-visible + .segment {
  position: relative;
  z-index: 1;
  outline: var(--focus-width) solid var(--focus);
  outline-offset: calc(-1 * var(--focus-width));
}

.feedback-form .field-error {
  margin: 0 0 var(--space-4);
  font-size: var(--type-sm);
  font-weight: var(--weight-strong);
  color: var(--danger);
}

.feedback-form .notice,
.feedback-slot .notice {
  margin: 0 0 var(--space-12);
  padding: var(--space-6) var(--space-8);
  border: var(--border-width) solid var(--border);
  border-left: var(--edge-width) solid var(--accent);
  border-radius: var(--radius);
  background: var(--accent-soft);
  color: var(--text);
}

.feedback-form .notice.error {
  border-left-color: var(--danger);
  background: var(--danger-soft);
}

/* The site's primary button (.button.button-primary) at the controls' height. */
.feedback-form .fb-submit {
  justify-content: center;
  min-height: var(--control-height);
  padding: var(--space-4) 1.25rem;
  font: inherit;
  font-weight: var(--weight-strong);
  cursor: pointer;
}

@media (max-width: 59.99rem) {
  .fb-submit {
    width: 100%;
  }
}

.feedback-slot .feedback-sent {
  font-size: var(--type-lg);
  color: var(--text);
}

/* The honeypot: out of sight; a person never fills it. */
.feedback-hp {
  position: absolute;
  left: -10000px;
  width: 1px;
  height: 1px;
  overflow: hidden;
}

/* ------------------------------------------------------------------ the landing's chapters

   The landing in five chapters (landing spec DOCS/design/landing/, founder approved 2026-10-19
   20:20Z): the hero, the exchange, build, what a receipt proves, and the promise. Every chapter is
   one composition (design language §6 Section composition): eyebrow, headline, one lead, one
   figure. Facts are hairline sets (§6 Hairline sets), not boxed cards; boxes stay for code
   figures only. Two-column chapters put the words on the left and the artefact on the right, 64 px
   apart; compact screens stack the words first. Two background treatments only (the page's
   surface, and the canvas band on chapters 2 and 4). Only the hero carries buttons (§8 Actions on
   the site); later chapters link inline.
   Since the six chapters (Commerce record §6.3, amendment 2026-10-24): hero, The exchange, The
   receipt, Your receipts, Build, Free for people; the figures alternate right, left, right, left,
   right (.chapter-pair-left below), and the bands fall on chapters 2, 4 and 6. */

/* The headline: 2.75rem (2rem compact), 650, leading 1.12, -0.022em, at most 30ch, balanced. */
.chapter h2 {
  max-width: 30ch;
  margin: 0;
  color: var(--display-ink);
  font-size: 2.75rem;
  font-weight: 650;
  line-height: 1.12;
  letter-spacing: -0.022em;
  text-wrap: balance;
}

/* Build's headline breaks after "page." wherever each sentence fits on one line (founder
   2026-10-24 01:25Z); where it does not (the two-column layout at 1280 and 1440), it wraps
   naturally in up to three lines rather than shrinking. The thresholds are the longer sentence's
   width at the compact (2rem) and desktop (2.75rem) sizes in the system font stack, with margin. */
.chapter-words {
  container-type: inline-size;
}

.chapter h2 .title-break {
  display: none;
}

@media (max-width: 59.99rem) {
  @container (min-width: 28rem) {
    .chapter h2 .title-break {
      display: inline;
    }
  }
}

@media (min-width: 60rem) {
  @container (min-width: 39rem) {
    .chapter h2 .title-break {
      display: inline;
    }
  }
}

/* The lead: 1.3125rem (1.125rem compact), text-2, at most 44rem and the §5 68ch measure (the
   narrower of the two in the reader's font: Roboto's ch makes 44rem 69.6ch at 768 px), with at
   most one strong clause. */
.chapter .section-lede {
  max-width: var(--measure);
  margin: 20px 0 0;
  font-size: 1.3125rem;
  line-height: 1.5;
  color: var(--text-2);
}

.chapter .section-lede strong {
  color: var(--text);
  font-weight: 600;
}

/* An uppercase key in a hairline set: the eyebrow's style. */
.chapter .key {
  display: block;
  margin: 0 0 10px;
  font-size: var(--type-xs);
  font-weight: 600;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--muted);
}

/* Words left, artefact right (founder 2026-10-24 00:58Z): the words are one column, from the
   eyebrow to the bottom of the hairline set (.chapter-words), and the artefact is centred
   vertically against all of it, never top-aligned to a row. Compact screens stack the words
   first, as before. */
.chapter-pair {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  align-items: center;
  gap: 64px;
  margin: 0;
}

.chapter-pair > figure.code,
.chapter-pair > figure.result {
  min-width: 0;
  margin: 0;
}

/* The artefact's box ends at its block at every width, so the block itself is what is centred
   (the one code block, CODE_BLOCK_RULES: the frame has no margin of its own). */

/* ask.mjs (founder 2026-10-21 20:25Z): one field per line, no line wraps at any width; the block
   scrolls sideways instead (its own scroller, never the page). */
figure[data-sdk-ask] pre {
  white-space: pre;
  overflow-wrap: normal;
}

/* A hairline set under a chapter's lead in its words column (every two-column chapter), across
   the whole text column: every rule of a chapter spans exactly its text column (founder
   2026-10-23 06:00Z, landing rhythm, item 4). */
.chapter .chapter-words > .rows {
  max-width: none;
  margin-top: 48px;
}

/* Hairline rows: a label column (11rem) beside the text; a hairline above the first row and
   between rows, none after the last (founder 2026-11-02 04:35Z). */
.chapter .rows {
  max-width: 44rem;
  margin: 0;
  padding: 0;
  list-style: none;
  border-top: 1px solid var(--border);
}

.chapter .rows > li {
  display: grid;
  grid-template-columns: 11rem minmax(0, 1fr);
  gap: 24px;
  margin: 0;
  padding: 16px 0;
  font-size: 1.0625rem;
}

.chapter .rows > li + li {
  border-top: 1px solid var(--border);
}

.chapter .rows .key {
  margin: 0;
  padding-top: 3px;
}

.chapter .rows p {
  margin: 0;
  color: var(--text-2);
}

/* Body lines under a chapter's lead (chapter 4's two sentences), at the prose measure. */
.chapter-text {
  max-width: var(--measure);
  margin: 20px 0 0;
  font-size: 1.0625rem;
  line-height: 1.55;
  color: var(--text-2);
}

/* Chapter 5's close: the signed promise under a hairline, its lines at the prose measure. */
.chapter .promise {
  margin: 56px 0 0;
  padding: 40px 0 0;
  border-top: 1px solid var(--border);
}

.chapter .promise h3 {
  margin: 0;
  font-size: 1.0625rem;
  font-weight: 600;
  letter-spacing: -0.01em;
}

.chapter .promise p {
  max-width: var(--measure);
  margin: 8px 0 0;
  font-size: 1.0625rem;
  line-height: 1.55;
  color: var(--text-2);
}

/* The page's foot: the builders' price line under one hairline. No rule after it (founder
   2026-11-02 04:35Z: on the landing no block ends with a rule; a rule only separates two things). */
.chapter .chapter-foot {
  margin: 56px 0 0;
  padding: 16px 0 0;
  border-top: 1px solid var(--border);
}

.chapter .chapter-foot p {
  max-width: var(--measure);
  margin: 0;
  font-size: 1.0625rem;
  line-height: 1.55;
  color: var(--text-2);
}

.chapter-note {
  margin: 24px 0 0;
  font-size: var(--type-md);
  color: var(--muted);
}

/* Chapter 3: the raw Surface API one click away (doctrine D-I); the gated share-link line. */
.chapter.build .advanced {
  margin: 48px 0 0;
}

/* Every child of the open panel keeps the panel's inner gutter on both sides, as its first
   paragraph does (founder 2026-10-31 00:40Z; .advanced > :not(summary), 24 px, 16 px on compact
   screens). The code figures' own margin rule (figure.code, later in this sheet and of equal
   specificity) had reset their inline margins to 0, so the shell labels and blocks ran flush with
   the panel's border. Only the inset: the code blocks themselves are unchanged. */
.chapter.build .advanced > :not(summary) {
  margin-inline: var(--space-12);
}

@media (max-width: 37.49rem) {
  .chapter.build .advanced > :not(summary) {
    margin-inline: var(--space-8);
  }
}

.build-share {
  margin: var(--space-12) 0 0;
  color: var(--text);
  font-weight: var(--weight-strong);
}

/* The landing's rhythm (founder 2026-10-23 06:00Z): every chapter either fills both columns or
   centres its block, and no paragraph is centred.
   - Words and a render (.chapter-pair with a .chapter-art figure; the receipt and Your receipts):
     the hero's composition, the words in minmax(0, 1fr) (at most 44rem, the text column) beside a
     372 px artefact column, 56 px apart, the render centred vertically against the whole words
     column (founder 2026-10-24 00:58Z, as in every two-column chapter), from the landing's 60em
     (the hero's container query); below it the words, then the artefact centred under them. The artefacts are real renders
     (scripts/landing-renders.ts): the receipt PDF's first page, and the Your receipts screen in
     the hero's phone.
   - A centred block (.chapter-centred, .pricing-strip; a chapter without a render, and the
     pricing strip, founder's choice 2026-10-23 16:15Z): one block at a 36em measure in the middle
     of the page grid, its text left-aligned in it and its rules the block's width. */
.chapter-pair:has(> .chapter-art) {
  grid-template-columns: minmax(0, 1fr);
  align-items: start;
  gap: 40px;
}

@container landing (min-width: 60em) {
  .chapter-pair:has(> .chapter-art) {
    grid-template-columns: minmax(0, 1fr) 372px;
    column-gap: 56px;
    align-items: center;
  }
}

.chapter-words {
  min-width: 0;
  max-width: 44rem;
}

.chapter-art {
  min-width: 0;
  max-width: 100%;
  margin: 0;
  justify-self: center;
}

/* The receipt's first page: a card on the page (design language §4, separation from the
   background): the PDF's paper, white in both themes, separated by one 1 px --card-edge, never a
   shadow. */
.receipt-page-image {
  display: block;
  width: 372px;
  max-width: 100%;
  height: auto;
  border: 1px solid var(--card-edge);
  border-radius: 4px;
  background: #fff;
}

/* The receipt image opens the lightbox (founder 2026-10-24 21:30Z): the image is a link to the PDF
   (assets/site.js opens the lightbox instead), with the site's focus ring around the page. */
.receipt-open {
  display: block;
  border-radius: 4px;
  cursor: zoom-in;
}

/* The lightbox: a native <dialog> opened modally (assets/site.js). A dark scrim over the page, no
   blur; the receipt page at readable size (744 px, the 1488 px render at 2x), centred, the dialog
   scrolling when the page is taller than the window; the 44 px × top-right; "Open the PDF" and,
   under it, "Verify this receipt", quiet links under the document. No motion at all, so reduced motion has nothing to remove. The page
   behind does not scroll while it is open (html.lightbox-open). Below 600 px a full-screen sheet on
   the page's canvas with the same ×. */
html.lightbox-open {
  overflow: hidden;
}

.lightbox {
  box-sizing: border-box;
  width: 100%;
  max-width: none;
  height: 100%;
  max-height: none;
  margin: 0;
  padding: 0 24px 32px;
  overflow: auto;
  overscroll-behavior: contain;
  border: 0;
  color: #f5f5f7;
  /* The scrim: the dialog itself covers the window, so its background is the scrim (and the
     colour its text is read against); the backdrop behind it stays clear. */
  background: rgba(0, 0, 0, 0.8);
}

.lightbox::backdrop {
  background: transparent;
}

.lightbox-bar {
  position: sticky;
  top: 0;
  z-index: 1;
  display: flex;
  justify-content: flex-end;
  margin: 0 -8px;
  padding: 12px 0 8px;
  pointer-events: none;
}

.lightbox-close {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 44px;
  height: 44px;
  padding: 0;
  border: 0;
  border-radius: 50%;
  color: inherit;
  background: rgba(0, 0, 0, 0.55);
  font-family: var(--font);
  font-size: 28px;
  line-height: 1;
  cursor: pointer;
  pointer-events: auto;
}

.lightbox-close:focus-visible,
.lightbox-pdf:focus-visible {
  outline: 2px solid currentColor;
  outline-offset: 2px;
}

.lightbox-document {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 16px;
  width: min(744px, 100%);
  margin: 0 auto;
}

.lightbox-page {
  display: block;
  width: 100%;
  height: auto;
  border-radius: 4px;
  background: #fff;
}

/* "Open the PDF" and "Verify this receipt" (founder 2026-10-25 05:05Z): the same quiet link, one
   under the other beneath the document, centred: a dialog's actions stack at every width (founder
   2026-10-23 21:15Z item 3), two text links included. */
.lightbox-links {
  display: flex;
  flex-direction: column;
  align-items: center;
  margin: 0;
}

.lightbox-pdf {
  padding: 10px 4px;
  color: inherit;
  font-size: var(--type-md);
}

@media (max-width: 37.49rem) {
  .lightbox {
    padding: 0 16px 24px;
    color: var(--text);
    background: var(--canvas);
  }

  .lightbox-close {
    background: transparent;
  }

  .lightbox-page {
    border: 1px solid var(--card-edge);
  }

  .lightbox-pdf {
    color: var(--accent);
  }
}

/* sess.si/use-cases "See the page" (founder 2026-11-01): the same lightbox around the person's
   page in the hero's phone (.demo-phone, its bezel and frame tokens; .demo-screen, its 34 px
   corners), the screen at 390 CSS px, or the sheet's width less its padding and the bezel on a
   narrower window. The page image is the screen's whole height; the dialog scrolls when it is
   taller than the window. One image per theme (as .chapter-screen): only the one shown is
   fetched, once the dialog has set its address (assets/site.js). */
.use-case-screen {
  width: min(390px, calc(100vw - 46px));
  height: auto;
}

.use-case-shot {
  display: block;
  width: 100%;
  height: auto;
}

.use-case-shot-dark {
  display: none;
}

@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) .use-case-shot-light {
    display: none;
  }

  :root:not([data-theme="light"]) .use-case-shot-dark {
    display: block;
  }
}

:root[data-theme="dark"] .use-case-shot-light {
  display: none;
}

:root[data-theme="dark"] .use-case-shot-dark {
  display: block;
}

/* From 600 px the whole phone fits the window (founder 2026-11-01): the phone is at most 90vh
   tall, its screen image scaling with it at its own aspect ratio (390 CSS px wide at most), and
   centred; the × stays in the top-right corner over the scrim, out of the flow, so the dialog
   does not scroll. Only this lightbox: the landing's receipt lightbox is unchanged. Below 600 px
   the sheet is as above. */
@media (min-width: 37.5rem) {
  .use-case-lightbox {
    padding: 0 24px;
  }

  .use-case-lightbox .lightbox-bar {
    position: fixed;
    top: 0;
    right: 24px;
    margin: 0;
  }

  .use-case-lightbox .lightbox-document {
    justify-content: center;
    height: 100%;
  }

  .use-case-lightbox .use-case-screen {
    width: auto;
  }

  /* 14 px: the phone's 6 px bezel and 1 px rim, above and below. */
  .use-case-lightbox .use-case-shot {
    width: auto;
    max-width: 390px;
    max-height: calc(90vh - 14px);
  }
}

/* The six chapters (Commerce record §6.3, amendment 2026-10-24): the sides alternate right, left,
   right, left, right. A figure-left chapter (.chapter-pair-left: The exchange, Your receipts)
   keeps its words first in the document, so a compact screen and a screen reader take the words
   first; from the landing's 60em the figure takes the first column. The exchange's phone keeps
   the hero's 372 px column; Your receipts' tablet takes six parts of eleven beside its words
   (598 px at the 1152 px grid, 600 px at most), the words the other five. Every right column is
   centred vertically against its left column, as in every two-column chapter. */
@container landing (min-width: 60em) {
  .chapter-pair-left:has(> .chapter-art) {
    grid-template-columns: 372px minmax(0, 1fr);
  }

  .chapter-pair-tablet:has(> .chapter-art) {
    grid-template-columns: minmax(0, 6fr) minmax(0, 5fr);
  }

  .chapter-pair-left > .chapter-art {
    grid-row: 1;
    grid-column: 1;
  }

  /* The words fill their column to the page grid's right edge, as a right figure ends on it. */
  .chapter-pair-left > .chapter-words {
    grid-row: 1;
    grid-column: 2;
    max-width: none;
  }
}

/* The exchange's typed result in its words column, under the Receipt row (§6.3 chapter 2). */
.chapter-words > figure.result {
  min-width: 0;
  margin: 48px 0 0;
}

@media (max-width: 59.99rem) {
  .chapter-words > figure.result {
    margin-top: 40px;
  }
}

/* Your receipts' figure: from 960 px the landscape tablet, below it the phone list; only the one
   shown is fetched (its lazy images are display:none otherwise). */
.chapter-yours {
  width: 100%;
}

.chapter-yours > .demo-tablet {
  display: none;
}

.chapter-yours > .yours-phone {
  display: flex;
  justify-content: center;
}

@container landing (min-width: 60em) {
  .chapter-yours > .demo-tablet {
    display: block;
  }

  .chapter-yours > .yours-phone {
    display: none;
  }
}

/* The tablet (founder 2026-10-24 06:35Z item 2: "phone materials, 8 px bezel"): the phone's
   bezel and 1 px edge (the frame tokens), 0.5 px inset ring, light inner edge and two shadows
   (dark: the 1 px #1d1d1f border and the inner edge only, as the phone); an 8 px bezel, 24 px outer corners,
   16 px screen corners. The screen is 1024 x 640 CSS px (16:10; founder 2026-10-29 item 6: the
   page fills it) drawn fluid, at most 600 px wide: a 24 px status bar ("9:41" and dots,
   decorative), then the two-pane page's render (1024 x 616). Every
   length inside the screen is a share of its width (container units), so the screen scales as one
   picture. */
.demo-tablet {
  box-sizing: border-box;
  width: 100%;
  max-width: 600px;
  margin-inline: auto;
  padding: 8px;
  border: 1px solid var(--frame-rim);
  border-radius: 24px;
  background: var(--frame-body);
  box-shadow:
    inset 0 0 0 0.5px var(--frame-rim),
    inset 0 0 0 1px rgba(255, 255, 255, 0.16),
    0 30px 60px -30px rgba(10, 20, 40, 0.35),
    0 2px 6px rgba(10, 20, 40, 0.08);
}

@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) .demo-tablet {
    box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.16);
  }
}

:root[data-theme="dark"] .demo-tablet {
  box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.16);
}

.demo-tablet-screen {
  position: relative;
  overflow: hidden;
  aspect-ratio: 1024 / 640;
  border-radius: 16px;
  background: var(--canvas);
  container-type: inline-size;
  isolation: isolate;
}

.demo-status.demo-tablet-status {
  height: calc(100cqw * 24 / 1024);
  padding: 0 calc(100cqw * 18 / 1024);
  font-size: calc(100cqw * 13 / 1024);
}

.tablet-screen {
  position: absolute;
  top: calc(100cqw * 24 / 1024);
  left: 0;
  width: 100%;
  height: auto;
}

/* Chapter 6, "Free for people. Always." (§6.3 chapter 6; founder 06:35Z item 3): left-aligned text
   in a centred block (the pricing strip's 36em), no imagery; the 06:00Z rule that no paragraph is
   centred stands. The promise is the chapter's headline and its two lines, then the builders'
   price line under its hairline. */
.chapter.free .pricing-strip {
  margin-top: 0;
}

/* The landing's last band ends at the footer, whose own top rule separates them: no second,
   parallel rule at the page's foot (founder 2026-11-02 04:35Z: a rule only separates two things). */
.chapter.free.band {
  border-bottom: 0;
}

.chapter.free .promise {
  margin: 0;
  padding: 0;
  border-top: 0;
}

.chapter.free .promise h2 + p {
  margin-top: 20px;
}

.chapter.free .promise p + p {
  margin-top: 12px;
}

.chapter-viewport {
  position: absolute;
  top: 0;
  left: 0;
  width: 390px;
  height: var(--hero-viewport-height);
  transform: scale(var(--hero-scale));
  transform-origin: 0 0;
}

.chapter-screen {
  position: absolute;
  top: var(--hero-status-bar);
  left: 0;
  display: block;
  width: 390px;
  height: calc(var(--hero-viewport-height) - var(--hero-status-bar));
  object-fit: cover;
  object-position: top;
}

.chapter-screen-dark {
  display: none;
}

@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) .chapter-screen-light {
    display: none;
  }

  :root:not([data-theme="light"]) .chapter-screen-dark {
    display: block;
  }
}

:root[data-theme="dark"] .chapter-screen-light {
  display: none;
}

:root[data-theme="dark"] .chapter-screen-dark {
  display: block;
}

.chapter-centred,
.chapter .pricing-strip {
  max-width: 36em;
  margin-inline: auto;
}

.chapter .pricing-strip {
  margin-top: 56px;
}

.chapter .pricing-strip > :first-child {
  margin-top: 0;
}

@media (max-width: 59.99rem) {
  .chapter h2 {
    font-size: 2rem;
  }

  .chapter .section-lede {
    font-size: var(--type-lg);
  }

  .chapter-pair {
    grid-template-columns: minmax(0, 1fr);
    gap: 32px;
  }

  .chapter .rows > li {
    grid-template-columns: minmax(0, 1fr);
    gap: 6px;
  }

  .chapter .chapter-words > .rows,
  .chapter .promise,
  .chapter .chapter-foot,
  .chapter .pricing-strip {
    margin-top: 40px;
  }

  .chapter .pricing-strip > :first-child {
    margin-top: 0;
  }
}

/* ------------------------------------------------------------------ /try and /demo in the site

   Founder 2026-10-20 18:32Z and its addendum (D-IV one continuum): the runtime's /try and /demo
   pages render in the site shell (apps/api site-shell.ts; their markup is @sess/renderer
   site-flow.ts) and follow the landing's language (design language §5, §6, §8): one eyebrow, one
   headline, one lead; facts in hairline rows, not boxed cards (code figures stay boxed); the
   site's buttons, at the controls' height with a 500 label (§8), stacked full width on a phone.
   The Sess link page (/s/) and the shared-agent page (/a/) are not these pages. */

.section.flow {
  padding-top: var(--space-20);
}

@media (min-width: 60rem) {
  .section.flow {
    padding-top: var(--space-24);
  }
}

/* The headline: the chapters' (2.75rem, 2rem compact), 650, at most 30ch, balanced. */
.section.flow h1 {
  max-width: 30ch;
  margin: 0;
  font-size: 2.75rem;
  font-weight: 650;
  line-height: 1.12;
  letter-spacing: -0.022em;
  text-wrap: balance;
}

/* The lead: 1.3125rem (1.125rem compact), text-2, at most 44rem. */
.section.flow .flow-lead {
  max-width: 44rem;
  margin: 20px 0 0;
  font-size: 1.3125rem;
  line-height: 1.5;
  color: var(--text-2);
}

.section.flow h2 {
  margin: 0 0 var(--space-6);
  font-size: 1.0625rem;
  font-weight: 600;
  line-height: 1.4;
  letter-spacing: -0.01em;
}

.flow-form {
  margin: 0;
}

/* The site's buttons at the controls' height (44 px), padding 0 20, radius 10, a 500 label; one
   primary per screen. On a phone they stack at the column's full width, in source order. */
.flow-actions {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-6);
  margin: var(--space-16) 0 0;
}

.flow-actions .button {
  justify-content: center;
  min-height: var(--control-height);
  padding: 0 1.25rem;
  border-radius: var(--radius);
  font: inherit;
  font-size: 1.0625rem;
  font-weight: 500;
  overflow-wrap: anywhere;
  cursor: pointer;
}

@media (max-width: 47.99rem) {
  .flow-actions {
    flex-direction: column;
    align-items: stretch;
  }
}

.flow-note {
  margin: var(--space-6) 0 0;
  font-size: var(--type-md);
  color: var(--muted);
}

.flow-note:empty {
  display: none;
}

/* Fine print under one top hairline: muted, small. */
.section.flow .flow-fine {
  max-width: 44rem;
  margin: var(--space-16) 0 0;
  padding-top: var(--space-8);
  border-top: 1px solid var(--border);
  font-size: var(--type-md);
  color: var(--muted);
}

.section.flow .flow-fine p {
  margin: 0;
}

.section.flow .flow-fine > * + * {
  margin-top: var(--space-4);
}

.flow-links {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-4) var(--space-12);
  margin: var(--space-12) 0 0;
  font-size: 1.0625rem;
}

.flow-state {
  margin: 0 0 var(--space-8);
  color: var(--text);
  font-weight: 600;
}

.flow-strong {
  font-weight: 600;
}

/* /demo's exchange: the request beside the result (with .flow-columns), under one hairline. */
.flow-pair {
  grid-template-columns: minmax(0, 1fr) auto;
  align-items: start;
  gap: 64px;
  max-width: 44rem;
  margin: var(--space-20) 0 0;
  padding-top: var(--space-12);
  border-top: 1px solid var(--border);
}

/* /try as stages (founder 2026-10-24 22:30Z, amended 22:35Z, and 22:45Z; design language §8
   "System pages are stages"; the stage itself is sess.css's STAGE_RULES): the start page, the
   waiting page with its QR card, the waits and the result, each one centred stage. A page's
   footnote is one small line under the stage, centred on its column, with no rule above it. */
/* The eyebrow keeps the site's paragraph measure, so it is centred as a block too (founder
   2026-11-03 05:40Z item 5: "TRY IT" on the page axis), not only its text within that measure. */
.try-stage .stage .eyebrow {
  margin: 0 auto var(--space-6);
}

.try-stage .try-footnote {
  max-width: 30rem;
  margin: var(--space-12) auto 0;
  font-size: var(--type-sm);
  line-height: 1.5;
  text-align: center;
  color: var(--muted);
}

/* The /try start page (founder 2026-11-03 00:58Z): the two demos as the landing's cards (.cards,
   .card: the same surface, 1 px card edge and radius), side by side from the medium size class and
   stacked full width on a phone. Each card is its form's one submit button, so the button takes
   the card's face, not a button's: no fill, the page's type, start-aligned, as tall as its row.
   Hover and focus show the accent border and nothing moves; the focus ring keeps the card's radius.
   "Start ›" is the card's quiet cue at its bottom right, in the accent (a stage's quiet link). The
   stage is wider here, so the two cards sit side by side under the one-line lead. */
.try-start .stage {
  max-width: 44rem;
}

.try-start .try-cards {
  margin: 0;
}

.try-start .try-card-item,
.try-start .try-card-item > form {
  display: flex;
  height: 100%;
  margin: 0;
}

.try-start .try-card {
  display: flex;
  flex-direction: column;
  box-sizing: border-box;
  width: 100%;
  margin: 0;
  font: inherit;
  color: var(--text);
  text-align: start;
}

.try-start button.try-card {
  cursor: pointer;
}

.try-start button.try-card:hover,
.try-start button.try-card:focus-visible {
  border-color: var(--accent);
}

.try-start button.try-card:focus-visible {
  border-radius: var(--radius-lg);
}

.try-start .try-card-title {
  display: block;
  margin: 0 0 var(--space-4);
  font-size: var(--type-lg);
  font-weight: 600;
  line-height: var(--leading-subheading);
  letter-spacing: -0.01em;
}

.try-start .try-card-text {
  display: block;
  margin: 0;
  color: var(--text-2);
}

.try-start .try-card-start {
  display: block;
  margin: auto 0 0;
  padding-top: var(--space-8);
  align-self: flex-end;
  color: var(--accent);
}

/* Centred between the header and the footer, at every width where the page is a column (the
   shared shell, above): the start page's main area centres its one section, whose own space above
   and below is the same, and the footer takes no space of its own above it here, so the room above
   the content and below it is balanced. */
.site-main:has(> .try-start) {
  display: flex;
  flex-direction: column;
  justify-content: center;
}

body:has(> .site-main > .try-start) > .site-footer {
  margin-top: 0;
}

/* Below 60rem a page's first section starts 24 px under the header (the spacing rule above); the
   start page ends as far above the footer, so it stays balanced on tablets and phones too. */
@media (max-width: 59.99rem) {
  .site-main > .try-start {
    padding-bottom: var(--space-12);
  }
}

/* The footnote's two lines balanced, so no word is left alone on the second. */
.try-start .try-footnote {
  text-wrap: balance;
}

/* P2-23: the bill's typed result, the one code block's figure.result ("What the agent receives"),
   under the rows. */
.try-stage .try-typed {
  margin: var(--space-8) 0 0;
}

/* The paused notice in place of Start: plain text in the text role, no edge, no box. */
.try-stage .try-notice {
  margin: 0;
  color: var(--text);
}

/* Start again after a failure posts its form: the button inside the actions' form keeps the
   stage's 44 px control height and its centred label (the stage rules give both to the form,
   the actions' child). */
.try-stage .stage-actions > form > button {
  min-height: var(--control-height);
  justify-content: center;
}

/* The script's live status ("Updating…", "Automatic updates stopped. Use Check now."). */
.try-stage .try-watch-status {
  margin: var(--space-6) 0 0;
  font-size: var(--type-sm);
  color: var(--muted);
}

.try-stage .try-watch-status:empty {
  display: none;
}

/* The waiting page: the QR card and its secondary button on a camera-ready screen (from 48rem);
   a phone gets one primary button instead. No horizontal rules. */
.try-stage .try-wide {
  display: none;
}

@media (min-width: 48rem) {
  .try-stage .try-wide {
    display: block;
  }

  .try-stage .try-phone {
    display: none;
  }
}

/* The card (design language §8 Card): surface, one 1 px edge, radius 14, padding 24. */
.try-stage .try-qr-card {
  padding: var(--space-12);
  background: var(--surface);
  border: 1px solid var(--card-edge);
  border-radius: var(--radius-lg);
  text-align: center;
}

.try-stage .try-qr-card .qr {
  display: block;
  inline-size: 16rem;
  max-inline-size: 100%;
  block-size: auto;
  margin: 0 auto;
  border-radius: var(--radius);
}

.try-stage .try-qr-card h2 {
  margin: var(--space-8) 0 0;
}

.try-stage .try-qr-line {
  margin: var(--space-4) 0 0;
  font-size: var(--type-sm);
  color: var(--text-2);
}

.try-stage .stage-body .try-wide > .stage-actions {
  margin-top: var(--space-8);
}

/* The result's record inside the stage: the plan's facts as hairline rows (a key column beside
   the text; the key above it compact), its notes, then the receipt card. */
.try-stage .try-rows {
  margin: 0;
  padding: 0;
  list-style: none;
  border-top: 1px solid var(--border);
}

.try-stage .try-rows > li {
  display: grid;
  grid-template-columns: 7rem minmax(0, 1fr);
  gap: 16px;
  margin: 0;
  padding: 14px 0;
  border-bottom: 1px solid var(--border);
}

.try-stage .try-rows .key {
  display: block;
  margin: 0;
  padding-top: 3px;
  font-size: var(--type-xs);
  font-weight: 600;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--muted);
}

.try-stage .try-rows p {
  margin: 0;
  color: var(--text-2);
}

/* The notes under the rows (the weather's sources, the bill's sample-data note) in the 13 px
   caption style (founder 2026-11-03 16:59Z fix 7), their links kept. */
.try-stage .try-fine {
  margin: var(--space-6) 0 0;
  font-size: var(--type-xs);
  line-height: 1.5;
  color: var(--muted);
}

.try-stage .try-fine p {
  margin: 0;
}

.try-stage .try-fine > * + * {
  margin-top: var(--space-4);
}

/* The receipt as one card on the table's column (founder 2026-11-03 16:59Z fix 7), the same at
   every width (full width on a phone): a 1 px card edge, 8 px radius, 20 px inside, no fill in
   light and the raised surface (`surface`, the card role) in dark; no success edge, no tint. */
.try-stage .try-receipt {
  margin: var(--space-12) 0 0;
  padding: var(--space-10);
  border: 1px solid var(--card-edge);
  border-radius: 8px;
  background: none;
}

@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) .try-stage .try-receipt {
    background: var(--surface);
  }
}

:root[data-theme="dark"] .try-stage .try-receipt {
  background: var(--surface);
}

/* The header row: "Receipt" (the result sentence's weight, at body size) on the left, the status
   pill on the right: 12 px, the success text on its soft tint ("Not verified": the status chip's
   text-2 on control-fill). */
.try-stage .try-receipt-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-6);
  margin: 0 0 var(--space-4);
}

.try-stage .stage-body .try-receipt-head h2 {
  margin: 0;
  font-size: var(--type-base);
  /* The weight the result sentence's <strong> ("A bike ride") draws (bold), per fix 7. */
  font-weight: bold;
  line-height: var(--leading-subheading);
  color: var(--text);
}

.try-stage .try-receipt-status {
  display: inline-flex;
  flex: none;
  align-items: center;
  gap: 4px;
  padding: 2px 8px;
  border-radius: 999px;
  background: var(--success-soft);
  color: var(--success);
  font-size: 0.75rem;
  font-weight: 600;
  line-height: 1.4;
}

.try-stage .try-receipt-status.try-receipt-unverified {
  background: var(--control-fill);
  color: var(--text-2);
}

.try-stage .try-receipt-check {
  flex: none;
}

.try-stage .try-receipt p {
  margin: 0 0 var(--space-4);
  color: var(--text-2);
}

.try-stage .try-receipt > :last-child {
  margin-bottom: 0;
}

/* The action row, left-aligned in the card with a 12 px gap: "Download receipt" (the primary) and
   "Data file (JSON)" (the secondary: a 1 px card edge, no fill, the text colour), both 36 px tall
   at the same type size and weight. They wrap, Download first, only where one row does not fit. */
.try-stage .try-receipt .try-receipt-actions {
  display: flex;
  flex-wrap: wrap;
  justify-content: flex-start;
  gap: var(--space-6);
  margin: var(--space-8) 0 0;
}

.try-stage .try-receipt .try-receipt-actions > .button {
  box-sizing: border-box;
  height: 2.25rem;
  min-height: 2.25rem;
  margin: 0;
  padding: 0 0.95rem;
  justify-content: center;
  font-size: var(--type-sm);
  font-weight: 600;
  line-height: 1.4;
  white-space: nowrap;
}

.try-stage .try-receipt .try-data-file,
.try-stage .try-receipt .try-data-file:hover,
.try-stage .try-receipt .try-data-file:active {
  background: none;
  border-color: var(--card-edge);
  color: var(--text);
  text-decoration: none;
}

/* "Start again" under the card: a text link, left-aligned, 24 px below it at every width (the
   stage's own actions are centred elsewhere). Past the download window, where it is the stage's
   primary, it keeps the stage's centred button. */
.try-stage .stage-body:has(> .try-receipt) + .stage-actions:has(> .stage-quiet) {
  margin-top: var(--space-12);
  justify-content: start;
  justify-items: start;
}

.try-stage .stage-body:has(> .try-receipt) + .stage-actions > .stage-quiet {
  width: auto;
  justify-content: flex-start;
  text-align: start;
  /* The 24 px is to the visible letters, not to the 44 px target around them (founder 18:10Z):
     the target's space above the line and the line's own half-leading above the letters (4 px)
     are pulled back up, so the target stays whole. */
  margin-top: calc((1lh - var(--control-height)) / 2 - 4px);
}

@media (max-width: 29.99rem) {
  .try-stage .try-rows > li {
    grid-template-columns: minmax(0, 1fr);
    gap: 4px;
  }
}

/* /demo: the steps as hairline rows; the request beside the result from 60rem. */
.section.flow .flow-steps {
  max-width: 44rem;
  margin: var(--space-16) 0 0;
  padding: 0;
  list-style: none;
  counter-reset: flow-step;
  border-top: 1px solid var(--border);
}

.section.flow .flow-steps > li {
  margin: 0;
  padding: 14px 0 14px 2.25rem;
  border-bottom: 1px solid var(--border);
  color: var(--text-2);
  counter-increment: flow-step;
  position: relative;
}

.section.flow .flow-steps > li::before {
  content: counter(flow-step);
  position: absolute;
  left: 0;
  font-weight: 600;
  color: var(--muted);
}

.flow-block {
  margin: var(--space-24) 0 0;
}

.flow-columns {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: 48px;
  max-width: none;
}

.flow-columns > section {
  min-width: 0;
}

@media (min-width: 60rem) {
  .flow-columns {
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 64px;
  }
}

@media (max-width: 59.99rem) {
  .section.flow h1 {
    font-size: 2rem;
  }

  .section.flow .flow-lead {
    font-size: var(--type-lg);
  }
}

/* Separation from the background at compact width (founder 2026-10-23 01:00Z, design language
   §4: both themes, all surfaces): at 40rem and below, the link page's phone width, the page and
   its bands are the page shade (light #f2f2f7, dark the canvas) and every card on it is the
   theme's surface with its card edge; the plan groups and the code blocks, surface-2 wider, are
   surface here. Last in the sheet, so it outranks the rules above by order. Wider, nothing
   changes. */
@media (max-width: 40rem) {
  html,
  body,
  .band {
    background: var(--page);
  }

  .plan-group dl,
  figure.code > pre,
  figure.result > pre {
    background: var(--surface);
  }
}
