/*
  Reldavi marketing site.

  Hand-written, no framework, no external fonts. The last one is a product decision as much as a
  performance one: a site selling GDPR and KVKK compliance should not open by shipping the
  visitor's IP address to a font CDN.

  The type scale is the backbone. Headlines are set tight and large, body copy is set generously,
  and almost everything else is whitespace.
*/

/*
  Two themes, chosen by the visitor rather than by their operating system.

  Following prefers-color-scheme sounds respectful and is not: somebody whose laptop is dark all
  day still arrives at a product page expecting to see the product, and the product is light. So
  light is the default, the switch in the header opts into dark, and the choice is remembered in
  localStorage - not a cookie, because the footer promises there are none.

  Every colour below is a custom property, which is what lets the inline SVG illustrations follow
  the theme without a second copy of any drawing.
*/
:root {
  color-scheme: light;

  /* The sticky header's height. Anchors and the docs sidebar both have to offset by it. */
  --nav-height: 56px;

  /* Neutrals. Not pure black on pure white: the small amount of warmth reads as considered
     rather than harsh, and it is easier on the eyes over a long page. */
  --ink: #1d1d1f;
  --ink-soft: #494a4d;
  --ink-faint: #86868b;
  --paper: #ffffff;
  --paper-alt: #f5f5f7;
  --paper-deep: #000000;
  --line: #d2d2d7;
  /* Cards and the pressed segment of a control: the same as paper in light, lifted in dark. */
  --raised: #ffffff;

  --accent: #0a5fff;
  --accent-soft: #e8f0ff;
  --accent-ink: #ffffff;

  /* The diff palette, matched to the product so a screenshot and the site agree. */
  --removed-bg: #fdeceb;
  --removed-ink: #8a1c14;
  --added-bg: #e9f6ec;
  --added-ink: #10612a;
  --updated-bg: #fdf3e0;
  --updated-ink: #8a5b00;

  --radius: 18px;
  --radius-sm: 10px;

  --shell: min(1120px, 100% - 3rem);

  --font: -apple-system, BlinkMacSystemFont, "SF Pro Display", "Segoe UI Variable Display",
          "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
  --font-mono: ui-monospace, "SF Mono", "Cascadia Mono", "JetBrains Mono", Consolas, monospace;
}

/*
  The dark theme. Not an inversion - the neutrals are warmed the other way and the accent is
  lightened, because #0a5fff on near-black fails contrast and #4d92ff does not.
*/
:root[data-theme="dark"] {
  color-scheme: dark;

  --ink: #f2f2f5;
  --ink-soft: #babac2;
  --ink-faint: #8a8a92;
  --paper: #0e0e11;
  --paper-alt: #16161a;
  --paper-deep: #000000;
  --line: #2b2b31;
  --raised: #1c1c21;

  --accent: #4d92ff;
  --accent-soft: #14233d;
  /* Near-black on a light blue button, because white on #4d92ff is unreadable. */
  --accent-ink: #07121f;

  --removed-bg: #351a18;
  --removed-ink: #ffb0a8;
  --added-bg: #14301f;
  --added-ink: #85dfa0;
  --updated-bg: #332612;
  --updated-ink: #f0c878;
}

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

html { scroll-behavior: smooth; scroll-padding-top: calc(var(--nav-height) + 1rem); }

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after { animation-duration: 0.001ms !important; transition-duration: 0.001ms !important; }
}

body {
  margin: 0;
  background: var(--paper);
  color: var(--ink);
  font-family: var(--font);
  font-size: 17px;
  line-height: 1.55;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
  /* A long unbroken identifier in a table cell must not widen the page on a phone. */
  overflow-wrap: break-word;
}

img, svg { max-width: 100%; height: auto; display: block; }

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

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

.shell { width: var(--shell); margin-inline: auto; }
.shell-narrow { width: min(760px, 100% - 3rem); margin-inline: auto; }

.visually-hidden {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip-path: inset(50%); white-space: nowrap;
}

/* ---------------------------------------------------------------- type scale */

h1, h2, h3, h4 { margin: 0; font-weight: 640; letter-spacing: -0.025em; line-height: 1.08; }

.display {
  font-size: clamp(2.9rem, 7.2vw, 5.4rem);
  letter-spacing: -0.04em;
  line-height: 1.04;
}

.headline { font-size: clamp(2.1rem, 4.4vw, 3.4rem); letter-spacing: -0.03em; }
.subhead  { font-size: clamp(1.4rem, 2.4vw, 1.9rem); letter-spacing: -0.02em; }
.eyebrow {
  font-size: 0.82rem; font-weight: 650; letter-spacing: 0.1em; text-transform: uppercase;
  color: var(--accent); margin: 0 0 1rem;
}

.lede {
  font-size: clamp(1.15rem, 1.9vw, 1.45rem);
  line-height: 1.5;
  color: var(--ink-soft);
  letter-spacing: -0.01em;
}

p { margin: 0 0 1.1rem; }
p:last-child { margin-bottom: 0; }

.muted { color: var(--ink-faint); }
.small { font-size: 0.92rem; }
.mono { font-family: var(--font-mono); font-size: 0.92em; }

/* ---------------------------------------------------------------- navigation */

.nav {
  position: sticky; top: 0; z-index: 50;
  background: color-mix(in srgb, var(--paper) 78%, transparent);
  backdrop-filter: saturate(180%) blur(20px);
  -webkit-backdrop-filter: saturate(180%) blur(20px);
  border-bottom: 1px solid color-mix(in srgb, var(--line) 60%, transparent);
}

.nav-inner { display: flex; align-items: center; gap: 2rem; min-height: var(--nav-height); }

.brand { display: flex; align-items: center; gap: 0.55rem; color: var(--ink); font-weight: 620; letter-spacing: -0.02em; }
.brand:hover { text-decoration: none; }
.brand svg { width: 22px; height: 22px; }

.nav-links { display: flex; gap: 1.6rem; flex: 1; font-size: 0.88rem; }
.nav-links a { color: var(--ink-soft); white-space: nowrap; }
.nav-links a:hover { color: var(--ink); text-decoration: none; }
.nav-links a[aria-current="page"] { color: var(--ink); }

.nav-end { display: flex; align-items: center; gap: 0.7rem; margin-inline-start: auto; }

/*
  A two-segment control rather than "EN · TR".

  Two links of equal weight separated by a dot make a visitor read both and work out which one
  they are already on. A pressed segment answers that before it is asked, and it doubles as the
  affordance that the other half is clickable.
*/
.lang-switch {
  display: inline-flex; align-items: center;
  margin: 0; padding: 2px;
  border: 1px solid var(--line); border-radius: 980px;
  background: var(--paper-alt);
}

.lang-switch a {
  padding: 0.2rem 0.6rem;
  border-radius: 980px;
  font-size: 0.75rem; font-weight: 620; letter-spacing: 0.04em; line-height: 1.5;
  color: var(--ink-faint);
}

.lang-switch a:hover { color: var(--ink); text-decoration: none; }

.lang-switch a[aria-current="true"] {
  background: var(--raised); color: var(--ink);
  box-shadow: 0 1px 2px rgb(0 0 0 / 10%);
}

/*
  The theme switch, beside the language switch because they are the same kind of decision.

  It is hidden where nothing can act on it: without JavaScript the click would do nothing, and a
  control that does nothing is worse than one that is not offered.
*/
.theme-toggle {
  display: none;
  width: 30px; height: 30px;
  align-items: center; justify-content: center;
  padding: 0;
  border: 1px solid var(--line); border-radius: 50%;
  background: var(--paper-alt); color: var(--ink-soft);
  cursor: pointer;
}

@media (scripting: enabled) {
  .theme-toggle { display: inline-flex; }
}

.theme-toggle:hover { color: var(--ink); background: var(--raised); }
.theme-toggle svg { width: 15px; height: 15px; }

.theme-toggle .icon-sun { display: none; }
:root[data-theme="dark"] .theme-toggle .icon-sun { display: block; }
:root[data-theme="dark"] .theme-toggle .icon-moon { display: none; }

/*
  Below this width the four links stop fitting beside the brand, so they take a row of their own
  and scroll sideways when a translation runs long. Hiding them - the easy answer, and the one
  this file used to take - leaves a phone with no way to reach the documentation at all.
*/
@media (max-width: 860px) {
  :root { --nav-height: 92px; }

  .nav-inner { flex-wrap: wrap; gap: 0.7rem; padding-block: 0.55rem; }

  .nav-links {
    order: 3; flex-basis: 100%; flex-grow: 0;
    gap: 1.25rem; padding-bottom: 2px;
    overflow-x: auto; scrollbar-width: none;
  }

  .nav-links::-webkit-scrollbar { display: none; }
}

/*
  On a 320px phone the first row has 272px to hold a wordmark, a language switch and a call to
  action, and the three of them want about 340. The wordmark is the one thing already spelled out
  twice on the page below, so it is the one that goes; the mark stays, and the link still leads
  home.
*/
@media (max-width: 420px) {
  .brand span { display: none; }
  .nav-end { gap: 0.55rem; }
}

/* ---------------------------------------------------------------- sections */

.section { padding: clamp(4.5rem, 10vw, 8.5rem) 0; }
.section-tight { padding: clamp(3rem, 6vw, 5rem) 0; }
.section-alt { background: var(--paper-alt); }

.section-head { max-width: 62ch; margin-bottom: clamp(2.5rem, 5vw, 4rem); }
.section-head.centered { margin-inline: auto; text-align: center; }

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

.hero { padding: clamp(4rem, 9vw, 7rem) 0 clamp(3rem, 6vw, 5rem); text-align: center; }
.hero .lede { max-width: 58ch; margin-inline: auto; margin-top: 1.5rem; }
.hero-actions { display: flex; gap: 0.85rem; justify-content: center; flex-wrap: wrap; margin-top: 2.25rem; }
.hero-note { margin-top: 1.25rem; font-size: 0.86rem; color: var(--ink-faint); }

.hero-visual { margin-top: clamp(2.5rem, 6vw, 4.5rem); }

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

.button {
  display: inline-flex; align-items: center; gap: 0.45rem;
  padding: 0.72rem 1.45rem;
  border-radius: 980px;
  border: 1px solid transparent;
  font-size: 0.95rem; font-weight: 550; letter-spacing: -0.01em;
  cursor: pointer;
  transition: transform 0.15s ease, background-color 0.15s ease, opacity 0.15s ease;
}

.button:hover { text-decoration: none; transform: translateY(-1px); }
.button:active { transform: translateY(0); }

.button-primary { background: var(--accent); color: var(--accent-ink); }
.button-primary:hover { opacity: 0.9; }
.button-ghost { background: transparent; color: var(--accent); border-color: color-mix(in srgb, var(--accent) 35%, transparent); }
.button-ghost:hover { background: var(--accent-soft); }
.button-quiet { background: var(--paper-alt); color: var(--ink); border-color: var(--line); }

/* The header is 56px tall. A full-size call to action inside it reads as a misprint. */
.button-sm { padding: 0.4rem 1rem; font-size: 0.84rem; font-weight: 580; }

.link-arrow { font-weight: 520; }
.link-arrow::after { content: " \203A"; font-weight: 400; }

/* ---------------------------------------------------------------- grids */

/*
  Every track is minmax(min(N, 100%), 1fr) rather than minmax(N, 1fr).

  Plain minmax(340px, 1fr) still lays out a 340px column inside a 300px phone and pushes the
  whole page sideways - the one responsive bug that survives every desktop review, because a
  desktop never triggers it. The min() clamps the floor to the space that actually exists.
*/
.grid { display: grid; gap: clamp(1.25rem, 2.5vw, 2rem); }
.grid-2 { grid-template-columns: repeat(auto-fit, minmax(min(300px, 100%), 1fr)); }
.grid-3 { grid-template-columns: repeat(auto-fit, minmax(min(270px, 100%), 1fr)); }
.grid-4 { grid-template-columns: repeat(auto-fit, minmax(min(210px, 100%), 1fr)); }

.split {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(340px, 100%), 1fr));
  gap: clamp(2rem, 5vw, 4.5rem);
  align-items: center;
}

.split-copy h3 { font-size: clamp(1.7rem, 3vw, 2.4rem); margin-bottom: 1rem; }

/* ---------------------------------------------------------------- cards */

.card {
  background: var(--raised);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: clamp(1.4rem, 2.5vw, 2rem);
}

.card h3 { font-size: 1.22rem; margin-bottom: 0.6rem; letter-spacing: -0.02em; }
.card p { color: var(--ink-soft); font-size: 0.97rem; }

.card-icon {
  width: 38px; height: 38px; margin-bottom: 1.1rem;
  color: var(--accent);
}

.stat-block { text-align: center; }
.stat-block .stat-value {
  display: block;
  font-size: clamp(2.2rem, 4.5vw, 3.2rem);
  font-weight: 650; letter-spacing: -0.035em; line-height: 1;
  margin-bottom: 0.5rem;
}
.stat-block .stat-label { color: var(--ink-soft); font-size: 0.95rem; }

/* ---------------------------------------------------------------- steps */

.steps { counter-reset: step; display: grid; gap: 2rem; }

.step { display: grid; grid-template-columns: 2.2rem 1fr; gap: 1.1rem; align-items: start; }

.step::before {
  counter-increment: step;
  content: counter(step);
  width: 2.2rem; height: 2.2rem;
  display: grid; place-items: center;
  border-radius: 50%;
  background: var(--accent); color: var(--accent-ink);
  font-size: 0.9rem; font-weight: 650;
}

.step h3 { font-size: 1.15rem; margin-bottom: 0.35rem; }
.step p { color: var(--ink-soft); font-size: 0.97rem; }

/* ---------------------------------------------------------------- code */

.code {
  background: #16181d;
  color: #e6e8ee;
  border-radius: var(--radius-sm);
  padding: 1.15rem 1.3rem;
  overflow-x: auto;
  font-family: var(--font-mono);
  font-size: 0.855rem;
  line-height: 1.7;
  margin: 0;
  border: 1px solid #24262d;
}

.code .c { color: #7f8797; }          /* comment  */
.code .k { color: #c792ea; }          /* keyword  */
.code .s { color: #a5d6a7; }          /* string   */
.code .t { color: #82b1ff; }          /* type     */
.code .a { color: #ffcb6b; }          /* attribute*/

.tabs { display: flex; gap: 0.4rem; flex-wrap: wrap; margin-bottom: 0.9rem; }

.tab {
  padding: 0.38rem 0.85rem;
  border-radius: 980px;
  border: 1px solid var(--line);
  background: transparent;
  color: var(--ink-soft);
  font: inherit; font-size: 0.85rem;
  cursor: pointer;
}

.tab[aria-selected="true"] { background: var(--ink); color: var(--paper); border-color: var(--ink); }

.tab-panel[hidden] { display: none; }

/* ---------------------------------------------------------------- product mockups */

.mockup {
  border-radius: var(--radius);
  overflow: hidden;
  border: 1px solid var(--line);
  background: var(--paper);
  box-shadow: 0 1px 2px rgb(0 0 0 / 5%), 0 18px 50px -20px rgb(0 0 0 / 22%);
}

:root[data-theme="dark"] .mockup {
  box-shadow: 0 1px 2px rgb(0 0 0 / 50%), 0 18px 50px -20px rgb(0 0 0 / 80%);
}

.mockup-wide { max-width: 980px; margin-inline: auto; }

/*
  Every illustration carries 12-15px labels inside a viewBox 640 to 960 units wide. Scaled down
  to a 320px phone those labels land at about four pixels, and the detail that makes the drawing
  worth showing at all is gone. Below this width they keep a legible size and scroll sideways.
*/
@media (max-width: 720px) {
  .mockup, .figure { overflow-x: auto; }
  .mockup > svg, .figure > svg { min-width: 560px; }
}

/* ---------------------------------------------------------------- pricing */

.plans { display: grid; gap: 1.25rem; grid-template-columns: repeat(auto-fit, minmax(min(250px, 100%), 1fr)); align-items: start; }

.plan {
  background: var(--raised);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: 1.75rem 1.5rem;
  display: flex; flex-direction: column; gap: 1rem;
  height: 100%;
}

.plan-featured { border-color: var(--accent); border-width: 2px; position: relative; }

.plan-badge {
  position: absolute; top: -0.75rem; left: 50%; transform: translateX(-50%);
  background: var(--accent); color: var(--accent-ink);
  padding: 0.2rem 0.75rem; border-radius: 980px;
  font-size: 0.72rem; font-weight: 650; letter-spacing: 0.04em; text-transform: uppercase;
  white-space: nowrap;
}

.plan h3 { font-size: 1.1rem; }
.plan-price { font-size: 2.4rem; font-weight: 650; letter-spacing: -0.04em; line-height: 1; }
.plan-price span { font-size: 0.95rem; font-weight: 450; color: var(--ink-faint); letter-spacing: -0.01em; }
/* Four lines: the longest plan description sets the floor so every call to action lines up. */
.plan-desc { color: var(--ink-soft); font-size: 0.92rem; min-height: 4.6em; }

.plan ul { list-style: none; margin: 0; padding: 0; display: grid; gap: 0.55rem; font-size: 0.92rem; flex: 1; }
.plan li { display: grid; grid-template-columns: 1.1rem 1fr; gap: 0.5rem; color: var(--ink-soft); }
.plan li::before { content: "✓"; color: var(--added-ink); font-weight: 700; }
.plan li.off { color: var(--ink-faint); }
.plan li.off::before { content: "—"; color: var(--ink-faint); font-weight: 400; }

.compare { width: 100%; min-width: 44rem; border-collapse: collapse; font-size: 0.92rem; }
.compare th, .compare td { padding: 0.8rem 0.9rem; border-bottom: 1px solid var(--line); text-align: start; }
.compare thead th { font-size: 0.78rem; text-transform: uppercase; letter-spacing: 0.06em; color: var(--ink-faint); font-weight: 650; }
.compare tbody th { font-weight: 500; color: var(--ink); }
.compare td { color: var(--ink-soft); }
.compare-wrap { overflow-x: auto; }

/*
  Self-hosting gets a band of its own rather than a fifth card.

  The person who buys it is not comparing event allowances - they are asking whether this can run
  where their data already lives - and a fifth column would have squeezed the other four into
  something nobody can read on a laptop.
*/
.self-hosted {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(320px, 100%), 1fr));
  gap: clamp(1.5rem, 4vw, 3rem);
  align-items: center;
  margin-top: clamp(1.75rem, 3vw, 2.5rem);
  padding: clamp(1.75rem, 4vw, 2.75rem);
  background: var(--raised);
  border: 1px solid var(--line);
  border-radius: var(--radius);
}

.self-hosted-points {
  list-style: none; margin: 1.4rem 0 0; padding: 0;
  display: grid; gap: 0.55rem;
  color: var(--ink-soft); font-size: 0.95rem;
}

.self-hosted-points li { display: grid; grid-template-columns: 1.1rem 1fr; gap: 0.5rem; }
.self-hosted-points li::before { content: "✓"; color: var(--added-ink); font-weight: 700; }

.self-hosted-price { text-align: start; }
.self-hosted-price .button { margin-top: 1.2rem; }

/* ---------------------------------------------------------------- comparison */

/*
  Six columns of vendor claims. Our column is tinted and the row headings stay put while the rest
  scrolls sideways, because a matrix you have to scroll is a matrix where you lose track of which
  row you are reading.
*/
.compare-matrix { min-width: 52rem; }

.compare-matrix thead th {
  text-transform: none; letter-spacing: -0.01em; font-size: 0.88rem; font-weight: 650;
  color: var(--ink);
}

.compare-matrix th[scope="row"] {
  position: sticky; inset-inline-start: 0; z-index: 1;
  background: var(--paper-alt);
  font-weight: 540;
}

.compare-matrix .is-us { background: var(--accent-soft); }
.compare-matrix thead .is-us { color: var(--accent); }

/* ---------------------------------------------------------------- roadmap */

.roadmap {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(260px, 100%), 1fr));
  gap: clamp(1.75rem, 3vw, 3rem);
}

.roadmap-stage {
  margin-bottom: 1.3rem;
  font-size: 0.74rem; font-weight: 650; letter-spacing: 0.12em; text-transform: uppercase;
  color: var(--ink-faint);
}

.roadmap-bucket ul { list-style: none; margin: 0; padding: 0; display: grid; gap: 1.3rem; }

.roadmap-bucket li {
  display: grid; gap: 0.35rem;
  padding-inline-start: 1.1rem;
  border-inline-start: 2px solid var(--line);
}

.roadmap-bucket strong { font-weight: 620; letter-spacing: -0.015em; }
.roadmap-bucket span { color: var(--ink-soft); font-size: 0.95rem; }

/* The first bucket is what is actually being worked on, so it is the one that is coloured. */
.roadmap-bucket:first-child .roadmap-stage { color: var(--accent); }
.roadmap-bucket:first-child li { border-inline-start-color: color-mix(in srgb, var(--accent) 45%, transparent); }

/* ---------------------------------------------------------------- faq */

.faq { display: grid; gap: 0; }

.faq details {
  border-bottom: 1px solid var(--line);
  padding: 1.2rem 0;
}

.faq summary {
  cursor: pointer; font-weight: 560; font-size: 1.05rem; letter-spacing: -0.015em;
  list-style: none; display: flex; justify-content: space-between; gap: 1rem; align-items: center;
}

.faq summary::-webkit-details-marker { display: none; }
.faq summary::after { content: "+"; color: var(--ink-faint); font-weight: 400; font-size: 1.4rem; line-height: 1; }
.faq details[open] summary::after { content: "–"; }
.faq details p { margin-top: 0.85rem; color: var(--ink-soft); font-size: 0.98rem; }

/* ---------------------------------------------------------------- callout */

.callout {
  background: var(--ink); color: var(--paper);
  border-radius: var(--radius);
  padding: clamp(2.5rem, 6vw, 4.5rem) clamp(1.5rem, 5vw, 4rem);
  text-align: center;
}

.callout h2 { color: var(--paper); }
.callout p { color: color-mix(in srgb, var(--paper) 72%, transparent); max-width: 52ch; margin-inline: auto; }
.callout .button-primary { background: var(--paper); color: var(--ink); }
.callout .button-ghost { color: var(--paper); border-color: color-mix(in srgb, var(--paper) 40%, transparent); }
.callout .button-ghost:hover { background: color-mix(in srgb, var(--paper) 12%, transparent); }

/* ---------------------------------------------------------------- quote */

.quote { max-width: 46ch; }
.quote blockquote { margin: 0 0 1rem; font-size: clamp(1.2rem, 2.2vw, 1.55rem); letter-spacing: -0.02em; line-height: 1.4; }
.quote figcaption { color: var(--ink-faint); font-size: 0.92rem; }

/* ---------------------------------------------------------------- footer */

.footer { border-top: 1px solid var(--line); padding: 3.5rem 0 2.5rem; font-size: 0.88rem; }
.footer-grid { display: grid; gap: 2rem; grid-template-columns: repeat(auto-fit, minmax(min(160px, 100%), 1fr)); margin-bottom: 2.5rem; }
.footer h4 { font-size: 0.78rem; text-transform: uppercase; letter-spacing: 0.08em; color: var(--ink-faint); margin-bottom: 0.9rem; font-weight: 650; }
.footer ul { list-style: none; margin: 0; padding: 0; display: grid; gap: 0.55rem; }
.footer a { color: var(--ink-soft); }
.footer a:hover { color: var(--ink); }
.footer-base { display: flex; justify-content: space-between; gap: 1rem; flex-wrap: wrap; color: var(--ink-faint); border-top: 1px solid var(--line); padding-top: 1.75rem; }

/* ---------------------------------------------------------------- reveal */

/*
  Sections fade in as they arrive — but only where something can fade them back.

  Starting at opacity 0 unconditionally means a visitor with JavaScript off sees a page of empty
  space: the markup is all there, the crawler reads it, and the human sees nothing. Scoping the
  hidden state to `scripting: enabled` inverts that, and a browser too old to know the feature
  skips the block entirely and simply shows the content, which is the right way to fail.
*/
@media (scripting: enabled) {
  .reveal { opacity: 0; transform: translateY(18px); transition: opacity 0.7s ease, transform 0.7s ease; }
}

.reveal.visible { opacity: 1; transform: none; }

@media (prefers-reduced-motion: reduce) {
  .reveal { opacity: 1; transform: none; }
}

/* ---------------------------------------------------------------- docs */

.doc-layout { display: grid; grid-template-columns: 220px minmax(0, 1fr); gap: 3rem; align-items: start; }

/*
  A grid item refuses to shrink below its own min-content unless it is told otherwise, and the
  widest thing in the documentation is a code sample. Without this the column grows to the length
  of the longest line and the whole page scrolls sideways - instead of the sample scrolling, which
  is what its own overflow is there for.
*/
.doc-nav, .doc-body { min-width: 0; }

@media (max-width: 900px) {
  /* minmax(0, 1fr), not 1fr, for the same reason: a bare 1fr track has a min-content floor. */
  .doc-layout { grid-template-columns: minmax(0, 1fr); }
  .doc-nav { position: static !important; }
}

.doc-nav { position: sticky; top: calc(var(--nav-height) + 1.25rem); font-size: 0.9rem; }
.doc-nav ul { list-style: none; margin: 0 0 1.5rem; padding: 0; display: grid; gap: 0.5rem; }
.doc-nav a { color: var(--ink-soft); }
.doc-nav h4 { font-size: 0.74rem; text-transform: uppercase; letter-spacing: 0.08em; color: var(--ink-faint); margin-bottom: 0.7rem; }

.doc-body h2 { font-size: clamp(1.7rem, 3vw, 2.2rem); margin: 3rem 0 1rem; scroll-margin-top: calc(var(--nav-height) + 1.5rem); }
.doc-body h2:first-child { margin-top: 0; }
.doc-body h3 { font-size: 1.2rem; margin: 2rem 0 0.75rem; }
.doc-body p, .doc-body li { color: var(--ink-soft); }
.doc-body ul, .doc-body ol { padding-inline-start: 1.3rem; display: grid; gap: 0.5rem; margin: 0 0 1.2rem; }
.doc-body .code { margin: 1.2rem 0; }
/*
  Reference tables carry long identifiers and defaults, so they get a scroll container of their
  own rather than being squeezed to a column of one word per line on a phone.
*/
.table-wrap { overflow-x: auto; margin: 1.2rem 0; }
.table-wrap table { margin: 0; min-width: 28rem; }

.doc-body table { width: 100%; border-collapse: collapse; font-size: 0.92rem; margin: 1.2rem 0; }
.doc-body th, .doc-body td { padding: 0.65rem 0.8rem; border-bottom: 1px solid var(--line); text-align: start; }
.doc-body th { font-size: 0.78rem; text-transform: uppercase; letter-spacing: 0.06em; color: var(--ink-faint); }

.notice {
  border-inline-start: 3px solid var(--accent);
  background: var(--accent-soft);
  padding: 1rem 1.2rem;
  border-radius: 0 var(--radius-sm) var(--radius-sm) 0;
  margin: 1.5rem 0;
  font-size: 0.95rem;
}

.notice strong { color: var(--ink); }

/* The documentation sidebar lists all seven pages and expands only the one being read. Without a
   mark the current group reads as just another link, and a reader who has scrolled has no way to
   tell where they are. */
.doc-nav h4.doc-nav-current { color: var(--ink); }
.doc-nav h4.doc-nav-current::before { content: "› "; color: var(--accent); }

/* The scene that opens the About page. Set apart from the argument after it: a reader who
   recognises their own Thursday in it has already agreed with what follows, and running the two
   together as one column of prose loses that. */
.scene { margin-top: 2rem; border-left: 3px solid var(--accent); padding-left: 1.5rem; }
.scene p { font-size: 1.05rem; line-height: 1.75; color: var(--ink); margin: 0 0 1.1rem; }
.scene p:last-child { margin-bottom: 0; font-weight: 600; }
