/* ==========================================================================
   Cambium — landing page shell
   Theme tokens: dark greys + dark green (dark), green + cream (light).
   ========================================================================== */

/* Spectral SC, SIL Open Font License — see assets/fonts/OFL-Spectral.txt.
   The Ridgeway wordmark only, which is set in the 700 cut. The 500 is kept
   declared so a `font-weight` other than 700 degrades to a real face rather
   than to a synthesised one. */
@font-face {
  font-family: "Spectral SC";
  src: url("../assets/fonts/SpectralSC-Bold.ttf") format("truetype");
  font-weight: 700;
  font-style: normal;
  font-display: swap;
}

@font-face {
  font-family: "Spectral SC";
  src: url("../assets/fonts/SpectralSC-Medium.ttf") format("truetype");
  font-weight: 500;
  font-style: normal;
  font-display: swap;
}

/* Stack Sans Text, SIL Open Font License — see assets/fonts/OFL.txt.
   Only the Medium cut is shipped; it is the one weight the headings use. */
@font-face {
  font-family: "Stack Sans Text";
  src: url("../assets/fonts/StackSansText-Medium.ttf") format("truetype");
  font-weight: 500;
  font-style: normal;
  font-display: swap;
}

:root {
  --font-sans: ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI",
    Roboto, "Helvetica Neue", Arial, sans-serif;
  --font-display: "Stack Sans Text", var(--font-sans);
  --font-wordmark: "Spectral SC", ui-serif, Georgia, serif;
  --font-mono: ui-monospace, SFMono-Regular, "SF Mono", "Cascadia Code", Menlo, Consolas, monospace;

  --shell-max: 1440px;
  --shell-pad: clamp(24px, 4.2vw, 64px);
  /* The stacked screenshots stop just short of the content margins. */
  --shots-inset: 6px;
  --topbar-height: 64px;

  --radius-btn: 10px;
  --ease: cubic-bezier(0.32, 0.72, 0.35, 1);
}

/* ---------------------------------------------------------------- themes */

html[data-theme="dark"] {
  --ground: #141414;
  --band: #171B18;
  --band-edge: #232823;
  --surface: #1B201C;
  --line: #272D28;
  --line-soft: #1F251F;

  --text: #E7EBE5;
  --text-dim: #A3AC9E;
  --text-faint: #79826F;

  --accent: #63BC85;
  --accent-hover: #86CE9F;
  --accent-solid: #2E7248;
  --accent-solid-hover: #378554;
  --accent-on-solid: #F1F7F1;
  --accent-line: rgba(99, 188, 133, 0.42);
  --accent-soft: rgba(99, 188, 133, 0.13);
  --stamp: #E4756A;
  --stamp-line: rgba(228, 117, 106, 0.6);
  --stamp-soft: rgba(228, 117, 106, 0.12);
  /* Documentation hints, in the client's own Modified orange
     (--status-orange in app.css) so a hint reads as the app talking. */
  --hint: #E2A54E;
  --hint-line: rgba(226, 165, 78, 0.5);
  --hint-soft: rgba(226, 165, 78, 0.1);

  --ring-ink: rgba(122, 194, 152, 0.2);
  --topbar-bg: rgba(20, 20, 20, 0.84);
  /* An offset-free, wide-blur ambient layer is what wraps the window on all
     four sides; the small offset layers only ground it. Negative spread or a
     blur that is small next to the window reads as a hard rectangular band. */
  /* Outline buttons sit on the ground colour so they read as surfaces rather
     than holes, including where they overlap the graphic band. */
  --btn-ghost-bg: #141414;
  --btn-ghost-bg-hover: #1F2420;
  /* The prose card borrows the client's own panel greys in dark mode: the
     availability week bar's fill and the panel-frame outline. */
  --card-bg: #333333;
  --card-line: #5A5A5A;
  /* Code boxes sit below the page rather than on it: almost black, darker than
     the --ground they are drawn on. Shares the palette's existing near-black. */
  --code-bg: #0E100E;
  --shot-ph-bg: #0E100E;
  --shadow-demo: 0 0 0 1px rgba(255, 255, 255, 0.07), 0 1px 3px rgba(0, 0, 0, 0.6),
    0 12px 32px rgba(0, 0, 0, 0.5), 0 0 72px 10px rgba(0, 0, 0, 0.6);
  --focus: #63BC85;
}

html[data-theme="light"] {
  /* Linen: a warm, slightly darker cream for the page, with the graphic band
     dropped further and pulled toward green so the ring lines read. */
  --ground: #EFEADA;
  --band: #E2E1CD;
  --band-edge: #D2D2B9;
  --surface: #F5F1E2;
  --line: #D6D3BE;
  --line-soft: #E2DECB;

  --text: #1A1F1A;
  --text-dim: #515A4C;
  --text-faint: #77806F;

  --accent: #2C6B45;
  --accent-hover: #23583A;
  --accent-solid: #2C6B45;
  --accent-solid-hover: #23583A;
  --accent-on-solid: #F3EFE1;
  --accent-line: rgba(44, 107, 69, 0.34);
  --accent-soft: rgba(44, 107, 69, 0.09);
  --stamp: #A8443B;
  --stamp-line: rgba(168, 68, 59, 0.55);
  --stamp-soft: rgba(168, 68, 59, 0.08);
  /* A darker cut of the same orange: #E2A54E as text on cream is about 2:1,
     which no amount of good intentions makes readable. */
  --hint: #8A5A12;
  --hint-line: rgba(138, 90, 18, 0.42);
  --hint-soft: rgba(138, 90, 18, 0.09);

  --btn-ghost-bg: #EFEADA;
  --btn-ghost-bg-hover: #F7F3E6;
  --card-bg: #F5F1E2;
  --card-line: #E2DECB;
  /* Unchanged from --card-bg / --surface: the light theme's boxes were right. */
  --code-bg: #F5F1E2;
  --shot-ph-bg: #E3DECC;
  --ring-ink: rgba(38, 88, 54, 0.26);
  --topbar-bg: rgba(239, 234, 218, 0.86);
  --shadow-demo: 0 0 0 1px rgba(30, 45, 34, 0.12), 0 1px 3px rgba(30, 45, 34, 0.12),
    0 12px 30px rgba(30, 45, 34, 0.16), 0 0 72px 10px rgba(30, 45, 34, 0.15);
  --focus: #2C6B45;
}

/* ------------------------------------------------------------- baseline */

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

html {
  -webkit-text-size-adjust: 100%;
  scroll-behavior: smooth;
}

/* In-page jumps must clear the sticky bar. */
[id] { scroll-margin-top: calc(var(--topbar-height) + 20px); }

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
}

body {
  margin: 0;
  background: var(--ground);
  color: var(--text);
  font-family: var(--font-sans);
  font-size: 16px;
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  overflow-x: hidden;
}

h1, h2, h3, p { margin: 0; }

a { color: inherit; text-decoration: none; }

/* Beats component rules that set their own display. */
[hidden] { display: none !important; }

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

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

.shell {
  width: 100%;
  max-width: var(--shell-max);
  margin: 0 auto;
  padding-left: var(--shell-pad);
  padding-right: var(--shell-pad);
}

/* ================================================================ top bar
   Its own bar above the graphic field, and it stays put on scroll.       */

.topbar {
  position: sticky;
  top: 0;
  z-index: 60;
  background: var(--topbar-bg);
  border-bottom: 1px solid var(--line-soft);
  backdrop-filter: saturate(160%) blur(12px);
  -webkit-backdrop-filter: saturate(160%) blur(12px);
}

/* Cambium at one end, nav at the other. The bar used to run three tracks with
   the Ridgeway mountain leading and the wordmark centred on the page; the
   mountain is gone from the bar now — the footer lockup is the way back to the
   company home — and Cambium has taken its place at the head of the row. */
.topbar-inner {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 24px;
  height: var(--topbar-height);
}

/* The mountain is black artwork on transparency, shown at two sizes. An
   <img> inverted per theme rather than a mask: a mask can only take an inlined
   data URI (a file URL is blocked over file://), and the home page's hero
   version is far too large to inline. */
.ridgeway-mark {
  display: block;
  width: auto;
}

html[data-theme="dark"] .ridgeway-mark { filter: invert(1); }

.brand {
  display: inline-flex;
  align-items: center;
  gap: 12px;
  min-width: 0;
}

.brand-icon {
  display: block;
  width: 28px;
  height: 28px;
  flex: none;
}

.brand-name {
  font-family: var(--font-display);
  font-size: 21px;
  font-weight: 500;
  letter-spacing: -0.015em;
  line-height: 1;
}

.topnav {
  display: flex;
  align-items: center;
  gap: 30px;
  font-size: 14.5px;
  color: var(--text-dim);
}

.topnav a { transition: color 0.15s var(--ease); }
.topnav a:hover { color: var(--text); }

/* =================================================================== band */

.band {
  position: relative;
  isolation: isolate;
  background: var(--band);
  border-bottom: 1px solid var(--band-edge);
  overflow: hidden;
}

/* The ring field covers the whole band; its centre sits left of centre and the
   outermost ring is repeated outward so the pattern carries across the width.
   The SVG is inline in the page and tinted through currentColor, and its own
   fade is an SVG <mask> — nothing here depends on CSS masking or on one local
   file being allowed to reference another. */
.band-rings {
  position: absolute;
  inset: 0;
  z-index: -1;
  overflow: hidden;
  pointer-events: none;
  color: var(--ring-ink);
}

.band-rings svg {
  position: absolute;
  left: 24%;
  top: 46%;
  /* --rings-x / --rings-y let a shorter band move the centre off-screen. */
  left: var(--rings-x, 24%);
  top: var(--rings-y, 46%);
  width: clamp(3400px, 250vw, 6000px);
  aspect-ratio: 1 / 1;
  height: auto;
  transform: translate(-50%, -50%);
  display: block;
}

/* ---------------------------------------------------------------- hero */

.hero {
  position: relative;
  z-index: 1;
  /* The preview reserves its own 80px of shadow room below, so the band's
     own bottom padding is trimmed to keep the spacing even. */
  padding: clamp(44px, 5.5vw, 78px) 0 clamp(8px, 1.5vw, 24px);
}

.hero-head {
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  gap: clamp(28px, 4vw, 64px);
  flex-wrap: wrap;
}

.hero-title {
  font-family: var(--font-display);
  font-size: clamp(1.9rem, 2.9vw, 2.55rem);
  font-weight: 500;
  letter-spacing: -0.022em;
  line-height: 1.16;
  text-wrap: balance;
}

.hero-word {
  display: flex;
  align-items: center;
  gap: 0.24em;
  font-size: 1.5em;
  line-height: 1.06;
  letter-spacing: -0.028em;
  margin-bottom: 0.06em;
}

.beta-tag {
  font-family: var(--font-mono);
  font-size: 0.44em;
  font-weight: 600;
  letter-spacing: 0.02em;
  line-height: 1;
  color: var(--stamp);
  background: var(--stamp-soft);
  border: 2px solid var(--stamp-line);
  border-radius: 0.3em;
  padding: 0.26em 0.42em 0.28em;
  /* Optically centres the tag against the wordmark's cap height rather than
     its line box, which sits low because of the descender space. */
  transform: translateY(-0.1em);
}

/* Three buttons on a two-column grid: the download spans the full width of
   the pair beneath it, and the pair share that width evenly. */
.hero-actions {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 12px;
  padding-bottom: 6px;
}

.hero-actions .btn--primary { grid-column: 1 / -1; }

/* ------------------------------------------------- interactive preview */

/* Full-bleed so the window's shadow has room on both sides; js/demo.js sizes
   the window itself to the hero text's own width and centres it there. */
.hero-demo {
  width: 100%;
  margin-top: clamp(4px, 1vw, 16px);
}

/* A scroll container clips at its box, so the window's shadow needs room
   inside it — js/demo.js reserves SHADOW_ROOM above, below and to the sides. */
.demo-viewport {
  overflow-x: auto;
  overflow-y: hidden;
  scrollbar-width: none;
  -webkit-overflow-scrolling: touch;
}

.demo-viewport::-webkit-scrollbar { display: none; }

.demo-scaler {
  transform-origin: top left;
  will-change: transform;
}

/* ================================================================== body */

.intro {
  padding: clamp(64px, 7.5vw, 104px) 0 clamp(72px, 8vw, 120px);
}

.section-title {
  font-family: var(--font-display);
  font-size: clamp(1.6rem, 2.4vw, 2.1rem);
  font-weight: 500;
  letter-spacing: -0.022em;
  line-height: 1.15;
  margin-bottom: 22px;
}

.intro-grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: clamp(36px, 4.5vw, 80px);
  align-items: start;
}

.intro-action { margin-top: 20px; }

.text-link {
  color: var(--accent);
  font-weight: 550;
  transition: color 0.15s var(--ease);
}

.text-link:hover {
  color: var(--accent-hover);
  text-decoration: underline;
  text-underline-offset: 3px;
}

.text-link-arrow {
  display: inline-block;
  margin-left: 0.45em;
  transition: transform 0.15s var(--ease);
}

.text-link:hover .text-link-arrow { transform: translateX(2px); }

.intro-lede {
  max-width: 54ch;
  font-size: clamp(1.02rem, 1.15vw, 1.16rem);
  line-height: 1.72;
  color: var(--text-dim);
  text-wrap: pretty;
}

/* ------------------------------------------------------------- buttons */

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-height: 46px;
  padding: 0 24px;
  border-radius: var(--radius-btn);
  border: 1px solid transparent;
  font-size: 14.5px;
  font-weight: 550;
  letter-spacing: -0.005em;
  white-space: nowrap;
  cursor: pointer;
  transition: background 0.15s var(--ease), border-color 0.15s var(--ease),
    color 0.15s var(--ease), transform 0.15s var(--ease);
}

.btn:active { transform: translateY(1px); }

.btn--lg {
  min-height: 60px;
  padding: 0 34px;
  font-size: 1rem;
  border-radius: 12px;
}

.btn--primary {
  background: var(--accent-solid);
  color: var(--accent-on-solid);
}

.btn--primary:hover { background: var(--accent-solid-hover); }

.btn--ghost {
  border-color: var(--line);
  color: var(--text);
  background: var(--btn-ghost-bg);
}

.btn--ghost:hover {
  border-color: var(--text-faint);
  background: var(--btn-ghost-bg-hover);
}

/* ================================================== designed for artists */

.artists {
  border-top: 1px solid var(--line);
  padding: clamp(56px, 6.5vw, 92px) 0 clamp(72px, 8vw, 118px);
}

.artists-copy {
  margin-top: clamp(36px, 4vw, 56px);
  background: var(--card-bg);
  border: 1px solid var(--card-line);
  border-radius: 16px;
  padding: clamp(26px, 3vw, 44px);
}

.artists-copy .section-title { margin-bottom: 20px; }

/* Full bleed to the content margins — the long measure is the point, setting
   this block apart from the two-column one above. */
.artists-paras {
  display: flex;
  flex-direction: column;
  gap: 20px;
}

.artists-paras .intro-lede { max-width: none; }

/* ---- the stacked screenshots ---- */

.shot-stack {
  position: relative;
  width: calc(100% - var(--shots-inset) * 2);
  margin: 0 auto;
}

/* Both windows are the same size. The front is offset up and to the left so it
   covers all of the back's repository panel bar a sliver of the file tree's
   right-hand columns, and leaves the graph panel whole. */
.shot-stack-inner {
  position: relative;
  width: 1704px;
  height: 870px;
  transform-origin: top left;
}

/* Compounded with .app-mock so these beat its own 1440×900 design size —
   app.css loads after this file. */
.shot {
  position: absolute;
  border-radius: 10px;
  /* Each window must be its own stacking context. Without one, the panel
     border (z-index 55) and the workspace tab strip (z-index 10) inside the
     BACK window escape into the shared context and paint over the front one. */
  isolation: isolate;
}

/* Back: the revision page with the graph open. The graph panel is never
   covered, and a band of the file tree stays visible below the front window. */
.app-mock.shot--back {
  right: 0;
  bottom: 0;
  width: 1160px;
  height: 720px;
  z-index: 1;
}

/* Front: the same project's organization page, overlapping the back window's
   top-left corner. */
.app-mock.shot--front {
  left: 0;
  top: 0;
  width: 1160px;
  height: 720px;
  z-index: 2;
}

/* ============================================================= downloads */

/* Sprite of platform glyphs, inlined at the top of the page. */
.icon-sprite {
  position: absolute;
  width: 0;
  height: 0;
  overflow: hidden;
}

.band--slim {
  --rings-x: 50%;
  --rings-y: -30%;
}

/* Mid-page band, about half the header's height. */
.band--strip {
  --rings-x: 50%;
  --rings-y: -70%;
  border-top: 1px solid var(--band-edge);
}

/* The field is declared once in a hidden sprite and <use>d by each band. */
.ring-sprite {
  position: absolute;
  width: 0;
  height: 0;
  overflow: hidden;
}

/* Heading and sentence sit side by side, which is what keeps this band to
   half the page header's height. */
.page-strip {
  position: relative;
  z-index: 1;
  padding: clamp(24px, 2.4vw, 34px) 0;
}

.page-strip .shell {
  display: flex;
  align-items: baseline;
  gap: clamp(20px, 2.6vw, 48px);
  flex-wrap: wrap;
}

.strip-title {
  flex: none;
  font-family: var(--font-display);
  font-size: clamp(1.3rem, 1.8vw, 1.6rem);
  font-weight: 500;
  letter-spacing: -0.022em;
  line-height: 1.2;
}

.strip-text {
  flex: 1 1 420px;
  max-width: 90ch;
  color: var(--text-dim);
  line-height: 1.68;
  text-wrap: pretty;
}

/* The band already draws its own edge; a second one under it doubles up. */
.band + .shell > .guide:first-child { border-top: 0; }

.page-hero {
  position: relative;
  z-index: 1;
  padding: clamp(44px, 5.5vw, 78px) 0 clamp(44px, 5vw, 72px);
}

/* The button shares the title's row so it sits level with the word, with the
   version line dropping beneath both. */
.page-hero-inner {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: clamp(24px, 4vw, 56px);
  flex-wrap: wrap;
}

.page-version {
  margin-top: 12px;
  font-family: var(--font-mono);
  font-size: 0.95rem;
  letter-spacing: 0.01em;
  color: var(--text-faint);
}

.page-title {
  font-family: var(--font-display);
  font-size: clamp(2.1rem, 3.4vw, 3rem);
  font-weight: 500;
  letter-spacing: -0.028em;
  line-height: 1.1;
}

.page-lede {
  margin-top: 16px;
  max-width: 58ch;
  font-size: clamp(1rem, 1.1vw, 1.1rem);
  line-height: 1.68;
  color: var(--text-dim);
  text-wrap: pretty;
}

.release {
  padding: clamp(36px, 4vw, 56px) 0;
  border-top: 1px solid var(--line);
}

/* Same three columns as the option grid below, so the licensing note starts
   on the "Compile From Source" column and tops out level with the blurb. */
.release-head {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  column-gap: clamp(24px, 3vw, 44px);
  /* No row gap: the blurb and the note both carry their own top margin, which
     is what keeps their first lines level. */
  row-gap: 0;
  align-items: start;
}

.release-head > .release-title { grid-column: 1 / -1; }
.release-head > .release-blurb { grid-column: 1 / 3; }
.release-head > .release-note { grid-column: 3; }

/* A documentation-style hint inside an option grid, spanning the last two
   columns and sitting in the space their one-row groups leave. .doc-note does
   the dressing; this only places it.

   The first group takes both rows so nothing overlaps — without that the hint's
   row would push the tall Installers list around. `align-self: end` closes the
   box up against the bottom of that list rather than leaving it adrift.

   Scoped through the grid rather than left bare because `.doc-note` is declared
   later in this file and would win the margin-top on equal specificity. */
.option-grid:has(> .option-hint) > .option-group:nth-of-type(1) {
  grid-column: 1;
  grid-row: 1 / span 2;
}

.option-grid:has(> .option-hint) > .option-group:nth-of-type(2) {
  grid-column: 2;
  grid-row: 1;
}

.option-grid:has(> .option-hint) > .option-group:nth-of-type(3) {
  grid-column: 3;
  grid-row: 1;
}

.option-grid > .option-hint {
  grid-column: 2 / -1;
  grid-row: 2;
  align-self: end;
  margin-top: 0;
  font-size: 0.92rem;
}

/* Links in a hint keep the hint's colour and their underline — the two on the
   downloads warning are the way out of a problem the reader is having right
   then, so they should look like the exits they are. */
.doc-note a {
  color: var(--hint);
  text-decoration: underline;
  text-underline-offset: 3px;
}

.doc-note a:hover { color: var(--text); }

/* A hint that is not advice but a warning: the whole box in --stamp red rather
   than the documentation's orange. The fill is the same hue at a fraction of
   the outline's strength, so it reads as a tint and never competes with the
   text on it. Both tokens are the site's own; nothing is invented for one box.

   Compounded as `.doc-note.doc-note--alarm` deliberately — `.doc-note` is
   declared after this in the file, and at equal specificity it would win every
   property this modifier is trying to change. */
.doc-note.doc-note--alarm {
  color: var(--stamp);
  border-color: var(--stamp-line);
  background: var(--stamp-soft);
}

.doc-note.doc-note--alarm a { color: var(--stamp); }


.release-title {
  font-family: var(--font-display);
  font-size: clamp(1.45rem, 2.1vw, 1.9rem);
  font-weight: 500;
  letter-spacing: -0.024em;
  line-height: 1.2;
}

.release-version {
  font-family: var(--font-mono);
  font-size: 0.6em;
  font-weight: 400;
  letter-spacing: 0;
  color: var(--text-faint);
  margin-left: 0.45em;
  vertical-align: 0.12em;
}

.release-note {
  margin-top: 12px;
  font-style: italic;
  font-size: 0.92rem;
  line-height: 1.62;
  color: var(--text-faint);
  text-wrap: pretty;
}

.release-blurb {
  margin-top: 12px;
  max-width: 62ch;
  color: var(--text-dim);
  line-height: 1.68;
  text-wrap: pretty;
}

.release code,
.guide code {
  font-family: var(--font-mono);
  font-size: 0.88em;
  background: var(--accent-soft);
  border-radius: 4px;
  padding: 0.1em 0.34em;
}

.option-grid {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: clamp(24px, 3vw, 44px);
  margin-top: clamp(26px, 3vw, 38px);
}

.option-heading {
  font-size: 0.78rem;
  font-weight: 600;
  letter-spacing: 0.09em;
  text-transform: uppercase;
  color: var(--text-faint);
  padding-bottom: 10px;
  border-bottom: 1px solid var(--line);
}

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

.option {
  display: flex;
  align-items: center;
  gap: 14px;
  padding: 11px 0;
  border-bottom: 1px solid var(--line-soft);
}

/* Every value in a list starts on the same line. Each row is its own box, so
   with plain flex each one measures its own label and the value column comes
   out ragged — "Download" landing in a different place on every line. Subgrid
   hands the rows the list's column widths instead, sized to the longest label
   in that list and no wider, which a fixed width could not do without either
   clipping a long label or wasting space in front of a short one. Without
   subgrid support the flex rules above still apply, ragged but intact. */
@supports (grid-template-columns: subgrid) {
  .option-list {
    display: grid;
    grid-template-columns: max-content minmax(0, 1fr);
  }

  .option {
    display: grid;
    grid-column: 1 / -1;
    grid-template-columns: subgrid;
    column-gap: 14px;
  }
}

.option-label {
  display: flex;
  align-items: center;
  gap: 8px;
  flex: none;
  min-width: 7rem;
  font-size: 0.82rem;
  color: var(--text-faint);
}

/* Rows without a glyph (Homebrew, "All platforms") keep the empty slot so
   every column's labels start on the same line. */
.option-icon {
  width: 15px;
  height: 15px;
  flex: none;
  display: block;
  color: var(--text-faint);
}

.option-link {
  color: var(--accent);
  font-weight: 550;
  font-size: 0.95rem;
  transition: color 0.15s var(--ease);
}

.option-link:hover {
  color: var(--accent-hover);
  text-decoration: underline;
  text-underline-offset: 3px;
}

.option-soon {
  font-size: 0.95rem;
  color: var(--text-faint);
}

/* The Intel builds: still shipped, no longer the ones to reach for. Dimmed as a
   whole — label, glyph and the Download link with them — and back to full
   strength on hover or keyboard focus, so the row is never dim while it is the
   thing being used. */
.option--legacy {
  opacity: 0.6;
  transition: opacity 0.15s var(--ease);
}

.option--legacy:hover,
.option--legacy:focus-within {
  opacity: 1;
}

/* The label carries no action, so it can take a little more than the link. */
.option--legacy .option-label { opacity: 0.9; }

/* ---- install commands ----
   The CLI's one-liners. Each sits in the value column of an ordinary option row,
   standing where the Download link stands in the other sections — so the rows,
   the hairlines and the label column are the list's, not this control's, and the
   field is only ever as wide as that column. Dressed like a documentation code
   block, because it is the same kind of object: something you read and then run.
   Compact enough to read as a control rather than a code listing. */

.install-cmd {
  display: flex;
  align-items: center;
  gap: 6px;
  min-width: 0;
  padding: 5px 5px 5px 11px;
  /* One hairline all the way round. Every code box used to carry a 2px accent
     edge on the left, which made them all asymmetric for no reason. */
  border: 1px solid var(--line);
  border-radius: 8px;
  background: var(--code-bg);
}

/* Scoped one level deeper than `.release code`, which would otherwise win on
   specificity and paint its green inline-code pill inside the card. */
.install-cmd .install-cmd-line {
  flex: 1;
  min-width: 0;
  background: none;
  border-radius: 0;
  padding: 0 0 2px;
  overflow-x: auto;
  white-space: pre;
  font-family: var(--font-mono);
  font-size: 0.8rem;
  line-height: 1.6;
  color: var(--text);
  /* Left at its default the thumb is a bright bar directly under the command
     and reads as an underline. Toned to the hairline colour it reads as what it
     is: a hint that the line continues. */
  scrollbar-width: thin;
  scrollbar-color: var(--line) transparent;
}

.install-cmd .install-cmd-line::-webkit-scrollbar { height: 5px; }
.install-cmd .install-cmd-line::-webkit-scrollbar-track { background: transparent; }

.install-cmd .install-cmd-line::-webkit-scrollbar-thumb {
  background: var(--line);
  border-radius: 3px;
}

.install-cmd-copy {
  flex: none;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 24px;
  height: 24px;
  padding: 0;
  border: 1px solid var(--line);
  border-radius: 6px;
  background: transparent;
  color: var(--text-faint);
  cursor: pointer;
  transition: color 0.15s var(--ease), border-color 0.15s var(--ease);
}

.install-cmd-copy:hover {
  color: var(--text);
  border-color: var(--accent-line);
}

.install-cmd-copy-icon {
  display: block;
  width: 13px;
  height: 13px;
  fill: currentColor;
}

/* js/site.js sets data-done for a moment after a copy; the tick replaces the
   glyph rather than the label, since the button has no text to swap. */
.install-cmd-copy-icon--done { display: none; }
.install-cmd-copy[data-done] { color: var(--accent); border-color: var(--accent-line); }
.install-cmd-copy[data-done] .install-cmd-copy-icon { display: none; }
.install-cmd-copy[data-done] .install-cmd-copy-icon--done { display: block; }

.guide {
  padding: clamp(32px, 3.6vw, 52px) 0;
  border-top: 1px solid var(--line);
}

.guide:last-child { padding-bottom: clamp(64px, 8vw, 110px); }

.guide-title {
  font-family: var(--font-display);
  font-size: clamp(1.25rem, 1.7vw, 1.5rem);
  font-weight: 500;
  letter-spacing: -0.02em;
}

.guide-note {
  margin-top: 12px;
  max-width: 62ch;
  color: var(--text-faint);
  font-style: italic;
  line-height: 1.68;
}

.steps {
  margin: 26px 0 0;
  padding: 0;
  list-style: none;
  counter-reset: step;
  display: flex;
  flex-direction: column;
  gap: 22px;
  max-width: 74ch;
}

.step {
  counter-increment: step;
  position: relative;
  padding-left: 40px;
}

.step::before {
  content: counter(step);
  position: absolute;
  left: 0;
  top: 0;
  width: 24px;
  height: 24px;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: 50%;
  border: 1px solid var(--line);
  background: var(--surface);
  font-family: var(--font-mono);
  font-size: 0.75rem;
  color: var(--text-faint);
}

.step-text {
  color: var(--text-dim);
  line-height: 1.62;
  text-wrap: pretty;
}

.step-code {
  margin: 10px 0 0;
  padding: 12px 14px;
  overflow-x: auto;
  border: 1px solid var(--line);
  border-radius: 8px;
  background: var(--code-bg);
  font-family: var(--font-mono);
  font-size: 0.82rem;
  line-height: 1.6;
  color: var(--text);
  white-space: pre;
}

/* The block already carries the code background; the inline-code chip rule
   must not paint a second one inside it. */
.step-code code {
  font: inherit;
  background: none;
  padding: 0;
  border-radius: 0;
}

/* ========================================================= documentation */

.docs-grid {
  display: grid;
  grid-template-columns: 232px minmax(0, 1fr);
  gap: clamp(32px, 4vw, 72px);
  align-items: start;
  padding-top: clamp(40px, 4.5vw, 64px);
  padding-bottom: clamp(72px, 8vw, 118px);
}

/* ---- sidebar ---- */

/* overflow-y on one axis makes the other axis clip too, which was shearing the
   left corners off the link highlight (it bleeds 10px past the text). The box
   is widened leftwards by exactly that bleed and the padding puts the content
   back where it was, so nothing moves and nothing is cut. */
.docs-nav {
  position: sticky;
  top: calc(var(--topbar-height) + 28px);
  align-self: start;
  max-height: calc(100vh - var(--topbar-height) - 56px);
  overflow-y: auto;
  margin-left: -10px;
  padding-left: 10px;
}

.docs-nav-heading {
  font-size: 0.74rem;
  font-weight: 600;
  letter-spacing: 0.09em;
  text-transform: uppercase;
  color: var(--text-faint);
  padding-bottom: 9px;
  border-bottom: 1px solid var(--line);
}

.docs-nav-heading + .docs-nav-list { margin-bottom: 26px; }

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

.docs-nav-link {
  display: block;
  padding: 6px 10px;
  margin-left: -10px;
  border-radius: 7px;
  font-size: 0.9rem;
  line-height: 1.4;
  color: var(--text-dim);
  transition: color 0.15s var(--ease), background 0.15s var(--ease);
}

.docs-nav-link:hover {
  color: var(--text);
  background: color-mix(in srgb, var(--text) 6%, transparent);
}

.docs-nav-link--current {
  color: var(--accent);
  font-weight: 550;
  background: var(--accent-soft);
}

/* ---- article ---- */

.docs-article {
  min-width: 0;
  max-width: 78ch;
  padding-left: 0.4em;
}

.doc-title {
  font-family: var(--font-display);
  font-size: clamp(1.7rem, 2.4vw, 2.15rem);
  font-weight: 500;
  letter-spacing: -0.024em;
  line-height: 1.15;
}

.doc-lead {
  margin-top: 12px;
  font-size: clamp(1.02rem, 1.15vw, 1.14rem);
  line-height: 1.66;
  color: var(--text-dim);
  text-wrap: pretty;
}

.doc-heading {
  font-family: var(--font-display);
  font-size: clamp(1.12rem, 1.5vw, 1.32rem);
  font-weight: 500;
  letter-spacing: -0.018em;
  margin-top: 40px;
}

.docs-article p {
  margin-top: 16px;
  line-height: 1.72;
  color: var(--text-dim);
  text-wrap: pretty;
}

.docs-article strong { color: var(--text); font-weight: 600; }

.doc-list,
.doc-steps {
  margin: 16px 0 0;
  padding-left: 1.35rem;
  display: flex;
  flex-direction: column;
  gap: 10px;
  line-height: 1.7;
  color: var(--text-dim);
}

.doc-list { list-style: none; padding-left: 0; }

.doc-list > li {
  position: relative;
  padding-left: 1.35rem;
}

.doc-list > li::before {
  content: "";
  position: absolute;
  left: 0.1rem;
  top: 0.85em;
  width: 0.5rem;
  height: 1px;
  background: var(--accent);
  opacity: 0.75;
}

.doc-steps > li::marker {
  color: var(--text-faint);
  font-family: var(--font-mono);
  font-size: 0.85em;
}

/* The chip's padding sits outside the text origin, so a code span at the start
   of a line had its left corner shaved off. The article is nudged in by that
   much, and `clone` gives both halves of a wrapped span their own corners. */
.docs-article code {
  font-family: var(--font-mono);
  font-size: 0.86em;
  background: var(--accent-soft);
  border-radius: 4px;
  padding: 0.1em 0.34em;
  word-break: break-word;
  -webkit-box-decoration-break: clone;
  box-decoration-break: clone;
}

.doc-code {
  margin: 14px 0 0;
  padding: 13px 15px;
  overflow-x: auto;
  border: 1px solid var(--line);
  border-radius: 9px;
  background: var(--code-bg);
  font-family: var(--font-mono);
  font-size: 0.82rem;
  line-height: 1.65;
  color: var(--text);
  white-space: pre;
}

.doc-code code {
  font: inherit;
  background: none;
  padding: 0;
  border-radius: 0;
}

/* ---- callout ----
   Orange throughout, so a hint is never mistaken for a code block: those keep
   the grey card background and the green edge, and these carry neither. */

.doc-note {
  display: block;
  margin-top: 22px;
  padding: 16px 18px;
  border: 1px solid var(--hint-line);
  border-radius: 12px;
  background: var(--hint-soft);
  font-size: 0.95rem;
  line-height: 1.66;
  color: var(--hint);
}

/* The bolded lead-in would otherwise revert to --text and break the wash. */
.doc-note strong { color: var(--hint); }

/* Inline code inside a hint: the green tint fights the orange. */
.doc-note code {
  background: var(--hint-soft);
  color: var(--hint);
}

/* ---- tables ---- */

.doc-table-wrap {
  margin-top: 20px;
  overflow-x: auto;
  border: 1px solid var(--line);
  border-radius: 12px;
}

.doc-table {
  width: 100%;
  border-collapse: collapse;
  font-size: 0.92rem;
}

.doc-table th,
.doc-table td {
  text-align: left;
  padding: 11px 14px;
  border-bottom: 1px solid var(--line-soft);
  vertical-align: top;
  line-height: 1.6;
}

.doc-table thead th {
  font-size: 0.74rem;
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--text-faint);
  background: var(--card-bg);
  border-bottom: 1px solid var(--line);
  white-space: nowrap;
}

.doc-table td { color: var(--text-dim); }
.doc-table tbody tr:last-child td { border-bottom: none; }
.doc-table td:first-child { color: var(--text); }

/* ---- status chips ---- */

.doc-chip {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  white-space: nowrap;
  font-weight: 500;
}

.doc-chip svg {
  width: 13px;
  height: 13px;
  flex: none;
}

.doc-table td:first-child:has(.doc-chip) { white-space: nowrap; }

/* ---- screenshot placeholders ---- */

.doc-shot {
  display: flex;
  align-items: center;
  justify-content: center;
  margin: 22px 0 0;
  padding: clamp(48px, 7vw, 84px) 20px;
  border: 1px solid var(--card-line);
  border-radius: 16px;
  background: var(--shot-ph-bg);
  text-align: center;
}

.doc-shot-label {
  font-size: 0.88rem;
  font-style: italic;
  color: var(--text-faint);
}

/* =================================================================== footer */

/* Monospace throughout — the wordmark is artwork and keeps its own face. */
.site-footer {
  border-top: 1px solid var(--line);
  padding: 22px 0;
  font-family: var(--font-mono);
}

/* Brand, links and copyright share one line, so the footer is only as tall as
   the brand lockup. The links used to be two headed columns stacked under
   nothing, which made the footer three times the height it needed and left the
   middle of the row empty. */
.footer-inner {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: clamp(20px, 3vw, 48px);
  flex-wrap: wrap;
}

/* ---- the lockup (footer and Ridgeway home both) ----
   Range and wordmark side by side, reading as one object because they start and
   stop on exactly the same two lines: the mark is set to the wordmark's cap
   height, and baseline alignment drops its base onto the baseline. Nothing has
   to be fudged at either end — the artwork's ink touches all four edges of its
   frame, so the image's box and the mountain's silhouette are the same thing,
   and RIDGEWAY in small caps has no descender, so its ink bottom is the
   baseline.

   The size lives on the container rather than the wordmark, so the mark's `em`
   height resolves against the same font-size the text is set in. */

.footer-brand,
.home-brand {
  display: flex;
  align-items: baseline;
  gap: 0.3em;
  width: max-content;
  max-width: 100%;
}

/* 0.676em is Spectral SC's cap height, measured off a render rather than taken
   from the font's metrics. A replaced element's baseline is its bottom margin
   edge, which is what lands the range's base on the wordmark's baseline. */
.footer-brand .ridgeway-mark,
.home-brand .ridgeway-mark {
  height: 0.676em;
  width: auto;
}

.footer-wordmark,
.home-wordmark {
  font-size: 1em;
  font-family: var(--font-wordmark);
  font-weight: 700;
  line-height: 1;
  letter-spacing: 0.08em;
  /* Letter-spacing lands after the last glyph too. Taking it back off the right
     keeps the lockup's box tight to the Y instead of trailing a space. */
  margin-right: -0.08em;
  white-space: nowrap;
  color: var(--text);
}

.footer-brand { font-size: 22px; }

/* ---- links ----
   One row, two groups. The hairline does the job the column headings used to:
   it keeps Projects and Resources reading as two sets. */

.footer-links {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
}

.footer-list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  align-items: center;
  gap: clamp(16px, 1.8vw, 26px);
}

.footer-list + .footer-list {
  margin-left: clamp(16px, 1.8vw, 26px);
  padding-left: clamp(16px, 1.8vw, 26px);
  border-left: 1px solid var(--line);
}

.footer-list a,
.footer-list button {
  font-family: inherit;
  font-size: 0.8rem;
  line-height: 1.5;
  letter-spacing: 0.02em;
  color: var(--text-dim);
  background: none;
  border: 0;
  padding: 0;
  text-align: left;
  cursor: pointer;
  transition: color 0.15s var(--ease);
}

.footer-list a:hover,
.footer-list button:hover { color: var(--text); }

.footer-legal {
  margin: 0;
  font-size: 0.72rem;
  line-height: 1.5;
  letter-spacing: 0.02em;
  color: var(--text-faint);
  text-align: right;
}

/* ============================================================= ridgeway home */

/* Brand on the top quarter line, quote on the bottom third, nothing between. */
.home {
  min-height: 100vh;
  display: grid;
  grid-template-rows: 25vh auto 1fr auto 25vh;
  justify-items: center;
  padding: 0 var(--shell-pad);
  text-align: center;
}

/* Shape and lockup tuning are shared with the footer brand, up in the footer
   block; only the grid placement and the size are the home page's own. The
   lockup is a single nowrap row now, so it is the width the page has to hold —
   hence a clamp rather than a fixed size. */
.home-brand {
  grid-row: 2;
  font-size: clamp(28px, 5.4vw, 46px);
}

.home-tagline {
  grid-row: 4;
  align-self: end;
  margin: 0;
  font-family: var(--font-mono);
  font-size: clamp(0.86rem, 1.1vw, 1rem);
  line-height: 1.6;
  letter-spacing: 0.01em;
  color: var(--text-dim);
}

/* A page that has nothing on it yet: one centred line under the band, with
   enough room above and below that the footer does not ride up to meet it. */
.page-message {
  padding: clamp(72px, 11vw, 150px) 0;
  text-align: center;
  color: var(--text-dim);
  font-size: clamp(1rem, 1.2vw, 1.15rem);
  line-height: 1.68;
  text-wrap: pretty;
}

/* ================================================================ source
   The two license summaries and the full text under them. Everything above
   them on that page is the downloads page's own release/option grid.      */

/* Two cards, one per license, on the same margins as the option grid. */
.license-grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: clamp(24px, 3vw, 44px);
  margin-top: clamp(26px, 3vw, 38px);
}

.license-card {
  background: var(--card-bg);
  border: 1px solid var(--card-line);
  border-radius: 16px;
  padding: clamp(22px, 2.4vw, 32px);
}

.license-kicker {
  font-size: 0.78rem;
  font-weight: 600;
  letter-spacing: 0.09em;
  text-transform: uppercase;
  color: var(--text-faint);
}

.license-name {
  margin-top: 8px;
  font-family: var(--font-display);
  font-size: clamp(1.1rem, 1.5vw, 1.3rem);
  font-weight: 500;
  letter-spacing: -0.02em;
  line-height: 1.25;
}

.license-basis {
  margin-top: 8px;
  font-size: 0.9rem;
  font-style: italic;
  color: var(--text-faint);
}

/* "You may" / "You may not" — these carry the meaning of the ✓ and ✗ marks
   below them, which are decoration and are not read out. */
.license-group {
  margin-top: 22px;
  font-size: 0.8rem;
  font-weight: 600;
  letter-spacing: 0.07em;
  text-transform: uppercase;
  color: var(--text-dim);
}

.license-points {
  list-style: none;
  margin: 6px 0 0;
  padding: 0;
}

.license-point {
  display: flex;
  gap: 10px;
  padding: 7px 0;
  font-size: 0.93rem;
  line-height: 1.55;
  color: var(--text-dim);
  text-wrap: pretty;
}

.license-point::before {
  flex: none;
  width: 1em;
  font-weight: 700;
}

.license-point--yes::before { content: "✓"; color: var(--accent); }
.license-point--no::before { content: "✗"; color: var(--stamp); }

/* ---- the full license text ---- */

.license-doc {
  margin-top: clamp(20px, 2.4vw, 30px);
  max-width: 78ch;
}

.license-doc p {
  margin-top: 14px;
  font-size: 0.94rem;
  line-height: 1.72;
  color: var(--text-dim);
  text-wrap: pretty;
}

.license-doc strong { color: var(--text); font-weight: 600; }

/* The one heading inside the license text — Permitted use. The terms above it
   run as plain paragraphs, the way MIT does. */
.license-clause {
  margin-top: 28px;
  font-size: 0.8rem;
  font-weight: 600;
  letter-spacing: 0.09em;
  text-transform: uppercase;
  color: var(--text-faint);
}

.license-list {
  margin: 14px 0 0;
  padding-left: 0;
  list-style: none;
}

.license-list > li {
  position: relative;
  padding-left: 20px;
  margin-top: 10px;
  font-size: 0.94rem;
  line-height: 1.72;
  color: var(--text-dim);
  text-wrap: pretty;
}

.license-list > li::before {
  content: "—";
  position: absolute;
  left: 0;
  color: var(--text-faint);
}

/* The warranty and liability disclaimers, which are conventionally set apart
   from the rest of the terms. */
.license-disclaimer {
  font-style: italic;
  color: var(--text-faint);
}

/* ============================================================ responsive */

@media (max-width: 900px) {
  .intro-grid { grid-template-columns: minmax(0, 1fr); }

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

  .docs-nav {
    position: static;
    max-height: none;
  }

  .release-head { grid-template-columns: minmax(0, 1fr); }
  .release-head > .release-blurb,
  .release-head > .release-note { grid-column: 1; }

  /* Two columns here, one under 560px, so the explicit placement has to come
     off: a group pinned to column 3 would conjure a third column, and the hint
     would keep a row it no longer shares. It becomes the last full-width thing
     in the grid instead. */
  /* `:nth-of-type(n)` matches every group, and exists purely to equal the
     specificity of the three nth-of-type rules above — without it they win and
     a group stays pinned to a column three that no longer exists, conjuring
     one. */
  .option-grid:has(> .option-hint) > .option-group:nth-of-type(n) {
    grid-column: auto;
    grid-row: auto;
  }

  .option-grid > .option-hint {
    grid-column: 1 / -1;
    grid-row: auto;
    align-self: auto;
    margin-top: 22px;
  }
  .page-hero-inner { align-items: stretch; }
  .option-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .license-grid { grid-template-columns: minmax(0, 1fr); }

  .hero-head {
    flex-direction: column;
    align-items: stretch;
    gap: 30px;
  }
}

@media (max-width: 720px) {
  .topnav { display: none; }
  .topbar-inner { gap: 16px; }

  /* Too narrow for one line: stack the three, and drop the divider so the two
     link groups don't start a wrapped row with a rule hanging off the left. */
  .footer-inner {
    flex-direction: column;
    align-items: flex-start;
    gap: 18px;
  }

  .footer-links { gap: 10px clamp(16px, 4vw, 26px); }

  .footer-list + .footer-list {
    margin-left: 0;
    padding-left: 0;
    border-left: 0;
  }

  .footer-legal { text-align: left; }

  .brand-icon { width: 32px; height: 32px; }
  .brand-name { font-size: 24px; }
}

@media (max-width: 560px) {
  .hero-actions { grid-template-columns: minmax(0, 1fr); }
  .option-grid { grid-template-columns: minmax(0, 1fr); }
}

@media (prefers-reduced-motion: reduce) {
  * {
    animation-duration: 0.01ms !important;
    transition-duration: 0.01ms !important;
  }
}

