/*
 * No CDN, no build step, no webfonts.
 *
 * The reference mockup pulled Tailwind from cdn.tailwindcss.com, which ships a
 * compiler to every visitor and is explicitly not for production, plus three
 * Google font families of which one was never used. A marketing page for a
 * texting product should load instantly on a phone on stadium wifi.
 *
 * The system font stack also removes a third-party request — which matters
 * here, because the privacy policy on this same site promises we do not hand
 * visitor data to anyone.
 */

:root {
  --carbon: #121212;
  --surface: #1c1c1c;
  --raised: #242424;
  --line: #2d2d2d;
  --turf: #21a366;
  --turf-dim: #17724a;
  /* Waiting-on-you amber. Distinct from the error red so an unfinished step
     never reads as a failure. */
  --amber: #d9a13b;
  --amber-dim: #4a3a12;
  --text: #f4f5f6;
  --muted: #9b9b9b;
  --radius: 10px;
  --sans: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
  --mono: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, monospace;
  /* Numerals only, nowhere else. A serif italic against the sans gives the step
     list a second voice without a webfont, and this site cannot load one: zero
     external requests is a property the privacy policy depends on. */
  --serif: Georgia, "Times New Roman", Times, serif;
}

* { box-sizing: border-box; }

body {
  margin: 0;
  background: var(--carbon);
  color: var(--text);
  font-family: var(--sans);
  font-size: 17px;
  line-height: 1.65;
  -webkit-font-smoothing: antialiased;
}

a { color: var(--turf); text-decoration: none; }
a:hover { text-decoration: underline; }

/* Visible focus everywhere. The reference used <a href="#"> with onclick
   handlers, which is unreachable by keyboard and invisible to screen readers. */
:focus-visible { outline: 2px solid var(--turf); outline-offset: 3px; border-radius: 3px; }

.wrap { max-width: 940px; margin: 0 auto; padding: 0 24px; }
.narrow { max-width: 680px; }

/* ---------------------------------------------------------------- nav ---- */
nav {
  border-bottom: 1px solid var(--line);
  position: sticky; top: 0; z-index: 20;
  background: rgba(18,18,18,.92);
  backdrop-filter: saturate(140%) blur(8px);
}
nav .wrap { display: flex; align-items: center; justify-content: space-between; height: 66px; gap: 16px; }
/*
 * The lockup: wordmark, then the bubble. That order is the whole joke, it reads
 * as "Commish is typing".
 *
 * Both halves are inline SVG. The wordmark is COMMISH outlined from Chakra Petch
 * Bold Italic, so the typeface never loads and the -10 degree lean is the real
 * designed italic rather than a skew. See website/logo.svg for provenance.
 */
.brand { display: flex; align-items: center; gap: 9px; color: var(--text); }
.brand:hover { text-decoration: none; }
.brand-word { display: block; height: 17px; }
.brand-word svg { height: 100%; width: auto; display: block; fill: currentColor; }
/*
 * The mark is the bot's own typing bubble, not a lettered tile.
 *
 * Inline SVG rather than an <img> or an icon font: this site makes zero
 * external requests, and inline also lets the shape inherit colour. It is a
 * rounded path and three circles, so it costs a few hundred bytes and stays
 * sharp at any size, including the 16px favicon where a letter would mush.
 *
 * The bubble is WIDER than it is tall, so the old 28px square would have
 * squashed it. Height is what has to match the bar, not width.
 */
/* Sized against the wordmark rather than the bar: in the lockup the bubble
   sits a little under cap height so the name leads and the mark answers. */
.mark { display: block; height: 21px; flex: none; }
.mark svg { height: 100%; width: auto; display: block; fill: var(--turf); }
.mark .dots { fill: #06130c; }
nav ul { display: flex; align-items: center; gap: 22px; list-style: none; margin: 0; padding: 0; font-size: .93rem; }
nav ul a { color: var(--muted); font-weight: 600; }
nav ul a:hover { color: var(--text); text-decoration: none; }

/* The persistent call to action.
 *
 * The bar is sticky, so this is the only CTA that is on screen for the whole
 * page. Before it existed, 57% of the home page had nothing to click: two
 * signup links, at screen 0.7 and 5.3 of 7.9.
 *
 * Smaller than a body button on purpose. At .btn's normal 13px/24px padding it
 * out-weighed the wordmark and the bar read as a banner ad. */
.btn.nav-cta { padding: 8px 15px; font-size: .87rem; white-space: nowrap; }
.btn.nav-cta:hover { color: #06130c; }

/* -------------------------------------------------------------- type ---- */
h1 { font-size: clamp(2.1rem, 5.5vw, 3.4rem); line-height: 1.08; letter-spacing: -.032em; font-weight: 800; margin: 0 0 20px; }
h2 { font-size: clamp(1.4rem, 3vw, 1.85rem); letter-spacing: -.02em; font-weight: 750; margin: 0 0 14px; }
h3 { font-size: 1.06rem; font-weight: 700; margin: 0 0 8px; }
p { margin: 0 0 18px; }
.lede { font-size: clamp(1.05rem, 2.2vw, 1.22rem); color: var(--muted); max-width: 62ch; }
.eyebrow { font-size: .74rem; text-transform: uppercase; letter-spacing: .14em; font-weight: 700; color: var(--turf); margin-bottom: 14px; }
.muted { color: var(--muted); }
.small { font-size: .88rem; }

section { padding: 76px 0; }
section + section { border-top: 1px solid var(--line); }

/* ------------------------------------------------------------ buttons ---- */
.btn {
  display: inline-block; padding: 13px 24px; border-radius: var(--radius);
  background: var(--turf); color: #06130c; font-weight: 700; font-size: .97rem;
  border: 1px solid var(--turf);
  /* No-op while a button is auto-width. Load-bearing the moment one is
     stretched to fill its container, which is what happens on mobile. */
  text-align: center;
}
.btn:hover { background: #26bd76; text-decoration: none; }
.btn.ghost { background: transparent; color: var(--text); border-color: var(--line); }
.btn.ghost:hover { background: var(--raised); border-color: var(--muted); }

/* ------------------------------------------------------------ steps ------ */
/*
 * The onboarding list. Vertical and boxless on purpose.
 *
 * This was three tiles across, which was the THIRD three-across grid on the
 * page: features, then these, then pricing. Each was fine alone and together
 * they gave the whole page one rhythm that repeated. A vertical list breaks the
 * cadence without touching the other two sections, which both have a real claim
 * to a row: pricing is compared horizontally, and these steps are read down.
 *
 * No cards, no arrows. The numbers carry the sequence, so a border around each
 * step would only be decoration competing with them.
 */
.steps { list-style: none; margin: 0; padding: 0; }

.steps li {
  display: grid;
  grid-template-columns: 44px 1fr;
  align-items: start;
  margin-bottom: 46px;
}
.steps li:last-child { margin-bottom: 0; }

.step-n {
  font-family: var(--serif);
  font-style: italic;
  font-size: 1.15rem;
  color: var(--muted);
  /* Nudged to sit against the cap height of the title rather than its box. */
  line-height: 1.85;
}

.steps h3 { margin: 0 0 6px; font-size: 1.2rem; }
.steps p { margin: 0; color: var(--muted); max-width: 48ch; }

@media (max-width: 620px) {
  .steps li { grid-template-columns: 32px 1fr; margin-bottom: 38px; }
}

/* --------------------------------------------------------- chat mockup ---- */
/*
 * Every message below is the bot's real output format, produced by the code in
 * src/. Team names are substituted — the actual league's names belong in the
 * group chat, not on a public page.
 */
.thread {
  background: var(--surface); border: 1px solid var(--line);
  border-radius: 14px; overflow: hidden; margin-top: 44px;
}
.thread-bar {
  display: flex; justify-content: space-between; align-items: center; gap: 12px;
  padding: 12px 18px; border-bottom: 1px solid var(--line);
  font-size: .76rem; font-weight: 700; color: var(--muted);
  text-transform: uppercase; letter-spacing: .09em; background: var(--carbon);
}
.thread-bar .live { color: var(--turf); }
.msgs { padding: 24px 20px; display: flex; flex-direction: column; gap: 20px; }
.msg { max-width: 84%; }
.msg .who { font-size: .72rem; font-weight: 700; color: var(--muted); text-transform: uppercase; letter-spacing: .07em; margin-bottom: 6px; }
.bubble { padding: 13px 17px; border-radius: 17px; background: var(--raised); border-radius: 17px 17px 17px 5px; white-space: pre-line; }
.msg.bot { align-self: flex-end; }
.msg.bot .who { color: var(--turf); text-align: right; }
.msg.bot .bubble { background: var(--turf-dim); border: 1px solid var(--turf); border-radius: 17px 17px 5px 17px; }
.bubble.mono { font-family: var(--mono); font-size: .87rem; line-height: 1.55; }

/* ------------------------------------------------------------- cards ---- */
.grid { display: grid; gap: 18px; grid-template-columns: repeat(auto-fit, minmax(268px, 1fr)); }
.card { background: var(--surface); border: 1px solid var(--line); border-radius: var(--radius); padding: 24px; }
.card h3 { color: var(--text); }
.card p { margin: 0; color: var(--muted); font-size: .95rem; }

.price {
  background: var(--surface); border: 1px solid var(--line);
  border-radius: var(--radius); padding: 30px;
  /* Column + auto margin on the button so the two calls to action sit on
     the same line regardless of how many bullets each plan has. */
  display: flex; flex-direction: column;
}
.price .btn { margin-top: auto; }
.price.feature { border-color: var(--turf); }
.price .amount { font-size: 2.6rem; font-weight: 800; letter-spacing: -.03em; }

/* The legal fine print under the price tiles.
 *
 * Centred and capped rather than left aligned and full width. Left aligned it
 * read as the start of a new paragraph of body copy; centred under the tiles it
 * reads as a footnote belonging to them, which is what it is. The cap keeps the
 * line length short enough that centring does not produce a ragged block. */
.fine-print { margin: 26px auto 0; text-align: center; max-width: 68ch; }
.price ul { list-style: none; padding: 0; margin: 20px 0 26px; }
.price li { padding-left: 26px; position: relative; margin-bottom: 11px; font-size: .95rem; }
.price li::before { content: "✓"; position: absolute; left: 0; color: var(--turf); font-weight: 700; }

/* --------------------------------------------------------- legal pages ---- */
.legal { padding: 56px 0 88px; }
.legal h2 { margin-top: 40px; font-size: 1.25rem; }
.legal h3 { margin-top: 26px; }
.legal ul { padding-left: 22px; }
.legal li { margin-bottom: 9px; }
.legal table { width: 100%; border-collapse: collapse; margin: 18px 0; font-size: .93rem; }
.legal th, .legal td { text-align: left; padding: 10px 12px; border-bottom: 1px solid var(--line); vertical-align: top; }
.legal th { color: var(--muted); font-size: .78rem; text-transform: uppercase; letter-spacing: .08em; }

/* Anything the operator must replace before this site goes live. Deliberately
   loud: a placeholder that ships unnoticed is worse than a missing page. */
.todo {
  background: #3a2a00; border: 1px solid #8a6a00; color: #ffd98a;
  padding: 2px 7px; border-radius: 4px; font-family: var(--mono);
  font-size: .84rem; font-weight: 700;
}

.callout { background: var(--surface); border: 1px solid var(--line); border-left: 3px solid var(--turf); border-radius: 0 var(--radius) var(--radius) 0; padding: 18px 22px; margin: 22px 0; }
.callout p:last-child { margin-bottom: 0; }

kbd { font-family: var(--mono); background: var(--raised); border: 1px solid var(--line); border-radius: 4px; padding: 1px 7px; font-size: .87em; }

/* ------------------------------------------------------- onboarding ---- */
.step { margin-top: 34px; }
.field-label { display: block; font-size: .78rem; text-transform: uppercase; letter-spacing: .1em; font-weight: 700; color: var(--muted); margin-bottom: 9px; }
.row { display: flex; gap: 10px; flex-wrap: wrap; align-items: center; }
.row > .btn { flex-shrink: 0; }

/* Include tel: a phone field left out of this list falls back to the
   browser default, which is a white box in the middle of a dark form. */
input[type="text"], input[type="email"], input[type="tel"] {
  flex: 1 1 240px; min-width: 0;
  background: var(--carbon); color: var(--text);
  border: 1px solid var(--line); border-radius: var(--radius);
  padding: 13px 15px; font-size: 1rem; font-family: inherit;
}
input:focus { border-color: var(--turf); }
input::placeholder { color: #6b6b6b; }

.msg-line { min-height: 1.4em; margin: 10px 0 0; font-size: .92rem; color: var(--muted); }
.msg-line.err { color: #ff8f7a; }
.msg-line.ok { color: var(--turf); }

.league-list { display: grid; gap: 10px; margin: 18px 0 22px; }
.league-card {
  display: flex; flex-direction: column; gap: 4px; text-align: left; width: 100%;
  background: var(--surface); color: var(--text);
  border: 1px solid var(--line); border-radius: var(--radius);
  padding: 15px 18px; cursor: pointer; font: inherit;
}
.league-card:hover { border-color: var(--turf); background: var(--raised); }
.lg-name { font-weight: 700; font-size: 1.02rem; }
.lg-meta { font-size: .84rem; color: var(--muted); }

.picked { background: var(--surface); border: 1px solid var(--turf); border-radius: var(--radius); padding: 18px 20px; display: flex; flex-direction: column; gap: 4px; }
.picked strong { font-size: 1.12rem; }

.sms-card { background: var(--surface); border: 1px solid var(--line); border-radius: var(--radius); padding: 22px; margin: 18px 0 6px; }
.sms-to { display: flex; align-items: baseline; gap: 10px; margin-bottom: 14px; flex-wrap: wrap; }
.sms-to strong { font-family: var(--mono); font-size: 1.2rem; letter-spacing: .04em; }
.sms-body {
  font-family: var(--mono); font-size: 1.05rem; background: var(--carbon);
  border: 1px dashed var(--line); border-radius: var(--radius);
  padding: 15px 18px; margin-bottom: 16px; word-break: break-all;
}

/* ------------------------------------------------------------ footer ---- */
footer { border-top: 1px solid var(--line); padding: 40px 0 56px; color: var(--muted); font-size: .89rem; }
footer .wrap { display: flex; flex-wrap: wrap; gap: 14px 26px; justify-content: space-between; align-items: center; }
footer nav { border: 0; position: static; background: none; backdrop-filter: none; }
footer ul { display: flex; gap: 20px; list-style: none; margin: 0; padding: 0; flex-wrap: wrap; }

@media (max-width: 620px) {
  section { padding: 54px 0; }
  /* Links must not wrap: a two-line "How it works" shoves the logo off-centre
     and makes the bar look broken on a phone, which is where this is read. */
  nav ul { gap: 12px; font-size: .85rem; }
  nav ul a { white-space: nowrap; }
  /* The button is the widest thing in the bar once the wordmark goes, so it
     gives up padding before any link gives up its place. */
  .btn.nav-cta { padding: 7px 12px; font-size: .82rem; }
  .msg { max-width: 95%; }
  .legal table, .legal td, .legal th { display: block; }
  .legal th { border: 0; padding-bottom: 2px; }
  .legal td { padding-top: 0; }
  .legal td:first-of-type { font-weight: 700; color: var(--text); padding-bottom: 2px; border: 0; }
}

/* There used to be a rule here hiding the first header link below 440px, back
   when the bar carried Features / Pricing / Messaging and could not fit the
   wordmark too. The messaging disclosures moved to their own page, the bar went
   down to two links, and the rule inverted into hiding Features and leaving
   Pricing alone in the nav.

   A third link is now back: FAQ. It was MEASURED rather than assumed, which is
   the whole point of this note. At 320px, the narrowest phone worth supporting,
   the bar is wordmark 110 + links 163 = 273 of 320, one line, 46px spare. At
   375px it has 101px spare. FAQ fits where Messaging never could because it is
   28px wide against roughly 90.

   So: no display:none, and if a FOURTH link is ever proposed, measure at 320
   first. If one has to go, scope the selector to `body > nav` — the original
   rule matched `nav ul li:first-child`, which also hits the FOOTER, where it
   silently dropped a legal link that has to stay reachable for carrier
   registration. */
/* 480, not 440. Measured: with the wordmark showing, the bar needs 457px, so
   the old 440 left a 17px band where it wrapped. The outlined wordmark is wider
   than the text it replaced, 154px against 110, and it outran its own
   breakpoint. Re-measure this if the wordmark or the links ever change. */
@media (max-width: 480px) {
  /* Below this the bar cannot hold wordmark + three links + the button. The
     WORDMARK is what gives way, not a link and not the button.
     Measured at 320px: mark 28 + links 164 + button ~95 + gaps leaves the row
     fitting, where keeping "Commish" needs another 80px it does not have.
     The mark still says who this is and still links home, so nothing is lost
     that a visitor can act on. Dropping a nav link instead would hide
     navigation to buy 80px, which is the trade the old rule here got wrong. */
  .brand-word { display: none; }
  /* With the wordmark gone the bubble is the entire brand, so it takes the
     space the wordmark vacated rather than sitting there looking incidental. */
  .mark { height: 26px; }
}

/* --------------------------------------------------- commissioner app ---- */
.view { margin-top: 8px; }

/* The roster table. Grid rather than <table> so it can restack on a phone —
   a commissioner will do this sitting on the couch, not at a desk. */
.roster-table { display: grid; gap: 10px; margin: 22px 0; }
/* One card per team, one row per person on it. A team can be co-managed, and a
   co-owner whose number is missing is invisible to the bot. */
.roster-team {
  background: var(--surface); border: 1px solid var(--line);
  border-radius: var(--radius); padding: 12px 14px;
  display: flex; flex-direction: column; gap: 10px;
}
.rt-head { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
/* The username leads. Team names are jokes and change mid-season; the username
   is what a commissioner can actually match to a person. */
.rt-head strong { font-size: .98rem; overflow-wrap: anywhere; }
.rt-owners { display: flex; flex-direction: column; gap: 8px; }

.rr-owner {
  display: grid; gap: 10px; align-items: center;
  grid-template-columns: 1fr 1fr 32px;
}
.rr-owner input { flex: none; width: 100%; padding: 10px 12px; font-size: .95rem; }
/* The primary owner has no remove button, but its row still reserves that
   column so the fields line up with the co-owners underneath. That comes free
   from the rule above — an attribute-scoped copy of it looked harmless and was
   not: it out-specified the mobile media query below, so the primary row kept
   the desktop grid on a phone and its number field came out half width. */

.rr-remove {
  width: 32px; height: 32px; padding: 0; line-height: 1;
  font-size: 1.15rem; border-radius: var(--radius);
  background: transparent; border: 1px solid var(--line);
  color: var(--muted); cursor: pointer;
}
.rr-remove:hover { color: var(--text); border-color: var(--muted); }

.rt-add {
  align-self: flex-start; padding: 6px 10px; font-size: .85rem;
  background: transparent; border: 1px dashed var(--line);
  border-radius: var(--radius); color: var(--muted); cursor: pointer;
}
.rt-add:hover { color: var(--text); border-color: var(--muted); }

@media (max-width: 640px) {
  /* The remove control keeps its own column on a phone — collapsing it to full
     width puts a destructive button directly under the number field. */
  .rr-owner { grid-template-columns: 1fr 32px; }
  .rr-owner .rr-name { grid-column: 1 / -1; }
}

/* The waiting state for "add me to your group chat". It has to look alive —
   a static message reads as broken while someone waits on it. */
.waiting {
  display: flex; gap: 15px; align-items: flex-start;
  background: var(--surface); border: 1px solid var(--line);
  border-left: 3px solid var(--turf);
  border-radius: 0 var(--radius) var(--radius) 0; padding: 18px 20px; margin: 20px 0;
}
.waiting .pulse {
  width: 11px; height: 11px; border-radius: 50%; background: var(--turf);
  margin-top: 6px; flex-shrink: 0; animation: pulse 1.6s ease-in-out infinite;
}
.waiting.done .pulse { animation: none; }
@keyframes pulse { 0%, 100% { opacity: 1; transform: scale(1); } 50% { opacity: .35; transform: scale(.8); } }
/* Respect people who have asked the OS to stop moving things. */
@media (prefers-reduced-motion: reduce) { .waiting .pulse { animation: none; } }

input[type="range"] { accent-color: var(--turf); }

/* The signup card: message, number, and a QR side by side. */
.sms-lead { display: flex; gap: 22px; align-items: center; justify-content: space-between; flex-wrap: wrap; }
.sms-number { font-family: var(--mono); font-size: 1.35rem; font-weight: 700; letter-spacing: .04em; margin: 4px 0 12px; }
.sms-card .sms-body { font-size: 1.25rem; font-weight: 700; letter-spacing: .06em; margin: 6px 0 14px; }
.qr { margin: 0; text-align: center; flex-shrink: 0; }
.qr svg { display: block; width: 150px; height: 150px; }
.qr figcaption { margin-top: 6px; }
/* On a phone the QR is useless — you cannot scan the screen you are holding. */
@media (max-width: 560px) { .qr { display: none; } }

/* Pending -> confirmed.
   Amber while it is waiting on the visitor, green once the text lands. Starting
   green gives away the ending and makes the change invisible; amber says "your
   move" without implying anything is broken. */
.sms-card { border-left: 3px solid var(--line); transition: border-color .35s ease; }
.sms-card.pending { border-left-color: var(--amber); }
.sms-card.done { border-left-color: var(--turf); }

.sms-status {
  display: flex; gap: 13px; align-items: flex-start;
  margin-top: 18px; padding-top: 16px;
  border-top: 1px solid var(--line);
}
.sms-status .pulse { background: var(--amber); margin-top: 5px; }
.sms-status.done .pulse { background: var(--turf); }
.sms-status.done strong { color: var(--turf); }

.waiting .pulse { background: var(--amber); }
.waiting.done { border-left-color: var(--turf); }
.waiting.done .pulse { background: var(--turf); }

.pulse.check {
  color: #06130c;
  width: 22px; height: 22px; margin-top: 1px;
  display: grid; place-items: center;
  font-size: .78rem; font-weight: 900; line-height: 1;
  animation: none;
}

/* ============================================================== hero ==== */
/*
 * Copy left, phone right. The frame is drawn in CSS rather than pulled from a
 * device-frame library: every such library ships forty device variants to use
 * one, and this site makes zero external requests — a property the privacy
 * policy on it depends on.
 */
.hero { padding-bottom: 64px; }
.hero-grid { display: grid; gap: 54px; grid-template-columns: 1fr; align-items: start; }

@media (min-width: 900px) {
  .hero-grid { grid-template-columns: minmax(0, 1.05fr) 330px; gap: 60px; align-items: center; }
  .hero-copy .lede { max-width: 46ch; }
}

/* The two calls to action. Flex with a gap rather than a margin on the second
   button: a margin only describes the space between them on ONE line, so when
   the pair wrapped it left them touching vertically and indented the second one
   by the 8px meant to separate them horizontally. */
.hero-actions { display: flex; flex-wrap: wrap; gap: 12px; margin-top: 30px; }

.hero-phone { display: flex; justify-content: center; }

.phone { width: 320px; max-width: 100%; }
.phone-bezel {
  background: #000;
  border-radius: 42px;
  padding: 11px 11px 8px;
  border: 1px solid #2f2f2f;
  /* A soft outer glow reads as a screen in a dark room rather than a sticker. */
  box-shadow: 0 26px 60px rgba(0,0,0,.65), 0 0 0 1px rgba(255,255,255,.04) inset;
}
.phone-screen {
  background: var(--carbon);
  border-radius: 33px;
  overflow: hidden;
  display: flex; flex-direction: column;
  /* Capped so a long recap cannot make the column absurdly tall. The thread
     scrolls inside, which is what a real chat does anyway. */
  height: 560px;
}

.phone-status {
  display: flex; align-items: center; justify-content: space-between;
  padding: 11px 22px 7px;
  font-size: .74rem; font-weight: 700; color: var(--text);
}
.phone-island {
  width: 78px; height: 20px; border-radius: 12px; background: #000;
  margin: 0 auto;
}
.phone-meters { display: flex; align-items: center; color: var(--text); }

.phone-screen .thread-bar { border-radius: 0; }
.phone-screen .msgs {
  flex: 1; overflow-y: auto; scrollbar-width: none;
  padding: 18px 14px;
}
.phone-screen .msgs::-webkit-scrollbar { display: none; }
.phone-screen .msg { max-width: 92%; }
.phone-screen .bubble { font-size: .84rem; padding: 10px 13px; }
.phone-screen .who { font-size: .62rem; }

.phone-home {
  width: 120px; height: 5px; border-radius: 3px;
  background: #3a3a3a; margin: 9px auto 4px;
}

/* Below this a phone drawn inside a phone wastes width and looks strange, so
   the frame is dropped and the bare thread stands on its own. */
@media (max-width: 620px) {
  /* Stack the pair and let them stretch, so they are the same width instead of
     266px next to 144px. Same breakpoint as the frame above deliberately: the
     hero has one mobile mode, not two that drift apart. */
  .hero-actions { flex-direction: column; }

  .phone-bezel { background: none; border: 0; padding: 0; box-shadow: none; }
  /* A FIXED height, not auto with a max. Pending messages are display:none, so
     an auto-height thread starts one message tall and grows with every arrival,
     shoving the rest of the page down eight times while someone is reading it.
     Reserving the full height up front costs nothing: the thread is already
     bottom-anchored, so it fills upward into space it was always going to use. */
  .phone-screen { height: 520px; border-radius: 14px; border: 1px solid var(--line); }
  .phone-status, .phone-home { display: none; }
  .phone { width: 100%; }
}

/* ---- reveal ---- */
/*
 * Messages arrive one at a time when the thread scrolls into view, then stay.
 * Deliberately not a loop: a conversation that restarts while someone is
 * reading the recap is actively hostile, and the recap is the best thing on
 * the page.
 */
/* display:none, not opacity:0. An invisible message still occupies layout, so
   the thread was always full height — which meant it could never sit at the
   bottom of the screen and margin-top:auto never applied. Out of flow, the
   conversation grows the way a real one does. */
.msgs .msg.pending { display: none; }
.msgs .msg.arrive { animation: arrive .34s cubic-bezier(.2,.7,.3,1) forwards; }
@keyframes arrive { from { opacity: 0; transform: translateY(10px); } to { opacity: 1; transform: none; } }

.typing { display: flex; gap: 4px; align-items: center; padding: 13px 15px; }
.typing i {
  width: 6px; height: 6px; border-radius: 50%; background: var(--muted);
  animation: blink 1.25s infinite ease-in-out;
}
.typing i:nth-child(2) { animation-delay: .18s; }
.typing i:nth-child(3) { animation-delay: .36s; }
@keyframes blink { 0%, 60%, 100% { opacity: .25; } 30% { opacity: 1; } }

/* Someone who asked their OS to stop moving things should still get the pitch.
   Everything visible, immediately, no stagger and no dots. */
@media (prefers-reduced-motion: reduce) {
  .msgs .msg.pending { display: block; }
  .msgs .msg.arrive { animation: none; }
  .typing { display: none; }
}

/* Bottom-anchor the thread.
   A chat starts at the bottom of the screen and grows upward — a short
   conversation pinned to the top of an empty panel reads as a document, not a
   conversation. margin-top:auto on the first message rather than
   justify-content:flex-end, which clips the top of overflowing content. */
.phone-screen .msgs > .msg:first-child { margin-top: auto; }

/* --------------------------------------------------------------- faq ----- */
/*
 * <details>, not a JS accordion. It is keyboard operable, screen readers
 * announce the expanded state on their own, ctrl-F still finds text inside a
 * closed answer in most browsers, and it works with JavaScript off, which is
 * the same reason the legal pages substitute their tokens server side.
 *
 * Deliberately NOT using <details name> to make it exclusive. Closing the
 * answer someone is halfway through reading because they opened another one is
 * a worse experience than two being open at once.
 */
.faq-item { border-bottom: 1px solid var(--line); }
.faq-item:first-of-type { border-top: 1px solid var(--line); }

.faq-item summary {
  cursor: pointer;
  padding: 20px 40px 20px 0;
  font-weight: 700;
  font-size: 1.02rem;
  position: relative;
  /* Both are needed: the second is the only thing that removes the disclosure
     triangle in Safari, and the first covers everyone else. */
  list-style: none;
}
.faq-item summary::-webkit-details-marker { display: none; }
.faq-item summary:hover { color: var(--turf); }
.faq-item summary:focus-visible { outline: 2px solid var(--turf); outline-offset: 3px; border-radius: 4px; }

/* Chevron, drawn rather than typed so it cannot render as a missing glyph. */
.faq-item summary::after {
  content: ''; position: absolute; right: 6px; top: 50%;
  width: 8px; height: 8px;
  border-right: 2px solid var(--muted);
  border-bottom: 2px solid var(--muted);
  transform: translateY(-70%) rotate(45deg);
  transition: transform .18s ease;
}
.faq-item[open] summary::after { transform: translateY(-20%) rotate(-135deg); }
.faq-item[open] summary { color: var(--text); }

.faq-item p { margin: 0 0 22px; color: var(--muted); max-width: 68ch; }

@media (prefers-reduced-motion: reduce) {
  .faq-item summary::after { transition: none; }
}

/* The email alternative on the signup screen. Collapsed by default — texting is
   the better path and should stay the obvious one. */
.alt-signup { margin: 22px 0 8px; }
.alt-signup summary { cursor: pointer; color: var(--muted); font-size: .93rem; }
.alt-signup summary:hover { color: var(--text); }
.alt-signup[open] summary { color: var(--text); }

/* The product name in the headline. Colour is emphasis only — the sentence
   reads identically without it, so nothing is carried by colour alone. */
.brand-accent { color: var(--turf); }


/* Onboarding step 3 — the names the bot answers to. Chips rather than a
   comma-separated text box, because the old text box was on the settings screen
   behind the dashboard and nobody found it until the bot had already ignored
   somebody. */
.name-chips { display: flex; flex-wrap: wrap; gap: 8px; margin-bottom: 16px; }
.chip {
  padding: 9px 16px; font-size: .95rem; font-weight: 500;
  border-radius: 999px; cursor: pointer;
  background: var(--surface); border: 1px solid var(--line); color: var(--muted);
  /* A tap target, not a link. 40px keeps it thumb-sized on a phone. */
  min-height: 40px;
}
.chip:hover { color: var(--text); border-color: var(--muted); }
.chip.on {
  background: var(--turf); border-color: var(--turf);
  color: var(--ink, #0b0f0d);
}
/* Selected state must not rest on colour alone — a check reads the same to
   anybody who cannot separate the green from the grey. */
.chip.on::before { content: "\2713\00a0"; }

.name-add { display: flex; gap: 8px; align-items: center; }
.name-add input { flex: 1; min-width: 0; padding: 10px 12px; font-size: .95rem; }

@media (max-width: 640px) {
  .name-add { flex-wrap: wrap; }
  .name-add input { flex: 1 1 100%; }
}

/* Onboarding step 3 — how hard the bot punches. Cards rather than a slider:
   the settings screen offered an unlabelled 0-2 range, which asked people to
   guess what the numbers meant. */
.tone-picker { display: grid; gap: 10px; grid-template-columns: repeat(3, 1fr); }
.tone {
  display: flex; flex-direction: column; gap: 4px; text-align: left;
  padding: 14px; border-radius: var(--radius); cursor: pointer;
  background: var(--surface); border: 2px solid var(--line); color: inherit;
  font: inherit; min-height: 92px;
}
.tone:hover { border-color: var(--muted); }
.tone.on { border-color: var(--turf); }
.tone strong { font-size: .98rem; }
.tone span { font-size: .82rem; color: var(--muted); line-height: 1.35; }
.tone.on span { color: var(--text); }

@media (max-width: 640px) {
  /* Stacked, so a three-line blurb does not squeeze into a 100px column. */
  .tone-picker { grid-template-columns: 1fr; }
  .tone { min-height: 0; }
}
