/* Shared styles for every page of the marketing site: tokens, the header,
   the rows, buttons, the signup area, the tile extras and the footer. Loaded
   after skin.css (the app's tokens and the tile chrome) and before a page's
   own stylesheet (home.css for the home page).

   Split from the style block of the chosen mockup,
   mockups/playground-checklist/04-corner-card.html, on 2026-09-25. Rules keep
   the mockup's order inside this file; a page's own file comes after it, so a
   page rule that overrides one here (.play over .row) still wins.

   Sizes and the page's layout rules (one container, one split, one type
   scale) are described at the top of home.css. */

/* ── Fonts: metric-matched fallbacks ────────────────────────────────────── */
/* While Montserrat is still on its way the page is set in Arial, scaled and
   spaced to take Montserrat's room: size-adjust makes the letters as wide on
   average, and the ascent, descent and line-gap overrides make each line as
   tall. So when the real face arrives the headline keeps its line breaks and
   nothing below it moves. One face per weight Montserrat ships, each against
   the Arial cut nearest it (Arial for 400 and 500, Arial Bold for 700 and
   900). Liberation Sans is Arial's metric twin on Linux.
   The overrides are Montserrat's own metrics (ascent 968, descent 251, no
   line gap, per 1000) divided by size-adjust. size-adjust started from
   @capsizecss/metrics (each face's average letter width, weighted by English
   letter frequency) and was then tuned on 2026-09-25 so the home page's own
   text, weight by weight, sets as wide in Arial as in Montserrat (to within
   0.2%). Measured in Chromium with the fonts held back 2.5 s: at 390 wide
   the headline kept its four lines and nothing moved (without these faces it
   set in three lines, then broke to four and pushed the board down 36px:
   CLS 0.0344, against 0 with them); at 1440, CLS 0.0029 without and 0.0001
   with. */
@font-face {
  font-family: "Montserrat Fallback"; font-style: normal; font-weight: 400;
  src: local("Arial"), local("ArialMT"), local("Liberation Sans"), local("LiberationSans");
  size-adjust: 111.53%; ascent-override: 86.79%; descent-override: 22.50%; line-gap-override: 0%;
}
@font-face {
  font-family: "Montserrat Fallback"; font-style: normal; font-weight: 500;
  src: local("Arial"), local("ArialMT"), local("Liberation Sans"), local("LiberationSans");
  size-adjust: 113.07%; ascent-override: 85.61%; descent-override: 22.20%; line-gap-override: 0%;
}
@font-face {
  font-family: "Montserrat Fallback"; font-style: normal; font-weight: 700;
  src: local("Arial Bold"), local("Arial-BoldMT"), local("Liberation Sans Bold"), local("LiberationSans-Bold");
  size-adjust: 110.06%; ascent-override: 87.95%; descent-override: 22.81%; line-gap-override: 0%;
}
@font-face {
  font-family: "Montserrat Fallback"; font-style: normal; font-weight: 900;
  src: local("Arial Bold"), local("Arial-BoldMT"), local("Liberation Sans Bold"), local("LiberationSans-Bold");
  size-adjust: 114.53%; ascent-override: 84.52%; descent-override: 21.92%; line-gap-override: 0%;
}
/* skin.css names the page face; the fallback goes straight after it. */
:root { --sans: Montserrat, "Montserrat Fallback", ui-sans-serif, system-ui, "Segoe UI", sans-serif; }

:root {
  --wrap: 1312px;
  --side: 16px;
  --head-h: 60px;
  --row-y: 72px;
  /* 6 to 5 at every two-column width, so the headline's first line holds
     "The things you check" and it stays three lines at full size. */
  --split: minmax(0, 6fr) minmax(0, 5fr);
  --split-gap: 40px;
  --ink: var(--page-fg);
  --ink-2: var(--page-note);   /* 10.6:1 on --page-bg */
  --ink-3: var(--page-help);   /* 6.8:1 on --page-panel, more on the others */
  --rule: var(--page-border);
  --tile-bg: #1A2236;
  /* The app's own Space ground: a dot every 40px (space.css). Stronger
     than the app's 3.5%, so the two invitation rows read as their own
     ground and not as plain navy. */
  --stars: radial-gradient(rgba(255, 255, 255, 0.10) 1.2px, transparent 1.8px);
}
@media (min-width: 768px) { :root { --side: 32px; --head-h: 64px; --row-y: 88px; } }
@media (min-width: 1200px) { :root { --side: 48px; --row-y: 104px; --split: minmax(0, 6fr) minmax(0, 5fr); --split-gap: 72px; } }

/* Anchors and keyboard focus land clear of the sticky header. --head-total
   is the header's full height, which grows in the open state on a phone,
   where the trial line takes a second row. */
html {
  -webkit-text-size-adjust: 100%; scroll-behavior: smooth;
  --head-total: var(--head-h);
  scroll-padding-top: calc(var(--head-total) + 16px);
}
@media (max-width: 767px) { html[data-signup="open"] { --head-total: 84px; } }
@media (max-width: 369px) { html[data-signup="open"] { --head-total: 100px; } }
@media (prefers-reduced-motion: reduce) { html { scroll-behavior: auto; } }
body {
  margin: 0;
  background: var(--page-bg);
  color: var(--ink-2);
  font-family: var(--sans);
  font-size: 16px;
  line-height: 1.55;
  -webkit-font-smoothing: antialiased;
}
img { display: block; max-width: 100%; height: auto; }
a { color: var(--ink); }
a:focus-visible, button:focus-visible, input:focus-visible, textarea:focus-visible, summary:focus-visible {
  outline: 2px solid var(--primary);
  outline-offset: 3px;
  border-radius: 4px;
}
h1, h2, h3 { margin: 0; color: var(--ink); font-weight: 900; text-wrap: balance; }
p { margin: 0; text-wrap: pretty; }
.wrap { width: min(var(--wrap), 100% - 2 * var(--side)); margin-inline: auto; }
.skip {
  position: absolute; left: 12px; top: -60px; z-index: 60;
  padding: 10px 14px; border-radius: 8px;
  background: var(--ink); color: var(--page-deep); font-weight: 700; text-decoration: none;
}
.skip:focus { top: 12px; }
.mark img, .foot-brand img { display: block; }

/* ── Header ─────────────────────────────────────────────────────────────── */
.site-head {
  position: sticky; top: 0; z-index: 50;
  background: var(--page-bg);
  border-bottom: 1px solid var(--rule);
}
.site-head .wrap { display: flex; align-items: center; gap: 28px; height: var(--head-h); }
.mark { flex: 0 0 auto; display: block; border-radius: 4px; }
.mark img { width: auto; height: 22px; }
.nav { display: none; }
.nav ul { display: flex; gap: 24px; margin: 0; padding: 0; list-style: none; }
.nav a { font-size: 14px; font-weight: 700; color: var(--ink-2); text-decoration: none; white-space: nowrap; }
.nav a:hover { color: var(--ink); }
.head-act { display: flex; align-items: center; gap: 18px; margin-left: auto; }
.head-start { display: flex; align-items: center; gap: 14px; }
.head-signin { font-size: 14px; font-weight: 700; color: var(--ink-2); text-decoration: none; white-space: nowrap; }
.head-signin:hover { color: var(--ink); }
/* On a phone the text links press like buttons: 44px tall, same layout. */
@media (max-width: 767px) { .head-signin { padding: 11px 0; margin: -11px 0; } }
.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 8px;
  height: 40px; padding: 0 16px; border: 0; border-radius: 9px;
  background: var(--lime); color: #07090F;
  font: inherit; font-size: 14px; font-weight: 800; line-height: 1; white-space: nowrap;
  text-decoration: none; cursor: pointer;
  transition: background-color 0.15s var(--ease-out);
}
.btn:hover { background: #C8FF78; box-shadow: 0 8px 22px -10px rgba(184, 255, 87, 0.7); }
.btn:focus-visible { outline-color: var(--lime); }
.btn .ico { width: 13px; height: 13px; }
.head-terms { max-width: 190px; font-size: 12px; line-height: 1.35; color: var(--ink-3); text-align: right; text-wrap: balance; }
/* Open state: Start free and its trial line sit together at every width.
   From 1024 the section links fit beside them on one row; below that the
   links go (Plans stays), and on a phone the trial line takes its own row
   under the buttons, still inside the header. */
@media (min-width: 1024px) {
  .nav { display: block; }
  .head-plans { display: none; }
}
@media (max-width: 767px) {
  html[data-signup="open"] .site-head .wrap {
    flex-wrap: wrap; column-gap: 16px; row-gap: 6px;
    height: auto; min-height: var(--head-h); padding: 11px 0 9px;
  }
  html[data-signup="open"] .head-act,
  html[data-signup="open"] .head-start { display: contents; }
  html[data-signup="open"] .head-plans { margin-left: auto; }
  .head-terms { order: 5; flex: 1 0 100%; max-width: none; }
}
@media (max-width: 400px) {
  .site-head .wrap { gap: 12px; }
  .mark img { height: 19px; }
  .head-act { gap: 14px; }
  html[data-signup="open"] .site-head .wrap { column-gap: 14px; }
  .btn { padding: 0 13px; }
}
/* Under 380 the Plans link gives way to keep one row; the footer has it too. */
@media (max-width: 379px) {
  html[data-signup="open"] .head-plans { display: none; }
  html[data-signup="open"] .head-signin:not(.head-plans) { margin-left: auto; }
}

/* ── Rows ───────────────────────────────────────────────────────────────── */
/* Each row is full bleed and owns its ground; the hairline on top of every
   row but the first keeps the seams crisp. Grounds are set per row below,
   with the reason beside each. */
.row { position: relative; padding: var(--row-y) 0; border-top: 1px solid var(--rule); }
.row-head { max-width: 44rem; }
.row-head h2, .h2 { font-size: clamp(28px, 1.9vw + 12px, 40px); line-height: 1.1; letter-spacing: -0.03em; }
.row-head p { margin-top: 14px; font-size: 17px; color: var(--ink-2); }

/* ── The signup area ────────────────────────────────────────────────────── */
/* The signup area: a label, the action, one line. Both states hold the
   same three rows at the same heights, so flipping the state moves nothing. */
.signup-label, #join h3 {
  display: flex; align-items: center; gap: 8px;
  height: 20px; margin: 0 0 10px;
  font-size: 14px; font-weight: 700; letter-spacing: 0; color: var(--ink);
}
#join form { display: flex; flex-direction: column; margin: 0; }
#join h3 { order: 0; }
#join .bar {
  order: 1; display: flex; align-items: center; gap: 8px; box-sizing: border-box;
  height: 56px; padding: 5px 5px 5px 16px;
  border: 1px solid var(--page-orbit); border-radius: 12px; background: var(--page-deep);
  transition: border-color 0.15s var(--ease-out), box-shadow 0.15s var(--ease-out);
}
#join .bar:focus-within { border-color: var(--primary); box-shadow: 0 0 0 1px var(--primary); }
#join .bar .ico { flex: 0 0 auto; width: 15px; height: 15px; color: var(--ink-3); }
#join input[type="email"] {
  flex: 1 1 0; width: 0; min-width: 0; height: 44px; padding: 0; border: 0; background: transparent;
  color: var(--ink); font: inherit; font-size: 16px;
}
#join input[type="email"]:focus-visible { outline: none; }
#join input::placeholder, #join textarea::placeholder { color: #7F90B4; }
#join button[type="submit"] {
  flex: 0 0 auto; height: 44px; padding: 0 20px; border: 0; border-radius: 8px;
  background: var(--lime); color: #07090F; font: inherit; font-size: 15px; font-weight: 800; cursor: pointer;
  transition: background-color 0.15s var(--ease-out);
}
#join button[type="submit"]:hover { background: #C8FF78; box-shadow: 0 8px 22px -10px rgba(184, 255, 87, 0.7); }
#join button[type="submit"]:focus-visible { outline: 2px solid var(--lime); outline-offset: 2px; }
#join .problem { order: 2; margin: 8px 0 0; font-size: 14px; color: #FF7AC6; }
#join .note, .start-terms, .act-line {
  order: 3; min-height: 3.1em; margin: 12px 0 0;
  font-size: 14px; line-height: 1.55; color: var(--ink-3);
}
/* The waiting list note holds only its own line. It used to keep the trial
   line's height so the strip stayed put when the state flipped, but on the
   site the state is fixed at build time, and the empty lines under it left
   the form sitting high beside the heading it is centred against. */
#join .note { min-height: 0; }
#join .split {
  order: 4; display: flex; align-items: center; gap: 10px; margin: 6px 0 10px;
  font-size: 11px; font-weight: 700; letter-spacing: 0.1em; text-transform: uppercase; color: var(--ink-3);
}
#join .split i { flex: 1 1 auto; height: 1px; background: var(--rule); }
#join .quiet { order: 5; }
#join .lab { display: block; margin-bottom: 6px; font-size: 14px; color: var(--ink-2); }
#join .ta-wrap { position: relative; }
#join textarea {
  display: block; width: 100%; box-sizing: border-box; padding: 10px 12px;
  border: 1px solid var(--page-orbit); border-radius: 10px; background: var(--page-deep);
  color: var(--ink); font: inherit; font-size: 15px; resize: vertical;
}
#join .ta-count { position: absolute; right: 10px; bottom: 8px; font-size: 11px; color: var(--ink-3); }
/* The optional question is a second step: it opens once somebody is in the
   form, and stays open while it holds an answer. */
#join form:not(:focus-within):has(#wl-wants:placeholder-shown) .split,
#join form:not(:focus-within):has(#wl-wants:placeholder-shown) .quiet { display: none; }

.start-row { display: flex; align-items: center; gap: 20px; height: 56px; }
.start-go { height: 56px; padding: 0 26px; border-radius: 12px; font-size: 16px; }
.start-go .ico { width: 14px; height: 14px; }
.start-signin { font-size: 15px; font-weight: 700; color: var(--ink-2); }
.start-signin:hover { color: var(--ink); }
.start-terms { margin-top: 12px; }
/* Under 414px the trial line takes three lines. */
@media (max-width: 413px) {
  .start-terms, .act-line { min-height: 4.65em; }
}
/* Under 414 the envelope gives its room to the address, so the whole
   placeholder shows on a 390 or 375 phone. The bar keeps its height. */
@media (max-width: 413px) {
  #join .bar { padding-left: 14px; }
  #join .bar .ico { display: none; }
  #join button[type="submit"] { padding: 0 14px; }
}
/* On a 360 phone the strip takes the board's 12px sides, and the bar and
   its button give up a few pixels more, so it still shows whole. */
@media (max-width: 374px) {
  #join .bar { gap: 6px; padding-left: 12px; }
  #join button[type="submit"] { padding: 0 12px; }
}
/* The one line under each action breaks evenly, never "there / is room". */
#join .note, .start-terms, .act-line, .close-line { text-wrap: balance; }

/* ── Tiles ──────────────────────────────────────────────────────────────── */
/* Below 1200 a two-cell Date is narrower than "September 23, 2026" at the
   tile's 12px floor with 16px sides, so its sides come in to 8px. By
   data-type, so a Date added again after Start over gets it too. */
@media (max-width: 1199px) {
  .board > [data-type="date"] .lv-date.lv-px16 { padding-left: 8px; padding-right: 8px; }
}
/* Under 360 even that is not enough: "September 24, 2026" at the tile's
   12px floor is wider than a two-cell Date, and the year was cut off. A
   stopgap until _live.js can wrap the year to a second line at its floor. */
@media (max-width: 359px) {
  .board > [data-type="date"] .lv-date.lv-px16 { padding-left: 2px; padding-right: 2px; }
  .board > [data-type="date"] .lv-fit-in { font-size: 11px !important; }
}
/* A two-row Forecast on the small cells of a phone or a narrow tablet is
   shorter than its five rows of text, and the rain amounts were cut off at
   the bottom edge. Below 140px of body they step aside; they come back when
   the tile is made taller. */
.board > [data-type="forecast"] .tile-body { container: fc / size; }
@container fc (max-height: 139px) { .lv-fc-rain { display: none; } }

/* The call to action: a row of its own under the playground, holding the
   page's one form. Its three rows (label, action, one line) are the same
   height in both states, so it never changes size when signup opens. */
.cta {
  padding: clamp(48px, 4vw + 20px, 76px) 0;
  background:
    radial-gradient(ellipse 50% 130% at 84% 50%, rgba(184, 255, 87, 0.07), transparent 64%),
    var(--page-panel);
}
.keep { display: grid; grid-template-columns: minmax(0, 1fr); gap: 22px 48px; align-items: center; }
.keep-say { font-size: clamp(28px, 1.9vw + 12px, 40px); line-height: 1.1; letter-spacing: -0.03em; color: var(--ink); }
/* Each sentence on its own line, so the break never lands mid-thought. */
.keep-say span { display: block; color: var(--page-help); }
.keep-act { min-width: 0; }
.keep-act > * { max-width: 560px; }
.keep .start-go .ico { width: 13px; height: 13px; }
.act-line a { color: var(--ink-2); font-weight: 700; white-space: nowrap; }
.act-line a:hover { color: var(--ink); }
/* From 1000 the form starts on the page's one split, level with the lede
   above the board. (Narrower, the trial line would take a third line in
   that column.) */
@media (min-width: 1000px) {
  .keep { grid-template-columns: var(--split); column-gap: var(--split-gap); }
}
/* Below 1200 the form keeps the wider column (5 to 6): at 6 to 5 the trial
   line takes an extra line there and the open state would stand taller. */
@media (min-width: 1000px) and (max-width: 1199px) {
  .keep { grid-template-columns: minmax(0, 5fr) minmax(0, 6fr); }
}
/* Under 520 the trial line and its plans link take three lines, and under
   380 four, so the waiting list line keeps as many and the strip stays one
   height in both states. */
@media (max-width: 519px) { .keep .act-line { min-height: 4.65em; } }
@media (max-width: 379px) { .keep .act-line { min-height: 6.2em; } }

/* A widget named inside a sentence. */
.wref { color: var(--ink-2); text-decoration: none; }
a.wref { text-decoration: underline; text-decoration-color: rgba(186, 198, 222, 0.35); text-underline-offset: 3px; }
a.wref:hover { color: var(--ink); text-decoration-color: currentColor; }

/* The closing card: the page ends on its one action. Same three rows in
   both states (heading, action, one line), so the card never changes size. */
.close-card {
  padding: 28px; border: 1px solid rgba(184, 255, 87, 0.3); border-radius: 14px; background: var(--page-panel);
}
.close-card h2 { font-size: 22px; line-height: 1.2; letter-spacing: -0.02em; }
/* The page's last primary action, the same size as the strip's. */
.close-go { margin-top: 20px; height: 56px; padding: 0 26px; border-radius: 12px; font-size: 16px; }
.close-go .ico { width: 13px; height: 13px; }
.close-line { min-height: 3.1em; margin-top: 12px; font-size: 14px; line-height: 1.55; color: var(--ink-3); max-width: 34em; }
/* Full width under the links: a strip, the button to the right of its words. */
@media (min-width: 768px) and (max-width: 1199px) {
  .close-card { display: grid; grid-template-columns: minmax(0, 1fr) auto; column-gap: 40px; align-items: center; padding: 28px 32px; }
  .close-card h2 { grid-column: 1; grid-row: 1; }
  .close-act { display: contents; }
  .close-go { grid-column: 2; grid-row: 1 / span 2; margin-top: 0; }
  .close-line { grid-column: 1; grid-row: 2; max-width: none; text-wrap: balance; }
}
/* The same for the closing card: three lines of trial line under 460. */
@media (max-width: 459px) { .close-line { min-height: 4.65em; } }
@media (max-width: 413px) {
  .close-card { padding: 24px 20px; }
}
/* Under 380 the trial line takes four lines, so the waiting list line
   keeps four too and the card stays one height. */
@media (max-width: 379px) { .close-line { min-height: 6.2em; } }

/* ── Footer ─────────────────────────────────────────────────────────────── */
/* Ground: deep, the floor of the page. 01's links, sorted into columns,
   plus the Widgets column: the six groups today, the /widgets/ index and
   its group pages next week. Extra room at the bottom on phones for the
   mockup switch. */
.site-foot { padding: 56px 0 96px; background: var(--page-deep); border-top: 1px solid var(--rule); font-size: 14px; color: var(--ink-3); }
/* Phone: the brand across the top, Widgets down the left, Account and
   Community stacked on the right. The last row takes the Widgets list's
   extra height, so Community sits right under Account. */
.foot-grid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); grid-template-rows: auto auto 1fr; gap: 36px 24px; }
.foot-brand { grid-column: 1 / -1; }
.foot-brand img { width: auto; height: 20px; }
.foot-brand p { margin-top: 14px; max-width: 22em; color: var(--ink-3); }
.foot-h { margin: 0 0 14px; font-size: 14px; font-weight: 700; letter-spacing: 0; color: var(--ink); }
/* On a phone each link is a 34px target; from 768 the list tightens. */
.foot-col ul { display: grid; gap: 2px; margin: -7px 0 0; padding: 0; list-style: none; }
.foot-col a { display: inline-block; padding: 7px 0; color: var(--ink-2); font-weight: 500; text-decoration: underline; text-decoration-color: transparent; text-underline-offset: 3px; }
@media (min-width: 768px) {
  .foot-col ul { gap: 10px; margin-top: 0; }
  .foot-col a { padding: 0; }
}
.foot-col a:hover { color: var(--ink); text-decoration-color: currentColor; }
.foot-groups { grid-row: span 2; }
.foot-small {
  display: flex; flex-wrap: wrap; gap: 8px 24px;
  margin-top: 44px; padding-top: 20px; border-top: 1px solid var(--rule);
}
.foot-small a { color: var(--ink-2); }
.foot-beta { margin: 0; color: var(--ink-3); }
.foot-small a:hover { color: var(--ink); }
@media (max-width: 767px) {
  .foot-small { row-gap: 0; }
  .foot-small > * { padding: 7px 0; }
}
@media (min-width: 768px) {
  /* The small links sit bottom left, where the mockup switch rests. */
  .site-foot { padding: 64px 0 80px; }
  /* The brand takes what is left; each link column is as wide as its
     longest link, so the lists never spill into each other. */
  .foot-grid { grid-template-columns: minmax(0, 1fr) repeat(3, auto); grid-template-rows: auto; column-gap: 44px; }
  .foot-brand { grid-column: auto; }
  .foot-groups { grid-row: auto; }
  /* Down the first column, then the second, in the picker's order. */
  .foot-groups ul { grid-auto-flow: column; grid-template-rows: repeat(4, auto); grid-template-columns: repeat(2, max-content); column-gap: 36px; }
}
@media (min-width: 1200px) { .foot-grid { column-gap: 80px; } }

/* ── Motion ─────────────────────────────────────────────────────────────── */
/* motion.js gives what starts below the fold .mo-wait, then lets it rise
   8px into place once as it scrolls in. Nothing else waits: a row already on
   screen, a page without script and reduced motion show everything at once. */
.mo-wait { opacity: 0; transform: translateY(8px); }
/* A printout or a saved PDF shows every row, scrolled to or not. */
@media print { .mo-wait { opacity: 1 !important; transform: none !important; } }
/* A press reads as a press: a button sinks a pixel while it is held. These
   come last so their transition lists win over the ones above. */
@media (prefers-reduced-motion: no-preference) {
  .btn, #join button[type="submit"] {
    transition-property: background-color, border-color, color, box-shadow, transform;
    transition-duration: 0.2s, 0.2s, 0.2s, 0.2s, 0.1s;
    transition-timing-function: var(--ease-out);
  }
  /* Text links fade to full ink instead of snapping to it. */
  .nav a, .head-signin, .start-signin, .act-line a, a.wref, .foot-col a, .foot-small a {
    transition: color 0.2s var(--ease-out), text-decoration-color 0.2s var(--ease-out);
  }
  .btn:active, #join button[type="submit"]:active { transform: translateY(1px); }
}
