/* Plumb's own stylesheet (not Tailwind, not main.css), written to read as
   a page of the site: its fonts (Monument Grotesk titles, Inter text, both
   loaded from /fonts), its slate palette and type scale, the home page's
   43rem column and its dark theme (Plumb is dark only). Served as-is from /plumb/style.css.
   The look (2026-10-01, from the user's references): a document, not a
   form. Answered rounds are flat ticked rows with hairlines between them;
   what is live (the composer, the current question, the review) sits on
   soft white cards; colour is flat and solid, one per question type. */
@font-face {
  font-family: 'eo-monument-grotesk';
  font-style: normal;
  font-weight: 500;
  font-display: swap;
  src: url('/fonts/monument/MonumentGrotesk-Medium.woff2') format('woff2');
}
@font-face {
  font-family: InterVariable;
  font-style: normal;
  font-weight: 100 900;
  font-display: swap;
  src: url('/fonts/inter/InterVariable.woff2') format('woff2');
}
:root {
  /* Plumb is dark only (the user, 2026-10-01): the site's dark theme,
     neutral black, not slate */
  color-scheme: dark;
  --bg: #0a0a0a;
  --card: #141414;
  --ink: #f5f5f5;
  --ink-soft: #a3a3a3;
  --ink-dim: #a3a3a3;
  --ink-faint: #737373;
  --line: #262626;
  --line-strong: #404040;
  --line-focus: #4a4a4a;
  --fill: rgb(38 38 38 / 0.5);
  --fill-strong: #1f1f1f;
  --shadow: 0 0 0 transparent;
  --shadow-focus: 0 0 0 transparent;
  --focus-ring: #60a5fa;
  --primary: #2563eb;    /* blue-600 */
  --primary-ink: #fff;
  --error: #f87171;
  /* Question types: --c-* fills a shape, --t-* is the same hue light
     enough to set text in on black */
  --c-why: #ebbf30;
  --c-what: #e86fc0;
  --c-how: #12b3e6;
  --c-source: #f58a3c;
  --c-falsifiable: #8b7cf6;
  --t-why: #f5cf4f;
  --t-what: #f08bd0;
  --t-how: #38bdf8;
  --t-source: #fb923c;
  --t-falsifiable: #a78bfa;
  /* The review's verdicts; no question type uses green or red */
  --c-good: #22b35e;
  --c-bad: #e5484d;
  --t-good: #4ade80;
  --t-bad: #fb7185;
  /* Motion: one entrance curve and one for things that open and close */
  --ease-out: cubic-bezier(0.22, 1, 0.36, 1);
  --ease-drawer: cubic-bezier(0.32, 0.72, 0, 1);
}
[data-type="why"] { --type-color: var(--c-why); --type-ink: var(--t-why); }
[data-type="what"] { --type-color: var(--c-what); --type-ink: var(--t-what); }
[data-type="how"] { --type-color: var(--c-how); --type-ink: var(--t-how); }
[data-type="source"] { --type-color: var(--c-source); --type-ink: var(--t-source); }
[data-type="falsifiable"] { --type-color: var(--c-falsifiable); --type-ink: var(--t-falsifiable); }

* { box-sizing: border-box; }
html, body { margin: 0; padding: 0; min-height: 100%; }
html { scrollbar-gutter: stable; }
body {
  background: var(--bg);
  color: var(--ink);
  font-family: InterVariable, BlinkMacSystemFont, -apple-system, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif;
  font-size: 16px;
  letter-spacing: -0.011em;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  display: flex;
  flex-direction: column;
  align-items: center;
  min-height: 100vh;
  min-height: 100dvh;
}
#app {
  width: 100%;
  max-width: 43rem;
  padding: 2rem 1.5rem 4rem;
  flex: 1;
}
p { margin: 0; }
.sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}
/* The one piece of site chrome: the credit, "Made by" and the site's
   logo lockup (the mark at the name's cap height) as one faint line of
   text that brightens on hover. It was a filled chip with the name in
   white semibold; the user asked for it lighter. */
.made-by {
  width: 100%;
  max-width: 43rem;
  padding: 0 1.5rem 2.5rem;
}
.made-by a {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  color: var(--ink-faint);
  font-size: 13px;
  line-height: 20px;
  text-decoration: none;
  -webkit-tap-highlight-color: transparent;
  transition: color 0.2s ease, opacity 0.12s ease;
}
.made-by a:hover { color: var(--ink-soft); }
.made-by a:active { opacity: 0.6; }
.made-by-mark {
  display: block;
  flex: none;
  width: auto;
  height: 12px;
  margin-right: -2px;
}
.made-by-name { font-weight: 500; }
:focus-visible { outline: 2px solid var(--focus-ring); outline-offset: 2px; }

/* Header: the mark and the name, and the chain's progress once it has
   started (one box per round, filled in its question type's colour) */
.top {
  display: flex;
  align-items: center;
  justify-content: space-between;
  min-height: 30px;
  margin-bottom: 3rem;
}
.brand {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  color: inherit;
  text-decoration: none;
  border-radius: 8px;
  -webkit-tap-highlight-color: transparent;
  transition: opacity 0.15s ease;
}
.brand:hover { opacity: 0.8; }
.brand:active { opacity: 0.6; }
.brand-mark { display: block; width: 30px; height: 30px; }
.brand-name {
  font-size: 16px;
  line-height: 24px;
  font-weight: 600;
  letter-spacing: -0.011em;
}
.pips { display: flex; gap: 5px; }
.pip {
  width: 10px;
  height: 10px;
  border-radius: 3px;
  border: 1.5px solid var(--line-strong);
  transition: background 0.4s ease, border-color 0.4s ease;
}
.pip.is-current { border-color: var(--type-color, var(--ink-dim)); }
/* The round just answered: its box fills with a small pop */
.pip.is-new { animation: pop 0.32s var(--ease-out) both; }
.pip.is-done {
  background: var(--type-color, var(--ink));
  border-color: var(--type-color, var(--ink));
}

/* Titles: the start screen's, and the thought once a chain is under way */
.start { animation: rise 0.4s cubic-bezier(0.22, 1, 0.36, 1); }
h1 {
  font-family: 'eo-monument-grotesk', BlinkMacSystemFont, -apple-system, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif;
  font-weight: 500;
  font-size: 24px;
  line-height: 1.25;
  letter-spacing: 0;
  margin: 0 0 8px;
}
.thought {
  white-space: pre-wrap;
  overflow-wrap: anywhere;
}
.thought.is-long {
  font-family: inherit;
  font-size: 18px;
  line-height: 1.5;
  letter-spacing: inherit;
}
/* The line under a title: words with a grey slash between them */
.meta {
  display: flex;
  flex-wrap: wrap;
  font-size: 14px;
  line-height: 20px;
  font-weight: 500;
  letter-spacing: -0.006em;
  color: var(--ink-faint);
  margin-bottom: 24px;
}
.meta-now { color: var(--ink-soft); }
.type-word { color: var(--type-ink); }
.slash { color: var(--line-strong); margin: 0 7px; }
p.lede {
  font-size: 18px;
  line-height: 1.6;
  color: var(--ink-soft);
  margin: 0 0 28px;
}

/* Cards: whatever is live on the page */
.card {
  background: var(--card);
  border: 1px solid var(--line);
  border-radius: 16px;
  box-shadow: var(--shadow);
  animation: rise 0.4s cubic-bezier(0.22, 1, 0.36, 1);
}

/* Composer: the field and its action in one card, under the question
   it answers when there is one (from Mobbin's composer cards: Notion,
   Langdock, Perplexity, and OKX's question form). The text, the question
   and the footer's first item share one left edge; the button is small
   and sits the same 8px from the card's right and bottom edges. */
.composer {
  position: relative;
  transition: border-color 0.15s ease, box-shadow 0.15s ease;
}
.composer:hover { border-color: var(--line-strong); }
/* Focus is the card's own border, one clear step darker, and a deeper
   shadow; no outer ring */
.composer:focus-within {
  border-color: var(--line-focus);
  box-shadow: var(--shadow-focus);
}
.composer-head {
  position: relative;
  padding: 20px 20px 16px;
}
/* The rule under the question starts where the question's text does
   and stops at the right margin, so the card reads as one sheet and the
   answer sits under the question it answers */
.composer-head::after {
  content: '';
  position: absolute;
  left: var(--answer-indent);
  right: 20px;
  bottom: 0;
  height: 1px;
  background: var(--line);
}
textarea {
  display: block;
  width: 100%;
  /* two lines */
  min-height: 66px;
  max-height: 40vh;
  background: transparent;
  border: none;
  color: var(--ink);
  font: inherit;
  letter-spacing: inherit;
  line-height: 24px;
  padding: 18px 20px 0;
  resize: none;
  outline: none;
}
/* An answer starts under its question's text, as it will in the list
   of answered rounds (box 18px + gap 14px past the card's 20px) */
.composer--answer { --answer-indent: 52px; }
.composer--answer textarea { padding-left: var(--answer-indent); }
/* The first field holds the thought, which becomes the page's title */
.composer--lead textarea {
  font-size: 18px;
  line-height: 28px;
  min-height: 74px;
}
/* The composer's own border shows the focus */
textarea:focus-visible { outline: none; }
::placeholder { color: var(--ink-faint); opacity: 1; }
.composer-foot {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 8px 8px 8px 20px;
}
/* The action, with its key (Enter) inside it on a keyboard and an arrow
   on a touch screen */
.composer-foot button.primary {
  margin-left: auto;
  gap: 10px;
  min-height: 40px;
  border-radius: 10px;
  padding: 8px 8px 8px 16px;
  font-size: 15px;
  line-height: 20px;
}
.btn-key {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 24px;
  height: 24px;
  border-radius: 6px;
  background: rgb(255 255 255 / 0.18);
}
button.primary:disabled .btn-key { background: rgb(255 255 255 / 0.06); }
.btn-arrow { display: none; margin-right: 6px; }
@media (hover: none) {
  .btn-key { display: none; }
  .btn-arrow { display: block; }
}
/* Hovering an example shows it in the empty field before it's chosen.
   The placeholder is drawn by this overlay (the attribute stays for
   screen readers), so one line can hand over to the next. */
.ph {
  position: absolute;
  top: 19px;
  left: 21px;
  right: 21px;
  font-size: 18px;
  line-height: 28px;
  color: var(--ink-faint);
  pointer-events: none;
  transition: opacity 0.12s ease;
}
.ph-line { display: block; text-wrap: balance; }
.ph-line + .ph-line { position: absolute; inset: 0 0 auto; }
.ph-line.is-preview { color: var(--ink-soft); }
.composer--lead textarea::placeholder { color: transparent; }
/* Gone at once when there is text: a fade let the placeholder show
   through a chosen example for a few frames */
.composer:has(textarea:not(:placeholder-shown)) .ph { opacity: 0; transition: none; }
/* Back to the previous question (or the thought): outside the card,
   under its left edge, small and faint with a chevron, so the card's one
   button keeps the focus. The user turned it down inside the card three
   times: bottom left at 14px grey with an arrow (too bold, bolder than
   the action), the card's top right, and beside the action (too close to
   it, too obvious). #858585 is the faintest grey that still reads at 5:1
   on the page. */
.back-row {
  margin-top: 8px;
  animation: fade 0.4s 0.25s both;
}
button.back {
  position: relative;
  display: inline-flex;
  align-items: center;
  gap: 3px;
  margin-left: -8px;
  padding: 6px 10px 6px 8px;
  background: none;
  border: none;
  border-radius: 8px;
  color: #858585;
  font-size: 13px;
  font-weight: 400;
}
button.back:hover { color: var(--ink-soft); background: var(--fill-strong); }
@media (pointer: coarse) {
  /* a full-size touch target without making it look any bigger */
  button.back::after { content: ''; position: absolute; inset: -6px 0; }
}
.composer--answer .composer-foot { padding-left: var(--answer-indent); }
/* What is left of the limit; empty until it is nearly reached */
.count {
  margin-right: auto;
  font-size: 13px;
  line-height: 20px;
  color: var(--ink-dim);
  font-variant-numeric: tabular-nums;
}
.count.is-out { color: var(--error); }
.notice {
  font-size: 14px;
  line-height: 20px;
  color: var(--t-source);
  margin-top: 12px;
}

button {
  font: inherit;
  letter-spacing: inherit;
  font-size: 14px;
  line-height: 20px;
  font-weight: 500;
  cursor: pointer;
  border-radius: 10px;
  padding: 8px 14px;
  -webkit-tap-highlight-color: transparent;
  transition: transform 0.12s ease, opacity 0.2s ease,
    border-color 0.2s ease, color 0.2s ease, background 0.2s ease;
}
button:active:not(:disabled) { transform: scale(0.97); }
button.primary {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  background: var(--primary);
  color: var(--primary-ink);
  border: none;
}
button.primary:hover:not(:disabled) { opacity: 0.88; }
button.primary:disabled {
  background: var(--fill-strong);
  color: var(--ink-faint);
  cursor: default;
}
button.ghost {
  background: none;
  border: 1px solid currentColor;
  color: inherit;
  padding: 7px 13px;
  flex-shrink: 0;
}
button.ghost:hover { opacity: 0.75; }
button.copy {
  margin-left: auto;
  background: none;
  border: none;
  color: var(--ink-dim);
  padding: 0 4px;
}
button.copy:hover { color: var(--ink); }

/* Examples: the thoughts themselves as outlined chips under the composer,
   three rows of three (from Mobbin: the suggestion chips under the prompt
   in Copilot, Julienne and Customer.io). They were a three by three grid
   of filled tiles with a field named above each thought, which outweighed
   the composer; now the composer is the one card on the screen, and its
   field is where a pointed-at example is read. Outlined, not filled, and
   round where the app's actions are square-cornered, so they read as
   suggestions rather than buttons. */
.examples { margin-top: 28px; }
.examples-label {
  font-size: 14px;
  line-height: 20px;
  color: #858585;
  margin-bottom: 12px;
}
.example-list { display: grid; gap: 8px; }
.example-row {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  gap: 8px;
}
/* Each row is stretched to the column's width, so the block keeps the
   composer's two edges; left ragged, three rows of nearly one length
   looked like a justify that had failed. They arrive one after another,
   just behind the page. */
.example-row li {
  flex: 1 1 auto;
  animation: rise 0.4s var(--ease-out) both;
  animation-delay: calc(var(--i) * 30ms + 90ms);
}
button.example {
  width: 100%;
  padding: 9px 14px;
  background: transparent;
  border: 1px solid var(--line);
  border-radius: 999px;
  color: var(--ink-soft);
  font-size: 15px;
  font-weight: 400;
}
@media (hover: hover) {
  button.example:hover {
    background: var(--fill-strong);
    border-color: var(--line-strong);
    color: var(--ink);
  }
}
/* The one the field holds */
button.example.is-chosen {
  border-color: var(--line-focus);
  color: var(--ink);
}
@media (pointer: coarse) {
  /* taller only: a wider chip would push a full row past the column */
  button.example { padding-block: 11px; }
}
/* Narrower than the column: the same three rows, swiped sideways and
   running off the screen's edge so the cut shows there is more. Wrapped,
   they came to seven rows, most of them one chip wide. The padding above
   and below keeps the focus ring inside the scroller. */
@media (max-width: 687px) {
  .example-list {
    grid-template-columns: minmax(max-content, 1fr);
    margin: -6px -1.5rem;
    padding: 6px 1.5rem;
    overflow-x: auto;
    overflow-y: hidden;
    scrollbar-width: none;
  }
  .example-list::-webkit-scrollbar { display: none; }
  button.example { white-space: nowrap; }
}
@media (max-width: 480px) {
  .example-list { margin-inline: -1.25rem; padding-inline: 1.25rem; }
}

/* The chain so far: each answered round a ticked row, a hairline under
   its text */
.rounds {
  list-style: none;
  margin: 0 0 8px;
  padding: 0;
}
.round {
  display: grid;
  grid-template-columns: 18px minmax(0, 1fr);
  column-gap: 14px;
}
.rounds .round { padding-top: 16px; }
.rounds .round:first-child { padding-top: 0; }
.rounds .round-body {
  padding-bottom: 16px;
  border-bottom: 1px solid var(--line);
}
.rounds .round:last-child .round-body { border-bottom: none; }
.box {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 18px;
  height: 18px;
  margin-top: 1px;
  border-radius: 5px;
  border: 1.5px solid var(--type-color, var(--line-strong));
  color: #fff;
}
.box.is-checked { background: var(--type-color, var(--ink)); }
/* The round just answered rises in and its box ticks */
.round.is-new { animation: rise 0.36s var(--ease-out) both; }
.round.is-new .box { animation: pop 0.32s 0.08s var(--ease-out) both; }
.round.is-new .box path {
  stroke-dasharray: 11;
  stroke-dashoffset: 11;
  animation: draw 0.24s 0.2s var(--ease-out) forwards;
}
/* A round the review points to, shown for a moment */
.round.is-flash .round-body { animation: flash 1.4s ease-out; }
.round-head {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px;
  margin-bottom: 4px;
}
.type-label {
  font-size: 14px;
  line-height: 20px;
  font-weight: 500;
  letter-spacing: -0.006em;
  color: var(--type-ink, var(--ink-soft));
}
.type-label::first-letter { text-transform: uppercase; }
.round-q {
  line-height: 1.6;
  color: var(--ink-dim);
  margin-bottom: 2px;
}
.round-a {
  line-height: 1.6;
  white-space: pre-wrap;
  overflow-wrap: anywhere;
}
.badge {
  font-size: 12px;
  font-weight: 500;
  line-height: 1;
  border-radius: 999px;
  padding: 4px 8px;
}
.badge-good { color: var(--t-good); background: color-mix(in srgb, var(--c-good) 14%, transparent); }
.badge-bad { color: var(--t-bad); background: color-mix(in srgb, var(--c-bad) 12%, transparent); }
.round-index {
  margin-left: auto;
  font-size: 14px;
  line-height: 20px;
  color: var(--ink-faint);
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}
.question .word {
  display: inline-block;
  animation: word-in 0.32s var(--ease-out) both;
  animation-delay: min(calc(var(--i) * 30ms + 60ms), 600ms);
}
.question {
  font-size: 18px;
  font-weight: 500;
  line-height: 1.5;
}

/* While the model reads */
.thinking { padding: 18px 20px 18px 18px; }
.thinking .box { animation: pulse 1.2s ease-in-out infinite; }
.thinking .type-label { color: var(--ink-dim); font-weight: 400; }
.thinking .round-head { margin-bottom: 14px; }
.skeleton span {
  display: block;
  height: 12px;
  border-radius: 6px;
  margin-bottom: 10px;
  background: linear-gradient(90deg, var(--fill-strong) 25%, var(--line) 50%, var(--fill-strong) 75%);
  background-size: 200% 100%;
  animation: shimmer 1.6s linear infinite;
}
.skeleton span:first-child { width: 86%; }
.skeleton span:last-child { width: 54%; margin-bottom: 4px; }

/* Care: the questions pause and a plain message takes their place */
.care { padding: 20px; outline: none; }
.care .note { color: var(--ink); }
.care-actions {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  margin-top: 16px;
}
.care-actions button.ghost {
  border-color: var(--line-strong);
  color: var(--ink-soft);
}
.care-actions button.ghost:hover {
  opacity: 1;
  border-color: var(--ink-faint);
  color: var(--ink);
}

.error-box {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  border: 1px solid color-mix(in srgb, var(--error) 35%, transparent);
  background: color-mix(in srgb, var(--error) 6%, transparent);
  color: var(--error);
  padding: 12px 12px 12px 16px;
  line-height: 1.5;
  border-radius: 16px;
  animation: rise 0.4s cubic-bezier(0.22, 1, 0.36, 1);
}

/* The review folds the answered rounds into one row at the top: their
   five colours, a label and a chevron; it opens them again in place
   (the drawer curve: a panel opening, not a page moving) */
.fold {
  margin-bottom: 8px;
  background: var(--fill);
  border-radius: 12px;
  animation: rise 0.36s var(--ease-out) both;
}
button.fold-toggle {
  display: flex;
  align-items: center;
  gap: 12px;
  width: 100%;
  min-height: 48px;
  padding: 12px 12px 12px 16px;
  background: none;
  border: none;
  border-radius: 12px;
  color: var(--ink);
  font-size: 15px;
  text-align: left;
}
button.fold-toggle:hover { background: var(--fill-strong); }
button.fold-toggle:active:not(:disabled) { transform: scale(0.99); }
.fold-pips { display: flex; gap: 4px; }
.fold-label { flex: 1; }
.fold-chevron {
  color: var(--ink-dim);
  transition: transform 0.3s var(--ease-drawer);
}
.fold.is-open .fold-chevron { transform: rotate(180deg); }
.fold-panel {
  display: grid;
  grid-template-rows: 0fr;
  opacity: 0;
  transition: grid-template-rows 0.42s var(--ease-drawer), opacity 0.24s ease;
}
.fold.is-open .fold-panel { grid-template-rows: 1fr; opacity: 1; }
.fold-inner { overflow: hidden; min-height: 0; }
.fold-inner .rounds { padding: 8px 16px 16px; margin: 0; }
/* "Round 3 · falsifiable" on a finding opens the fold at that round: a
   quiet underlined link, with a larger hit area than it looks */
button.round-link {
  position: relative;
  background: none;
  border: none;
  border-radius: 0;
  padding: 0;
  font-size: 14px;
  font-weight: 400;
  line-height: 20px;
  color: var(--ink-soft);
  text-decoration: underline;
  text-decoration-color: var(--line-strong);
  text-underline-offset: 3px;
}
button.round-link::after { content: ''; position: absolute; inset: -8px -6px; }
button.round-link:hover { color: var(--ink); text-decoration-color: currentColor; }

/* Review: one card per finding, its mark on the left */
.review .verdict,
.review .review-again {
  animation: rise 0.4s var(--ease-out) both;
  animation-delay: calc(var(--i) * 60ms + 60ms);
}
/* Its label comes in with the folded row, so the page never shows one
   without the other */
.review h2 { animation: rise 0.36s var(--ease-out) both; }
.review {
  margin-top: 28px;
  scroll-margin-top: 24px;
}
.review h2 {
  font-family: inherit;
  font-size: 14px;
  line-height: 20px;
  font-weight: 500;
  letter-spacing: -0.006em;
  color: var(--ink-soft);
  margin: 0 0 16px;
  outline: none;
}
.verdict {
  display: grid;
  grid-template-columns: 24px minmax(0, 1fr);
  column-gap: 14px;
  padding: 18px 20px 18px 18px;
  margin-bottom: 12px;
}
.verdict .round-head { min-height: 24px; }
.verdict-title {
  font-size: 16px;
  line-height: 24px;
  font-weight: 600;
}
.mark {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 24px;
  height: 24px;
  border-radius: 50%;
  color: #fff;
}
.mark-good { background: var(--c-good); }
/* The weak link: a ring left open in the middle */
.mark-open { border: 2.5px solid var(--c-bad); }
.mark-ink { background: var(--ink); color: var(--bg); }
.mark-logo { display: block; }
.gap {
  font-size: 14px;
  line-height: 20px;
  color: var(--ink-dim);
}
.gap::before { content: '· '; }
.note {
  line-height: 1.6;
  color: var(--ink-soft);
  white-space: pre-wrap;
}
.sharper-text {
  font-size: 18px;
  line-height: 1.55;
  white-space: pre-wrap;
}
.review button.primary { margin-top: 12px; min-height: 40px; padding: 10px 16px; font-size: 15px; }
@media (pointer: coarse) { .review button.primary { min-height: 44px; } }

/* Intro: the first visit in a session opens on the mark, drawn in the
   middle of the screen as one pen line through the five colours, which
   then flies into its place in the header as the page rises in (main.js
   playIntro; index.html's head script sets html.plumb-intro). While it
   plays the page is only transparent, never hidden or inert: the field
   keeps its focus and takes typing, and any key, click or scroll ends the
   intro at once. The draw is CSS so it starts with the first paint and
   also covers a slow load: the drawn mark waits until the page is ready. */
.intro { display: none; }
.plumb-intro .intro {
  display: grid;
  place-items: center;
  position: fixed;
  inset: 0;
  z-index: 10;
  pointer-events: none;
}
/* Laid out at the header mark's size and scaled up to 96px, so it lands
   at scale 1 and hands over to the header's <img> without a change */
.intro-mark {
  width: 30px;
  height: 30px;
  transform: scale(3.2);
}
.intro-mark svg { display: block; width: 100%; height: 100%; overflow: visible; }
/* One pen stroke round the closed line, the arcs end to end in question
   order: the first eases in from rest, the last eases out into the close
   (both quadratic and twice as long as the rest, so the speed matches at
   every joint), 160ms per arc in between. A 150ms beat, then 1.12s of
   drawing: unhurried, at the user's asking (it first ran in 560ms, which
   they found "too in a hurry"). The dash waits a unit
   short of each arc's start (101, with a longer gap) so no round cap
   shows as a dot before its arc begins. */
.intro-mark path {
  stroke-dasharray: 100 110;
  stroke-dashoffset: 101;
  animation: intro-draw 160ms linear both;
}
.intro-mark path:nth-of-type(1) {
  animation-delay: 150ms;
  animation-duration: 320ms;
  animation-timing-function: cubic-bezier(0.333, 0, 0.667, 0.333);
}
.intro-mark path:nth-of-type(2) { animation-delay: 470ms; }
.intro-mark path:nth-of-type(3) { animation-delay: 630ms; }
.intro-mark path:nth-of-type(4) { animation-delay: 790ms; }
.intro-mark path:nth-of-type(5) {
  animation-delay: 950ms;
  animation-duration: 320ms;
  animation-timing-function: cubic-bezier(0.333, 0.667, 0.667, 1);
}
@keyframes intro-draw { to { stroke-dashoffset: 0; } }
/* The page waits unseen under the mark (#app as a whole, so its own
   render-time rise can't show it early); the header's mark stays hidden
   until the flying one lands on it */
.plumb-intro:not(.is-docking) #app,
.plumb-intro:not(.is-docking) .made-by { opacity: 0; }
.plumb-intro .brand-mark { opacity: 0; }

@keyframes rise {
  from { opacity: 0; transform: translateY(6px); }
  to { opacity: 1; transform: translateY(0); }
}
@keyframes pop {
  from { transform: scale(0.7); }
  to { transform: scale(1); }
}
@keyframes draw {
  to { stroke-dashoffset: 0; }
}
@keyframes word-in {
  from { opacity: 0; filter: blur(4px); transform: translateY(3px); }
  to { opacity: 1; filter: blur(0); transform: none; }
}
@keyframes flash {
  from { background: color-mix(in srgb, var(--type-color, var(--ink)) 14%, transparent); }
  to { background: transparent; }
}
@keyframes pulse {
  0%, 100% { opacity: 0.35; }
  50% { opacity: 1; }
}
@keyframes shimmer {
  from { background-position: 200% 0; }
  to { background-position: 0 0; }
}
@media (prefers-reduced-motion: reduce) {
  /* Things still fade in; nothing moves, scales or blurs */
  .start, .card, .error-box, .round.is-new, .review .verdict, .review .review-again, .example-row li {
    animation-name: fade;
  }
  .skeleton span, .thinking .box, .pip.is-new, .round.is-new .box { animation: none; }
  .question .word { animation: none; }
  .round.is-new .box path { animation: none; stroke-dashoffset: 0; }
  .fold-panel, .fold-chevron { transition: none; }
  .pip, button, .composer, .ph, .made-by a { transition: none; }
}
@keyframes fade {
  from { opacity: 0; }
}
/* Phones: a little less padding inside the cards so the text keeps its
   width, larger touch targets, and room for the home indicator */
@media (max-width: 480px) {
  #app { padding: 1.25rem 1.25rem 3rem; }
  .top { margin-bottom: 2rem; }
  .composer-head { padding: 16px 16px 14px; }
  .composer-head { column-gap: 12px; }
  textarea { padding: 16px 16px 0; }
  .composer-foot { padding: 8px 8px 8px 16px; }
  .composer--answer { --answer-indent: 46px; }
  .ph { top: 17px; left: 17px; right: 17px; }
  .verdict { padding: 16px; column-gap: 12px; }
  .made-by { padding: 0 1.25rem max(2rem, env(safe-area-inset-bottom)); }
}
@media (pointer: coarse) {
  .composer-foot button.primary { min-height: 44px; }
}
