/* ChessRoller — "Sky", light.
   Paper background, near-black ink, DM Sans display, no accent hue,
   white rounded cards, white FAQ band, dark footer.
   Zero external requests. */

/* DM Sans + DM Mono (OFL) — self-hosted so the site makes zero external
   requests. One variable file covers every weight the site uses, display
   included, which is why the display face no longer needs its own download. */
@font-face {
  font-family: 'DM Sans Variable';
  font-style: normal;
  font-weight: 100 1000;
  font-display: swap;
  src: url('/assets/fonts/dm-sans-latin-wght-normal.9fea608a.woff2') format('woff2-variations');
}
/* DM Mono ships 300/400/500 only — there is no 600 cut, so the micro-labels
   that used IBM Plex Mono SemiBold sit at 500 instead */
@font-face {
  font-family: 'DM Mono';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url('/assets/fonts/dm-mono-latin-400-normal.e1896b13.woff2') format('woff2');
}
@font-face {
  font-family: 'DM Mono';
  font-style: normal;
  font-weight: 500;
  font-display: swap;
  src: url('/assets/fonts/dm-mono-latin-500-normal.9964608a.woff2') format('woff2');
}

:root {
  color-scheme: light;
  --bg: #eeebe3;
  --card: #ffffff;
  --ink: #141413;
  --ink-muted: #4f4e47;
  --line: rgba(20, 20, 19, 0.25);
  --line-soft: rgba(20, 20, 19, 0.2);
  /* Controls are ink. They lighten to --ink-muted on hover rather than
     shifting hue — white on --ink-muted still clears AA at 8.6:1. */
  --on-ink: #ffffff;
  /* secondary button fill — a tint of ink rather than of a hue */
  --ink-wash: rgba(20, 20, 19, 0.07);
  --ink-wash-hover: rgba(20, 20, 19, 0.12);
  /* Text selection is the one place blue survives. A tint rather than a solid
     fill, so selected text keeps its own colour instead of being flattened —
     ink stays ink. The dark variant is for the footer, where the paper tint
     would leave light-on-dark text unreadable. */
  --select: rgba(11, 97, 255, 0.18);
  --select-dark: rgba(94, 171, 255, 0.3);
  /* The one hue in the palette. It carries a single tag — "matches your
     device" on the download row — where a wash of ink would read as just
     another muted label rather than as a positive match.

     The wash is the comp's green at 10%. The text is the comp's #017a57
     darkened along the same hue (162 deg) and saturation until it clears AA:
     over the resolved wash the comp value lands at 3.9:1, which fails the
     check:a11y gate at the 10px the tag is set in. This is 4.7:1. */
  --match: #016d4d;
  --match-wash: rgba(1, 122, 87, 0.1);
  --footer-bg: #141413;
  --footer-ink: #ffffff;
  --footer-muted: #b0aea4;
  /* header height — the news date column sticks just below it */
  --header-h: 79px;
  /* one family now carries body and display; they are told apart by weight
     and tracking, not by typeface */
  --sans:
    'DM Sans Variable', 'DM Sans', -apple-system, BlinkMacSystemFont,
    'Segoe UI', Roboto, 'Helvetica Neue', sans-serif;
  --mono: 'DM Mono', ui-monospace, 'SF Mono', Consolas, 'Liberation Mono', monospace;
  /* page gutter. Fitted to anthropic.com's measured margins below their column
     cap — 47px @768, 57 @1024, 64 @1200, 71 @1360 — which is a line, not a
     ratio: 0.0405 x viewport + 16px. A plain vw can't express it (their gutter
     is 6.1vw at 768 but 5.2vw at 1360), hence the rem offset. Above ~1428px
     the column cap takes over and this stops governing the margin.

     Deliberately off the 8px grid every other horizontal value follows: a
     fluid gutter cannot land on 8s at every width, and the fitting above is
     worth more than the grid here. Everything fixed — gaps, button and card
     padding, list indents — is a multiple of 8. */
  --gutter: clamp(1.5rem, 1rem + 4.05vw, 5.5rem);
  /* column system, measured against anthropic.com at 1440px:
     wide  1280px — grids and cards; anthropic caps at 1272-1285
     mid    880px — headings that shouldn't be squeezed to prose width
     text   640px — running copy; ~71ch at 18px, ~75ch at 17px
     The comp draws the wide column at 1080px, which left the page in far more
     whitespace than anthropic.com (75% of a 1440px viewport against their 89%).
     At 1280 a third of the grid lands on 405px against their measured 407. */
  --col-wide: 80rem;
  --col-mid: 55rem;
  --col-text: 40rem;
}

* {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}
html {
  scroll-behavior: smooth;
}
/* the open menu covers the viewport; without this the page scrolls behind it */
html:has(.nav-menu[open]) {
  overflow: hidden;
}

body {
  background: var(--bg);
  color: var(--ink);
  -webkit-font-smoothing: antialiased;
}

/* Hover system — three rules, by what the control already is. With no accent
   hue in the palette, nothing moves on colour except to lighten:
   1. anything that looks like a button lightens its ink fill
   2. a link in running text sets in ink like the copy around it, marked by its
      underline at rest, and lightens to muted ink on hover
   3. every other link sets in ink with no underline at rest, and gains one on
      hover. On the dark footer, where an underline reads heavily against muted
      text, those links lighten to white instead.
   Rule 3 is the change: standalone links used to be marked by their colour, so
   they now depend on position and, where present, a trailing arrow. */
a {
  color: var(--ink);
  text-decoration: none;
  transition:
    color 0.12s ease,
    text-decoration-color 0.12s ease,
    text-decoration-thickness 0.12s ease;
}
a:hover {
  text-decoration: underline;
  text-underline-offset: 3px;
}
/* links inside running text must not rely on color alone (WCAG 1.4.1). List
   items in long-form copy are running text too — a link mid-sentence in a
   bullet is no more self-evident than one in a paragraph. Scoped to the
   long-form containers so the footer and social link lists, which are
   standalone links that happen to sit in <li>, stay clean. */
p a,
.prose li a,
.article-body li a,
.cb-section li a {
  color: var(--ink);
  text-decoration: underline;
  text-underline-offset: 3px;
}
/* rule 2: the underline already marks it, so hover moves the colour instead —
   lightening rather than deepening, since the resting state is already ink.
   --ink-muted is the site's muted ink. */
p a:hover,
.prose li a:hover,
.article-body li a:hover,
.cb-section li a:hover {
  color: var(--ink-muted);
  text-decoration-thickness: auto;
}

:focus-visible {
  outline: 3px solid var(--ink);
  outline-offset: 2px;
}
.site-footer :focus-visible {
  outline-color: var(--footer-ink);
}

.skip-link {
  position: absolute;
  left: -999px;
  top: 0;
  z-index: 20;
  padding: 0.6rem 1rem;
  background: var(--ink);
  color: var(--on-ink);
  border-radius: 0 0 8px 0;
}
.skip-link:focus {
  left: 0;
}

/* text for screen readers only — carries context a visual cue conveys on its
   own (e.g. what the struck-through price is) */
.sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}

/* no colour is set, so selected text keeps whatever colour it already had */
::selection {
  background: var(--select);
}
.site-footer ::selection {
  background: var(--select-dark);
}



/* one shared content column. Below the cap the column falls back to the page
   gutter rather than a fixed 3rem — with a 1280px cap that fallback engages at
   1328px, where 24px margins would be far too tight for a desktop window. This
   also keeps .col's margin identical to the header/footer padding at every
   width, since both resolve to the gutter once the cap stops applying. */
.col {
  width: min(var(--col-wide), 100% - 2 * var(--gutter));
  margin-inline: auto;
}

/* ── Type styles ────────────────────────────────────── */

/* Ten styles carry the whole site. Each is defined once here, with every
   selector that uses it listed on the rule — so changing a style is a single
   edit, and two selectors sharing a rule are provably the same style rather
   than coincidentally equal numbers. The scale is 12 · 16 · 40 · 80, plus the
   32px floor the display headline falls to below ~576px. */

/* display — the hero headline; the only tier that scales with the viewport */
.hero h1,
.news-hero h1 {
  font-weight: 700;
  font-size: clamp(2rem, 5.56vw, 5rem);
  line-height: 1.06;
}

/* h1 — page titles on the article and legal templates, and the download
   page, which the comp moved down off the display tier */
.article-hero h1,
.prose h1,
.download-intro h1 {
  font-weight: 700;
  font-size: 2.5rem;
  line-height: 1.15;
}

/* h2 — section headings, and the price, which the comp sets at the same
   32/700/1.2 rather than giving the figure a tier of its own */
h2,
.price-amount {
  font-weight: 700;
  font-size: 2rem;
  line-height: 1.2;
}


/* h3 — every subhead: cards, FAQ rows, long-form sections, the wordmark;
   also the struck pre-launch price, which sits a tier below the live one */
.card h3,
.faq summary,
.price-card h3,
.price-was,
.cb-section h2,
.article-body h2,
.prose h2 {
  font-weight: 700;
  font-size: 1.25rem;
  line-height: 1.3;
}


/* body — running copy, and everything that reads as running copy */
body,
.lede,
.price-note,
.news-table .news-title,
.card p,
.faq details p,
.price-card li,
.price-term,
.news-table,
.news-hero p,
.article-date,
.download-intro p,
.download-build p,
.download-version,
.prose em {
  font-family: var(--sans);
  font-weight: 400;
  font-size: 1rem;
  line-height: 1.45;
}

/* body-strong — the build name on a download row. The comp keeps it at body
   size and leading and separates it by weight alone, so the lines of a row set
   on one baseline rhythm instead of stepping up into a subhead. */
.download-build h2 {
  font-weight: 700;
  font-size: 1rem;
  line-height: 1.45;
}

/* ui — controls: buttons, nav, standalone links */
.btn,
.btn-wide,
.btn-secondary,
.site-nav a,
.link-standalone {
  font-weight: 500;
  font-size: 1rem;
  line-height: 1.2;
}

/* menu — the full-screen mobile panel's links. Mobile only: the panel does
   not exist above 640px, and 24 appears nowhere else in the scale. */
.menu-panel a:not(.menu-cta) {
  font-weight: 500;
  font-size: 1.5rem;
  line-height: 1.2;
}

/* micro — small print sitting under or beside everything else */
.link-groups li,
.footer-bottom a,
.footer-bottom .copyright,
.price-currency,
.price-card .fineprint,
.cb-disclaimer {
  font-weight: 400;
  font-size: 0.75rem;
  line-height: 1.4;
}

/* label — the mono kicker above a headline */
.eyebrow {
  font-family: var(--mono);
  font-weight: 500;
  font-size: 0.75rem;
  line-height: 1.3;
  letter-spacing: 0.08em;
}

/* label-sm — mono column and group headers */
.link-groups .group-label,
.news-table th {
  font-family: var(--mono);
  font-weight: 500;
  font-size: 0.75rem;
  line-height: 1.3;
  letter-spacing: 0.125em;
}

/* label-xs — the "matches your device" tag, and the only 10px on the site.
   It sits off the 12·16·40·80 scale on purpose: the tag annotates the build
   name beside it, and at 12px it competed with the name for the row. */
.download-yours {
  font-family: var(--mono);
  font-weight: 500;
  font-size: 0.625rem;
  line-height: 1.3;
  letter-spacing: 0.1em;
}

/* anchor targets (the nav's Features, Pricing, FAQ) stop half a header's
   height short of the sticky header, so the heading lands about 40px below
   it rather than tight against its edge */
[id] {
  scroll-margin-top: calc(var(--header-h) / 2);
}

/* ── Header ─────────────────────────────────────────── */

.site-header {
  position: sticky;
  top: 0;
  z-index: 10;
  display: flex;
  align-items: center;
  gap: 2rem;
  min-height: var(--header-h);
  padding-block: 1.25rem;
  /* the nav shares the content column's edges rather than the page gutter, so
     the brand and Buy button line up with the grid below. max() keeps the
     56px gutter as a floor once the viewport is narrower than the column */
  padding-inline: max(var(--gutter), (100% - var(--col-wide)) / 2);
  background: var(--bg);
  border-bottom: 1px solid var(--line);
}

.brand {
  display: flex;
  align-items: center;
  color: var(--ink);
  margin-right: auto;
}
/* the wordmark is inline SVG, so the site still makes zero external requests.
   fill: currentColor means it takes .brand's colour — ink in the header, white
   against the footer — rather than needing a second file for the dark band. */
.wordmark {
  display: block;
  width: auto;
  height: 25px;
}
.brand:hover {
  text-decoration: none;
}

.site-nav {
  display: flex;
  align-items: center;
  gap: 2rem;
}
.site-nav a {
  color: var(--ink);
}
.site-nav a:hover {
  color: var(--ink);
  text-decoration: underline;
  text-underline-offset: 3px;
}

/* hamburger dropdown — hidden on desktop, replaces .site-nav on mobile */
.nav-menu {
  display: none;
}
.nav-menu summary {
  list-style: none;
  display: flex;
  align-items: center;
  cursor: pointer;
  padding: 0.25rem;
  color: var(--ink);
}
.nav-menu summary::-webkit-details-marker {
  display: none;
}
/* two bars that cross into an X when the panel opens. Both bars move to the
   same centre line and counter-rotate, so the open and closed states are the
   same two elements rather than a swapped icon — which is what lets the
   transition read as one continuous movement. */
.burger {
  position: relative;
  display: block;
  width: 26px;
  height: 26px;
}
.burger span {
  position: absolute;
  left: 2px;
  right: 2px;
  height: 1.5px;
  border-radius: 1px;
  background: var(--ink);
  transition:
    top 0.2s ease,
    transform 0.2s ease;
}
.burger span:first-child {
  top: 9.5px;
}
.burger span:last-child {
  top: 15.5px;
}
.nav-menu[open] .burger span {
  top: 12.5px;
}
.nav-menu[open] .burger span:first-child {
  transform: rotate(45deg);
}
.nav-menu[open] .burger span:last-child {
  transform: rotate(-45deg);
}
/* deliberately no hover colour: this control only exists below 640px, where a
   tap leaves an emulated hover behind and the icon would stay tinted */
/* full-screen below the header, so the menu is the page rather than a panel
   hanging off it. Fixed rather than absolute: the sheet stays put if the page
   behind it scrolls, and the CTA can sit against the bottom edge. */
.menu-panel {
  position: fixed;
  top: var(--header-h);
  left: 0;
  right: 0;
  bottom: 0;
  display: flex;
  flex-direction: column;
  background: var(--bg);
  overflow-y: auto;
  /* clears the home indicator on notched phones */
  padding-bottom: env(safe-area-inset-bottom, 0px);
}
.menu-panel a:first-child {
  border-top: none;
}
.menu-panel a {
  padding: 0.9rem var(--gutter);
  color: var(--ink);
  border-top: 1px solid rgba(20, 20, 19, 0.08);
}
.menu-panel a:hover {
  color: var(--ink);
  text-decoration: underline;
  text-underline-offset: 3px;
}
/* the panel's own call to action. It sits below the links rather than in the
   header bar, so the bar carries only the wordmark and the menu toggle. */
/* scoped to the panel so it outranks `.menu-panel a`, which would otherwise
   paint the label ink on the ink fill */
.menu-panel .menu-cta {
  margin: auto var(--gutter) 1.5rem;
  text-align: center;
  color: var(--on-ink);
}
.menu-panel .menu-cta:hover {
  color: var(--on-ink);
  background: var(--ink-muted);
}

/* ── Buttons ────────────────────────────────────────── */

.btn {
  display: inline-block;
  padding: 0.875rem 1.5rem;
  border: none;
  border-radius: 7px;
  background: var(--ink);
  color: var(--on-ink);
  /* the fill already distinguishes a button from body text, so it opts out of
     the `p a` underline that running-text links need for WCAG 1.4.1 */
  text-decoration: none;
  transition: background 0.12s ease;
}
/* colour change only — no lift or shadow. The colour is restated rather than
   inherited so that a button placed inside a <p> keeps its label: the
   running-text rule would otherwise repaint the label muted ink on the ink
   fill, which is unreadable.
   Stating it here (0,2,0) outranks p a:hover (0,1,2) without touching that
   rule. */
.btn:hover {
  text-decoration: none;
  background: var(--ink-muted);
  color: var(--on-ink);
}
.btn-small {
  padding: 0.625rem 1rem;
}
.btn-wide {
  display: block;
  width: 100%;
  text-align: center;
}
/* secondary button — same box as .btn, carrying a light ink wash instead of a
   solid fill. Both buttons follow the same hover rule: the fill moves. The
   label is full ink, which the wash is light enough to carry. */
.btn-secondary {
  display: inline-block;
  padding: 0.875rem 1.5rem;
  border-radius: 7px;
  background: var(--ink-wash);
  color: var(--ink);
  transition: background 0.12s ease;
}
/* colour restated for the same reason as .btn:hover, so this stays correct if
   a secondary button is ever placed inside a paragraph */
.btn-secondary:hover {
  text-decoration: none;
  background: var(--ink-wash-hover);
  color: var(--ink);
}

/* ── Standalone link ────────────────────────────────── */

/* One definition for every link that stands on its own: card links, the news
   subscribe link, section CTAs. These are unambiguous without an underline
   (WCAG 1.4.1), so they move on colour instead — rule 3 of the hover system.
   Colour and decoration are stated explicitly because each of them sits inside
   a <p>, which would otherwise hand it the running-text treatment: ink plus an
   underline. 16px holds them together as one thing wherever they appear, since
   they otherwise inherit whatever their container sets — 20px in a section,
   16px in a card. */
.link-standalone {
  color: var(--ink);
  text-decoration: none;
}
.link-standalone:hover {
  color: var(--ink);
  text-decoration: none;
}
/* the underline rides the label span so it stops before the trailing arrow —
   a decoration on the <a> would run under the arrow too */
.link-standalone:hover span {
  text-decoration: underline;
  text-underline-offset: 3px;
}

/* ── Hero ───────────────────────────────────────────── */

.hero {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 2rem;
  /* no bottom padding: the section that follows brings its own 5rem, and the
     two together put 160px between the hero shot and the next heading */
  padding: 5rem var(--gutter) 0;
  text-align: center;
}

.eyebrow {
  text-transform: uppercase;
  /* the comp's 0.23em is roughly 3x what Anthropic uses on the same treatment */
  color: var(--ink);
}

/* the hero flex gap already puts 32px under it */
.hero-logomark {
  display: block;
  width: 68px;
  height: 68px;
}

.hero h1 {
  max-width: 62.5rem;
  /* 5.56vw so the 80px cap is actually reached at the 1440px comp width.
     The 32px floor is the one size left off the six-step scale: at 40px the
     headline breaks across four lines at 390px instead of the two the <br>
     is written for. It never renders above ~576px, so the visible desktop
     scale is still 12/16/20/24/40/80. */
}

.lede {
  max-width: var(--col-text);
}

/* the two hero buttons sit side by side; wrap is the fallback for narrow
   viewports, where they stack rather than shrink */
.cta-row {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  align-items: center;
  gap: 1rem;
}

/* the ChessBase link hangs under the buttons as a text aside; the hero's
   2rem gap is too much for a footnote, so pull it up */
.cta-aside {
  margin-top: -1rem;
}

/* the shot carries its own window chrome and drop shadow on a transparent
   background, so no border or radius here — they'd box the transparent margin */
.app-shot {
  display: block;
  /* hero already provides the gutters */
  width: 100%;
  max-width: var(--col-wide);
  height: auto;
  /* 80px below the copy block, which itself uses the 32px hero gap */
  margin: 3rem auto 0;
}

/* ── Sections ───────────────────────────────────────── */

section {
  padding: 5rem 0;
}

h2 {
  text-align: center;
  margin-bottom: 2.5rem;
}

/* ── Features ───────────────────────────────────────── */

.features h2 {
  margin-bottom: 1rem;
}
.section-cta {
  text-align: center;
  margin-bottom: 2.75rem;
}

/* gutter matches the 32px Anthropic runs on its 12-track grid. The ratio
   matters more than the absolute value: the comp's 52/20 put rows 2.6x further
   apart than columns, which read as three squeezed columns rather than a grid */
.features .grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 3rem 2rem;
}

/* image slot — 3:2 to match the screenshot crops, which carry their own
   window edge */
.card figure {
  aspect-ratio: 3 / 2;
  background: var(--card);
  border: 1px solid var(--line);
  border-radius: 20px;
  margin-bottom: 1.5rem;
  overflow: hidden;
}
.card figure img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
}
.card h3 {
  margin-bottom: 0.75rem;
}
.card p {
}
/* not in the comp — added so the import card can point at the ChessBase page */
.card-link {
  margin-top: 0.75rem;
}

/* ── Pricing ────────────────────────────────────────── */

.price-card {
  display: flex;
  flex-direction: column;
  --card-gap: 2.5rem;
  gap: var(--card-gap);
  max-width: 33.125rem;
  margin: 0 auto;
  background: var(--card);
  border: 1px solid var(--line);
  border-radius: 20px;
  padding: 3.5rem 3rem 3.125rem;
}

.price-head {
  display: flex;
  flex-direction: column;
  gap: 1.5rem;
}
.price-id {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 1rem;
}
/* the PNG ships with square corners, so clip them to the 15/72 radius the
   old SVG tile drew itself */
.product-icon {
  display: block;
  width: 72px;
  height: 72px;
  border-radius: 15px;
}
.price-card h3 {
}
/* baseline, not flex-end: the two sit at different sizes and line-heights, so
   aligning their box bottoms left the term sitting 3.3px below the amount */
.price {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 0.5rem;
}
/* wrap between the pieces, never inside them: on a narrow card the term drops
   to its own line instead of splitting "$69" from "USD" */
.price-amount,
.price-term {
  white-space: nowrap;
}
/* the pre-launch price. A tier below the live figure and struck through —
   that pairing carries it, so the colour stays at full ink. skip-ink off so
   the rule runs unbroken through the descender of the $.
   The comp asks for from-font, but DM Sans's own strike metric is hairline
   at 20px and all but disappears next to a 700-weight figure. 0.1em — 2px
   here — is stated instead, in em so it tracks the tier if the size moves.
   3px was tried and starts to swallow the digits. */
.price-was {
  text-decoration-thickness: 0.1em;
  text-decoration-skip-ink: none;
}

/* the rule sits closer to what it separates than the other blocks do: negative
   margins take back half the card's flex gap on each side, so the divider gets
   20px above and below where everything else gets 40. */
.price-card hr {
  border: none;
  border-top: 1px solid var(--line-soft);
  margin-block: calc(var(--card-gap) / -2);
}

.price-card ul {
  list-style: none;
  display: flex;
  flex-direction: column;
  gap: 0.875rem;
}
/* flex-start, not center: a wrapping item would otherwise hang its disc
   halfway down the block instead of beside the line it belongs to */
.price-card li {
  display: flex;
  align-items: flex-start;
  gap: 1rem;
}
.price-card li::before {
  content: '';
  flex: none;
  width: 15px;
  height: 15px;
  /* centres the disc on the first line rather than on its top edge: half the
     difference between the line box and the disc. Derived from the line-height
     so it stays correct if the body size moves. */
  margin-top: calc((1.45em - 15px) / 2);
  /* white check in an ink disc */
  background-color: var(--ink);
  border-radius: 50%;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M7 12.5l3.2 3.2L17 9' fill='none' stroke='%23fff' stroke-width='2.4' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
}

.price-card .fineprint {
  color: var(--ink);
  text-align: center;
  margin-top: calc(1.125rem - var(--card-gap));
}

/* the trial line sits just above the buy button; pull it out of the card's
   flex gap so the two read as one unit rather than two spaced rows */
.price-card .price-try {
  text-align: center;
  margin-bottom: calc(0.875rem - var(--card-gap));
}

/* ── FAQ ────────────────────────────────────────────── */

.faq {
  background: var(--card);
  padding: 5rem 0 10rem;
}
/* answers are running copy, so the FAQ takes the text measure (was 805px,
   which ran to ~95 characters per line) */
.faq .col {
  width: min(var(--col-text), 100% - 2 * var(--gutter));
}

.faq details {
  border-bottom: 1px solid var(--line);
}
.faq summary {
  cursor: pointer;
  list-style: none;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1.5rem;
  padding: 2.5rem 0;
}
.faq summary::-webkit-details-marker {
  display: none;
}
/* plus / minus toggle, matching anthropic.com/careers: a 24px box holding a
   13.5px bar 1.25px thick, in ink. Two gradients rather than an SVG so the
   vertical bar can collapse into the horizontal one when the row opens. */
.faq summary::after {
  content: '';
  flex: none;
  width: 24px;
  height: 24px;
  background-image:
    linear-gradient(var(--ink), var(--ink)),
    linear-gradient(var(--ink), var(--ink));
  background-size:
    13.5px 1.25px,
    1.25px 13.5px;
  background-position: center;
  background-repeat: no-repeat;
  transition: background-size 0.2s ease;
}
/* open: the vertical bar collapses, leaving the minus */
.faq details[open] summary::after {
  background-size:
    13.5px 1.25px,
    1.25px 0;
}
/* open rows tighten the summary and hand the 40px to the answer */
.faq details[open] summary {
  padding-bottom: 1.625rem;
}
.faq details p {
  padding-bottom: 2.5rem;
}

/* ── Footer ─────────────────────────────────────────── */

.site-footer {
  background: var(--footer-bg);
  color: var(--footer-muted);
  padding-block: 5rem;
  /* matches .site-header — both bands ride the content column's edges */
  padding-inline: max(var(--gutter), (100% - var(--col-wide)) / 2);
  /* the section above the footer usually ends on a fractional device pixel —
     its height depends on how the copy wraps, so it moves with the viewport
     width. Chromium hands that straddling row to the lighter background, which
     reads as a hairline above the footer at roughly a quarter of widths, worse
     on retina. The shadow repaints that row in the footer's colour. It has to
     paint *outside* the box: a border-top sits inside it, so the box's top edge
     snaps the same way and the hairline survives. */
  box-shadow: 0 -1px 0 var(--footer-bg);
}

.footer-top {
  display: flex;
  align-items: flex-start;
  gap: 10rem;
  flex-wrap: wrap;
  margin-bottom: 8.1875rem;
}
.footer-top .brand {
  color: var(--footer-ink);
  margin-right: 0;
}

.link-groups {
  display: flex;
  gap: 4.5rem;
  flex-wrap: wrap;
}
.link-groups .group-label {
  text-transform: uppercase;
  color: var(--footer-ink);
  margin-bottom: 1rem;
}
.link-groups ul {
  list-style: none;
  display: flex;
  flex-direction: column;
  gap: 1rem;
}
/* the metrics live on the <li>: an inline <a> can't shrink the line box below
   the list item's own 18px/1.6 strut */
.link-groups li {
}
.link-groups a {
  color: var(--footer-muted);
}
.link-groups a:hover {
  color: var(--footer-ink);
  text-decoration: none;
}

.footer-bottom {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 1.5rem;
}
.footer-bottom a {
  color: var(--footer-muted);
}
.footer-bottom a:hover {
  color: var(--footer-ink);
  text-decoration: none;
}
/* the social marks (see .social-links) take the footer link colours through
   currentColor; the negative margins pull the 44px targets back so the marks
   line up with the email link above and the copyright below */
.footer-bottom .social-links {
  margin: -0.625rem 0 -0.625rem -0.625rem;
}
.footer-bottom .copyright {
  color: var(--footer-muted);
}

/* ── Download page ──────────────────────────────────── */

/* The page runs on the 640px text column, left-aligned, following the news
   hero rather than the centred marketing hero: this is a utility page, and the
   rows below it are a left-aligned table that a centred headline would sit
   awkwardly over.

   The hero holds two intro blocks, default and post-checkout; the script on
   the page shows one. Both are in the flow so the hero keeps its own gap. */
.download-hero {
  padding: 5rem 0 0;
}
.download-intro {
  display: flex;
  flex-direction: column;
  gap: 1.5rem;
}
/* display: flex would otherwise outrank the hidden attribute */
.download-intro[hidden] {
  display: none;
}
.downloads {
  padding: 5rem 0 10rem;
}
/* one row per build: the build's name, requirement and version on the left,
   the button on the right, the "matches your device" tag under the name when
   the script sets it. The rule rides the top of every row and the bottom of
   the last, so the list is closed at both ends. */
.download-list {
  list-style: none;
  margin: 0;
  padding: 0;
}
.download-row {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-start;
  justify-content: space-between;
  gap: 1rem 1.25rem;
  padding: 1.5rem 0;
  border-top: 1px solid var(--line);
}
.download-row:last-child {
  border-bottom: 1px solid var(--line);
}
/* Name and version sit on two equal columns filling whatever the button
   leaves — 233px each on the 640px measure, against the comp's 240. They are
   sized by share rather than by a 15rem basis because two fixed 240s plus the
   button come to 647px, seven over the column, which wrapped the version under
   the name. The comp absorbs that overflow in Figma's auto-layout; a flex row
   wraps instead.

   The comp draws the gap at 19px, a nudge off the 8px grid every other fixed
   value here follows — 20px is the grid-true reading of the same measure. */
.download-info {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem 1.25rem;
  flex: 1 1 auto;
}
.download-build,
.download-version {
  flex: 1 1 0;
  min-width: 0;
}
/* the row heading opts out of the section-heading h2 treatment, which is
   centred with a 40px margin below */
.download-build h2 {
  text-align: left;
  margin: 0;
}
.download-build p {
  margin: 0;
}
/* the caveat that hangs off a build (Intel Macs) sets in muted ink so it reads
   as a footnote to the row rather than as a third line of its address. The
   comp draws it at 50% ink, which lands at 3.4:1 on paper; --ink-muted is the
   site's token for the same intent and clears AA at 7:1.

   It sits below the tag, and the 24px stands whether or not the tag is shown —
   the comp puts both on the same column with a gap, so a visitor on Windows
   sees the caveat at the same distance a Mac visitor does. */
/* selector carries the parent so the margin outranks .download-build p above,
   which zeroes it */
.download-build .download-caveat {
  margin-top: 1.5rem;
  color: var(--ink-muted);
}
/* the tag is a block of its own under the name, not a chip beside it, so the
   margin rides the tag itself — that way the name sits tight against the
   requirement in the far more common case where no tag is shown */
.download-yours {
  display: inline-flex;
  margin-top: 0.5rem;
  padding: 0.25rem 0.5rem;
  text-transform: uppercase;
  background: var(--match-wash);
  color: var(--match);
}
/* inline-flex would otherwise outrank the hidden attribute */
.download-yours[hidden] {
  display: none;
}

/* ── News index ─────────────────────────────────────── */

/* the news index now shares the wide column: holding it at the comp's 1024px
   would leave a 128px step against the 1280px header and footer. Article copy
   runs at the 640px text measure, with the article's own header on the wider
   880px tier so a 52px headline doesn't set in three ragged lines */
.col-news {
  width: min(var(--col-wide), 100% - 2 * var(--gutter));
  margin-inline: auto;
}
.col-mid {
  width: min(var(--col-mid), 100% - 2 * var(--gutter));
  margin-inline: auto;
}
/* the download page runs on the same 640px measure as article copy, but it is
   not an article — the generic name is here so a third page needing the text
   column doesn't have to reach for .col-article either */
.col-article,
.col-text {
  width: min(var(--col-text), 100% - 2 * var(--gutter));
  margin-inline: auto;
}

.news-hero {
  padding: 5rem 0;
}
.news-hero h1 {
  margin-bottom: 1.5rem;
}
/* metrics go on the paragraph: an inline <a> can't shrink its parent's strut */
.news-hero p {
}
.news-index {
  padding: 0 0 10rem;
}

/* ── Follow row ─────────────────────────────────────── */

/* ── Social marks ───────────────────────────────────── */

/* the three social marks, shared by the news hero and the footer (partial:
   _includes/social-links.njk). 20px marks in 44px targets. Colour is left to
   the context: ink moving to muted in the hero, muted moving to white in the
   footer, so the marks follow the same hover rule as the links around them. */
.social-links {
  list-style: none;
  display: flex;
  gap: 0.25rem;
  margin: 0;
  padding: 0;
}
.social-links a {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 2.75rem;
  height: 2.75rem;
  transition: color 0.12s ease;
}
.social-links svg {
  width: 1.25rem;
  height: 1.25rem;
}

/* "Follow us on" and the marks on one line under the news heading, standing
   in for the subscribe form until the list is live. The negative margin pulls
   the targets' padding back so label and marks read as one line. */
.follow {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.25rem;
}
.follow .social-links {
  margin: -0.625rem 0;
}
.follow .social-links a {
  color: var(--ink);
}
.follow .social-links a:hover {
  color: var(--ink-muted);
}

/* ── Subscribe form (parked, see news.html) ─────────── */

/* field and button on one line, stacking on narrow viewports like .cta-row.
   The field takes the button's box — same radius, same vertical rhythm — so
   the pair reads as one control. It sits on --card so it registers as a
   field against the paper background; the border is the standard rule. */
.subscribe {
  display: flex;
  flex-wrap: wrap;
  align-items: stretch;
  gap: 0.75rem;
  margin-top: 1.5rem;
}
.subscribe input[type='email'] {
  flex: 1 1 14rem;
  max-width: 22rem;
  min-width: 0;
  padding: 0.875rem 1rem;
  border: 1px solid var(--line);
  border-radius: 7px;
  background: var(--card);
  color: var(--ink);
  font: inherit;
  font-size: 1rem;
  line-height: 1.2;
}
.subscribe input[type='email']::placeholder {
  color: var(--ink-muted);
}
.subscribe input[type='email']:focus-visible {
  outline: 2px solid var(--ink);
  outline-offset: 2px;
}
.subscribe .btn {
  font: inherit;
  font-weight: 500;
  font-size: 1rem;
  line-height: 1.2;
  cursor: pointer;
}
/* disabled is the settled state after a successful submit as well as the
   in-flight one, so it keeps the ink fill rather than fading out */
.subscribe .btn:disabled {
  background: var(--ink-muted);
  cursor: default;
}
.subscribe input[type='email']:disabled {
  color: var(--ink-muted);
  background: var(--ink-wash);
}
/* status line takes the full row beneath the field and button */
.subscribe-status {
  flex-basis: 100%;
  margin: 0;
  color: var(--ink);
}

.news-table {
  width: 100%;
  table-layout: fixed;
  border-collapse: collapse;
  text-align: left;
}
.news-table th,
.news-table td {
  /* comp gutter between columns */
  padding: 1.5rem 1.5rem 1.5rem 0;
  vertical-align: top;
}
.news-table th:last-child,
.news-table td:last-child {
  padding-right: 0;
}
.news-table th {
  text-transform: uppercase;
}
/* dates and categories step back so the title carries the row — in the comp
   all three columns share one size and the eye has nothing to land on */
.news-table td {
  border-top: 1px solid var(--line);
  color: var(--ink-muted);
}
/* comp column widths: 227 / 214 / remainder, each plus the 26px gutter */
.news-table th:first-child {
  width: 15.8125rem;
}
.news-table th:nth-child(2) {
  width: 15rem;
}
.news-table .news-title {
}
.news-table .news-title a {
  color: var(--ink);
}
/* ink at rest like the nav links, and marked by an underline on hover */
.news-table .news-title a:hover {
  color: var(--ink);
  text-decoration: underline;
  text-underline-offset: 3px;
}

/* ── News article ───────────────────────────────────── */

.article-hero {
  padding: 5rem 0;
  text-align: center;
}
.article-hero .eyebrow {
  margin-bottom: 1.5rem;
}
.article-hero h1 {
  margin-bottom: 1.5rem;
}
.article-date {
}

.article-body {
  border-top: 1px solid var(--line);
  padding: 2.5rem 0 10rem;
}
/* section heads sit 40px below the previous block, 32px above their figure */
.article-body h2 {
  text-align: left;
  margin: 2.5rem 0 2rem;
}
.article-body > :first-child {
  margin-top: 0;
}
.article-body p {
  margin-bottom: 1.8rem;
}
.article-body ul {
  padding-left: 1.5rem;
  margin-bottom: 1.8rem;
}
.article-body li {
  margin-bottom: 1.125rem;
}
.article-body li:last-child {
  margin-bottom: 0;
}
/* the comp keeps body links in ink, distinguished by the underline alone */
.article-body a {
  color: var(--ink);
}

/* article screenshot: full column width, rounded like the feature cards */
.news-shot {
  display: block;
  width: 100%;
  height: auto;
  border-radius: 20px;
  margin-bottom: 2rem;
}

/* ── ChessBase page ─────────────────────────────────── */

/* no comp for this page — built from the existing type scale, with the
   article column's 700px measure for readable long-form copy */
.cb-section {
  padding: 3.5rem 0;
}
/* the rule rides the 700px column, so the section hands its top padding over */
.cb-section + .cb-section {
  padding-top: 0;
}
.cb-section + .cb-section .col-article {
  border-top: 1px solid var(--line);
  padding-top: 3.5rem;
}
/* smaller than the homepage's h2: these head left-aligned long-form copy in a
   640px column, which can't carry the larger size */
.cb-section h2 {
  text-align: left;
  margin-bottom: 1.5rem;
}
.cb-section p {
  margin-bottom: 1.25rem;
}
.cb-section p:last-child {
  margin-bottom: 0;
}

/* full-bleed white, continuing the FAQ band above it rather than dropping back
   to paper for one paragraph. The text still sits on the 640px measure — the
   padding-inline trick from .site-header holds it there without an inner box,
   and the vertical spacing is unchanged from when this sat on paper. */
.cb-disclaimer {
  background: var(--card);
  padding-block: 3rem 5rem;
  padding-inline: max(var(--gutter), (100% - var(--col-text)) / 2);
  color: var(--ink-muted);
  text-align: center;
}

/* ── Prose (legal / long-form pages) ────────────────── */

/* legal pages set everything at body weight — no display treatment beyond h1 */
.prose {
  max-width: var(--col-text);
  padding: 4rem 0 5rem;
}
.prose h1 {
  margin-bottom: 1.5rem;
}
.prose h2 {
  text-align: left;
  margin: 2.5rem 0 1rem;
}
.prose p,
.prose li {
  margin-bottom: 1rem;
}
.prose ul {
  padding-left: 1.5rem;
  margin-bottom: 1rem;
}
.prose em {
  font-style: normal;
  color: var(--ink-muted);
}
/* legal tables borrow the news table's rules: mono headers, a hairline per row */
.prose table {
  width: 100%;
  border-collapse: collapse;
  text-align: left;
  margin-bottom: 1.5rem;
}
.prose th,
.prose td {
  padding: 0.75rem 1rem 0.75rem 0;
  vertical-align: top;
}
.prose th:last-child,
.prose td:last-child {
  padding-right: 0;
}
.prose th {
  font-family: var(--mono);
  font-weight: 500;
  font-size: 0.75rem;
  line-height: 1.3;
  letter-spacing: 0.125em;
  text-transform: uppercase;
}
.prose td {
  border-top: 1px solid var(--line);
}
/* narrow screens keep the grid (stacking would lose the column labels) and
   tighten it instead */
@media (max-width: 780px) {
  .prose table {
    table-layout: fixed;
    font-size: 0.875rem;
    hyphens: auto;
    overflow-wrap: break-word;
  }
  .prose th,
  .prose td {
    padding-right: 0.75rem;
  }
}

/* ── Motion ─────────────────────────────────────────── */

.rise {
  opacity: 0;
  transform: translateY(14px);
  animation: rise 0.7s ease forwards;
  animation-delay: calc(var(--d, 0) * 110ms);
}
@keyframes rise {
  to {
    opacity: 1;
    transform: none;
  }
}

@media (prefers-reduced-motion: reduce) {
  html {
    scroll-behavior: auto;
  }
  .rise {
    animation: none;
    opacity: 1;
    transform: none;
  }
  a,
  .btn,
  .btn-secondary,
  .faq summary::after,
  .burger span {
    transition: none;
  }
}

/* ── Responsive ─────────────────────────────────────── */

@media (max-width: 1200px) {
  /* the footer's 160px logo/links gap is comp-width-specific */
  .footer-top {
    gap: 4rem;
    margin-bottom: 5rem;
  }
}

@media (max-width: 1000px) {
  .features .grid {
    grid-template-columns: repeat(2, 1fr);
  }
}

/* the three-column index gets too tight to read before the 640px breakpoint */
@media (max-width: 780px) {
  .news-table,
  .news-table tbody,
  .news-table tr,
  .news-table td {
    display: block;
    width: auto;
  }
  .news-table thead {
    display: none;
  }
  .news-table tr {
    border-top: 1px solid var(--line);
    padding: 1.5rem 0;
  }
  .news-table td {
    border-top: none;
    padding: 0;
  }
  .news-table .news-title {
    margin-top: 0.5rem;
  }
}

@media (max-width: 640px) {
  .site-header {
    gap: 1rem;
  }
  .wordmark {
    height: 21px;
  }
  .brand img {
    width: 28px;
    height: 28px;
  }
  .site-nav {
    display: none;
  }
  /* the header bar keeps only the wordmark and the toggle — Buy now moves
     into the panel, where it reads as the end of the menu rather than as a
     third thing competing for the bar */
  .site-header > .btn-small {
    display: none;
  }
  .nav-menu {
    display: block;
  }
  /* footer stacks into one left-aligned column */
  .footer-top {
    flex-direction: column;
    gap: 2.5rem;
  }
  .link-groups {
    flex-direction: column;
    gap: 2.5rem;
  }
  .features .grid {
    grid-template-columns: 1fr;
  }
  /* the labels went 15 -> 16px, which pushed the pair past the container and
     stacked them at uneven widths. Tightening the side padding keeps them
     shoulder to shoulder. */
  .btn,
  .btn-secondary {
    padding-inline: 1rem;
  }
  /* the two columns no longer fit side by side, and the button moves under
     them. The row is stacked outright rather than left to wrap: wrapping put
     the button below only on the one row tall enough to force it, so the three
     buttons landed on different sides of the page. */
  .download-row {
    flex-direction: column;
    align-items: flex-start;
  }
  .download-info {
    flex-direction: column;
    gap: 0.25rem;
  }
  .price-card {
    padding: 2rem 1.5rem;
  }
  .faq {
    padding-bottom: 6rem;
  }
  .faq summary {
    padding: 1.6rem 0;
  }
  .faq details[open] summary {
    padding-bottom: 1.25rem;
  }
  .faq details p {
    padding-bottom: 1.6rem;
  }
}
