/* ═══════════════════════════════════════════════════════════
   rf.css - Rational Forge global stylesheet
   All custom components, animations, and design tokens.
   Tailwind CDN handles layout utilities in HTML.
═══════════════════════════════════════════════════════════ */

/* ── 1. Design tokens ──────────────────────────────────── */
:root {
  /* Muted brand palette. Same six hues as the original, with the saturation
     pulled back so the pages read calm rather than electric. Hue is held to
     within about three degrees of the old value on every one, so the site is
     still red and blue, just quieter. Lightness was tuned for contrast: every
     one of these carries white or sits on white at 4.5:1 or better. */
  --rf-red:     #a8323c;   /* was #b60018, s 100 -> 54 */
  --rf-blue:    #1d2b4e;   /* was #132451, s  62 -> 46 */
  --rf-lblue:   #2c5f96;   /* was #005ab2, s 100 -> 55 */
  --rf-cyan:    #4e9fd1;   /* was #00a1fb, s 100 -> 59 */
  --rf-orange:  #c8622f;   /* was #ff5600, s 100 -> 62 */
  --rf-yellow:  #d8bf4a;   /* was #ffd900, s 100 -> 65 */

  /* Light mode surfaces. The page used to sit on pure #ffffff, which is the
     brightest thing a monitor can do and is tiring to read against for the
     length of a legal document. --rf-surface is the page and the sections,
     --rf-surface-alt is the band that alternates with it, and --rf-raised is
     the cards, which stay just above the page so they still lift off it.
     The same three names are redefined under .dark below, so every rule that
     uses them themes itself. The matching Tailwind colours (bg-rf-surface,
     bg-rf-surface-alt) are in assets/rf-tailwind.js. */
  --rf-surface:     #f6f8fa;
  --rf-surface-alt: #eceff4;
  --rf-raised:      #fcfdfe;
  --rf-border:      #e2e6ec;

  --nav-h:     72px;
  --ease:      cubic-bezier(0.4, 0, 0.2, 1);
  --ease-pop:  cubic-bezier(0.34, 1.56, 0.64, 1);
  --radius-card: 18px;
}

/* Dark mode keeps the values the pages already used, so nothing shifts:
   gray-950 for the page, gray-900 for the raised surfaces, gray-800 for
   the borders. Naming them here is what lets the rules below be written
   once instead of once per theme. */
.dark {
  --rf-surface:     #030712;
  --rf-surface-alt: #0b1120;
  --rf-raised:      #111827;
  --rf-border:      #1f2937;
}

html { scroll-padding-top: var(--nav-h); }
*, *::before, *::after { box-sizing: border-box; }
body { font-family: 'Inter', system-ui, -apple-system, sans-serif; -webkit-font-smoothing: antialiased; }


/* ── 1b. Wordmarks ──────────────────────────────────────────
   The two lockups that sit beside a logo, in the navbar, the mobile drawer
   and the footer: RationalForge and RFCommand.

   These keep the ORIGINAL fully saturated brand colours, and that is not an
   oversight. A logotype is allowed to be louder than the interface around it,
   and against the muted palette the desaturated versions read as washed out
   next to the logos' own colours. Everything that is not a logotype stays
   muted: .btn-primary, .legal-notice, the section headings, the icons, the
   "Rational" heading in the home page values section (a section title, not
   the company name) and the "Transformative" value word.

   Deliberately literal hexes. Do NOT wire these to --rf-red, --rf-orange or
   --rf-cyan: those are the muted tokens and the whole point here is that the
   wordmarks do not follow them. */
.wordmark-rational { color: #b60018; }   /* RationalForge, first half  */
.wordmark-rf       { color: #ff5600; }   /* RFCommand, first half      */

/* The second half of both lockups, "Forge" and "Command". Same colour, same
   job, so one pair of classes covers them.
     .wordmark-forge      over a dark ground: the hero navbar, the footer, 404
     .wordmark-forge-alt  over a light panel: the mobile drawer
   The navbar version is #navForge further down, because it has to cross-fade
   as the bar goes from transparent-over-hero to solid-over-page. */
.wordmark-forge     { color: #00a1fb; }
.wordmark-forge-alt { color: #132451; }
.dark .wordmark-forge-alt { color: #00a1fb; }


/* ── 2. Scroll reveal ──────────────────────────────────── */
.reveal {
  opacity: 0;
  transform: translateY(22px);
  transition: opacity 0.62s var(--ease), transform 0.62s var(--ease);
}
.reveal.visible  { opacity: 1; transform: none; }
.reveal-d1       { transition-delay: 0.10s; }
.reveal-d2       { transition-delay: 0.22s; }
.reveal-d3       { transition-delay: 0.34s; }
.reveal-d4       { transition-delay: 0.46s; }


/* ── 3. Gradient text helpers ──────────────────────────── */
.gt-blue {
  background: linear-gradient(135deg, var(--rf-cyan) 0%, #7fb8dd 45%, var(--rf-lblue) 100%);
  -webkit-background-clip: text;
  -webkit-text-fill-color: transparent;
  background-clip: text;
}


/* ── 4. Section label ──────────────────────────────────── */
.section-label {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  font-size: 0.70rem;
  font-weight: 700;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--rf-lblue);
  margin-bottom: 14px;
}
.section-label::before {
  content: '';
  width: 22px;
  height: 2px;
  background: currentColor;
  border-radius: 2px;
  flex-shrink: 0;
}
.dark .section-label { color: var(--rf-cyan); }


/* ── 5. Navbar ─────────────────────────────────────────── */
#navbar {
  position: fixed;
  inset: 0 0 auto 0;
  height: var(--nav-h);
  z-index: 1000;
  transition: background 0.32s var(--ease), box-shadow 0.32s var(--ease);
}
#navbar.scrolled {
  background: rgba(246, 248, 250, 0.93);
  backdrop-filter: blur(18px);
  -webkit-backdrop-filter: blur(18px);
  box-shadow: 0 1px 0 rgba(0, 0, 0, 0.07);
}
.dark #navbar.scrolled {
  background: rgba(6, 10, 22, 0.92);
  box-shadow: 0 1px 0 rgba(255, 255, 255, 0.05);
}

/* Nav links - white over hero, dark when scrolled */
.nav-link {
  position: relative;
  font-size: 0.875rem;
  font-weight: 500;
  color: rgba(255, 255, 255, 0.78);
  transition: color 0.2s;
}
.nav-link::after {
  content: '';
  position: absolute;
  bottom: -3px;
  left: 0;
  width: 0;
  height: 2px;
  background: var(--rf-cyan);
  border-radius: 2px;
  transition: width 0.24s var(--ease);
}
.nav-link:hover             { color: #fff; }
.nav-link:hover::after      { width: 100%; }
#navbar.scrolled .nav-link  { color: #4b5563; }
#navbar.scrolled .nav-link:hover { color: var(--rf-blue); }
#navbar.scrolled .nav-link:hover::after { background: var(--rf-blue); }
.dark #navbar.scrolled .nav-link { color: #9ca3af; }
.dark #navbar.scrolled .nav-link:hover { color: #fff; }
.dark #navbar.scrolled .nav-link:hover::after { background: var(--rf-cyan); }

/* Brand "Forge" text - cyan over hero, dark blue when scrolled light, cyan when scrolled dark */
#navForge                         { color: #00a1fb; transition: color 0.32s; }
#navbar.scrolled #navForge        { color: #005ab2;  }
.dark #navbar.scrolled #navForge  { color: #00a1fb; }

/* Icon buttons */
.nav-btn                   { color: rgba(255,255,255,0.82); transition: color 0.2s; }
#navbar.scrolled .nav-btn  { color: #4b5563; }
.dark #navbar.scrolled .nav-btn { color: #9ca3af; }


/* ── 6. Hero ───────────────────────────────────────────── */
/* The hero band and the footer are the SAME background, declared once so they
   cannot drift apart again. They are the original, brighter blue: desaturating
   this pair along with everything else took the life out of the top and bottom
   of every page, which is the one place the site is allowed to be vivid.
   The muted palette still governs everything between them. */
.hero-bg,
.site-footer {
  background:
    radial-gradient(ellipse 72% 58% at 82% 18%, rgba(0, 90, 178, 0.28) 0%, transparent 68%),
    radial-gradient(ellipse 48% 38% at 52% 52%, rgba(0, 161, 251, 0.08) 0%, transparent 60%),
    linear-gradient(158deg, #050d1c 0%, #0e1a38 38%, #091527 68%, #050d1c 100%);
}
.hero-bg {
  position: relative;
  overflow: hidden;
}
.hero-grid {
  position: absolute;
  inset: 0;
  background-image: radial-gradient(circle, rgba(255,255,255,0.042) 1px, transparent 1px);
  background-size: 36px 36px;
  -webkit-mask-image: linear-gradient(to bottom, transparent, black 12%, black 88%, transparent);
  mask-image: linear-gradient(to bottom, transparent, black 12%, black 88%, transparent);
  pointer-events: none;
}

/* Staggered hero entrance animations */
.h-title, .h-sub, .h-scroll {
  opacity: 0;
  transform: translateY(16px);
  animation: hIn 0.65s var(--ease) forwards;
}
.h-badge  { animation-delay: 0.14s; }
.h-title  { animation-delay: 0.28s; }
.h-sub    { animation-delay: 0.44s; }
.h-cta    { animation-delay: 0.58s; }
.h-scroll { animation-delay: 0.86s; }
@keyframes hIn { to { opacity: 1; transform: none; } }

/* ── 6b. Hero window cascade ────────────────────────────────
   Four real captures dealt out like a hand of cards, from the top left
   down to the bottom right, instead of one full-width screenshot. The
   captures are 951 x 579, and stretched across the whole hero they went
   soft. Here the largest is 56% of the frame (about 610px at most), so
   every one is shown below its own size and stays sharp. They all share
   the capture's shape, so replacing one with a new capture of the same
   window size needs no change here.

   The main window is the largest, sits at the top left and is in front,
   because that is where a reader starts. The other three step out from
   under it by an even 13.33% of the frame each way, and each is 6%
   narrower than the one before, so the cascade tapers into the distance
   and the last one lands exactly on the bottom right corner. Depth also
   comes from shadow and from dimming each step a little more.

   The windows are as large as four of them can be and still all show.
   The main one is 78% of the frame, about 850px on a wide screen, and
   the strip each window shows past its neighbour is an even 7%. Those
   two numbers trade against each other: **widening the main window alone
   closes the strip up**, which is what a first attempt at 62% against
   50% did, leaving the second window a 5% sliver that had all but
   vanished. Widening all four in step is what keeps the strips even.
   78% is also about as far as this can go before the rest state starts
   upscaling: 78% of the 1088px frame is 849px against the capture's own
   951. And the frame is 100 by 61, the capture's own shape, which makes
   a window's height in percent of the frame equal to its width in
   percent, so the offsets are the same number on both axes.

   No rotation: a rotated screenshot resamples its text and blurs it.
   Phone widths show the main window alone, see section 27. */
.hero-stack {
  position: relative;
  aspect-ratio: 100 / 61;
}
.hero-win {
  position: absolute;
  display: block;
  height: auto;
  border-radius: 8px;
  border: 1px solid rgba(255,255,255,0.10);
  box-shadow:
    0 30px 60px -12px rgba(0, 0, 0, 0.65),
    0 12px 24px -8px rgba(0, 0, 0, 0.45);
  opacity: 0;
  animation: hWinIn 0.8s var(--ease) forwards;
  /* scale rather than transform, because the entrance animation owns
     transform and an animation beats a plain declaration. scale is its
     own property, so the hover further down still works. */
  transition: scale 0.38s var(--ease), filter 0.3s, box-shadow 0.3s;
}
/* The four steps. Each one deals out from under the window before it,
   down and to the right, so they all enter from where their neighbour
   already is. */
.hero-win-1 {
  z-index: 4;
  width: 78%;
  left: 0;
  top: 0;
  box-shadow:
    0 40px 90px -16px rgba(0, 0, 0, 0.75),
    0 16px 32px -10px rgba(0, 0, 0, 0.5),
    0 0 0 1px rgba(78, 159, 209, 0.10);
  --from: translateY(24px);
  animation-delay: 0.72s;
  /* 951 / 849. See the hover block for what the pair of values does. */
  --zoom: 1.12;
  transform-origin: 0% 0%;
}
.hero-win-2 {
  z-index: 3;
  width: 72%;
  left: 13.33%;
  top: 13.33%;
  filter: brightness(0.88) saturate(0.95);
  --from: translate(-16%, -22%);
  animation-delay: 0.88s;
  --zoom: 1.215;
  transform-origin: 47.6% 47.6%;
}
.hero-win-3 {
  z-index: 2;
  width: 66%;
  left: 26.67%;
  top: 26.67%;
  filter: brightness(0.8) saturate(0.9);
  --from: translate(-16%, -22%);
  animation-delay: 1s;
  --zoom: 1.324;
  transform-origin: 78.4% 78.4%;
}
.hero-win-4 {
  z-index: 1;
  width: 60%;
  left: 40%;
  top: 40%;
  filter: brightness(0.72) saturate(0.86);
  --from: translate(-16%, -22%);
  animation-delay: 1.12s;
  --zoom: 1.456;
  transform-origin: 100% 100%;
}
@keyframes hWinIn {
  from { opacity: 0; transform: var(--from); }
  to   { opacity: 1; transform: none; }
}

/* Hover opens a window to full size, meaning the capture's own 951px:
   its real resolution, not a blow-up of it. The window comes to the
   front at full brightness, and the cascade behind it is still there
   when the pointer leaves.

   Two values per window make that work, set in the four blocks above.
   --zoom is 951 divided by the window's resting width in pixels at the
   widest the frame gets, which is 1088px, the max-w-6xl container less
   its padding. On a narrower screen the same factor lands short of 951
   rather than over it, which is the right way to be wrong: the picture
   is never upscaled. transform-origin is the point it grows from,
   L / (100 - W), the value that would still hold a window inside the
   frame if it grew all the way to full frame width, so a smaller zoom
   cannot push past the edge and be cut off by the hero's own overflow.
   Change a window's width or offset and both numbers have to be
   recomputed.

   It grows from a corner it is already near, so the pointer stays inside
   the window it is pointing at and there is no flicker. z-index 10
   clears all four, whichever one it is.

   There is no hover on a touch screen, and nothing is hidden behind
   anything there either: a phone shows the main window alone. */
.hero-win:hover {
  z-index: 10;
  filter: none;
  scale: var(--zoom);
  box-shadow:
    0 50px 100px -18px rgba(0, 0, 0, 0.8),
    0 20px 40px -12px rgba(0, 0, 0, 0.55),
    0 0 0 1px rgba(78, 159, 209, 0.28);
}

/* Scroll bounce indicator */
@keyframes sbounce { 0%,100% { transform:translateY(0); opacity:.5; } 50% { transform:translateY(7px); opacity:1; } }
.scroll-bounce { animation: sbounce 2.2s ease-in-out infinite; }


/* ── 7. Buttons ────────────────────────────────────────── */
.btn-primary {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 13px 28px;
  border-radius: 10px;
  background: var(--rf-red);
  color: #fff;
  font-weight: 600;
  font-size: 0.9375rem;
  border: 1px solid transparent;
  text-decoration: none;
  box-shadow: 0 2px 10px rgba(120, 34, 42, 0.18);
  transition: background 0.2s, transform 0.15s, box-shadow 0.2s;
  cursor: pointer;
}
.btn-primary:hover  { background: #8d2831; transform: translateY(-1px); box-shadow: 0 4px 16px rgba(120,34,42,0.26); }
.btn-primary:active { transform: none; }

.btn-ghost {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 12px 28px;
  border-radius: 10px;
  background: transparent;
  color: #fff;
  font-weight: 600;
  font-size: 0.9375rem;
  border: 1px solid rgba(255, 255, 255, 0.22);
  text-decoration: none;
  transition: background 0.2s, border-color 0.2s, transform 0.15s;
  cursor: pointer;
}
.btn-ghost:hover { background: rgba(255,255,255,0.07); border-color: rgba(255,255,255,0.36); transform: translateY(-1px); }


/* ── 8. Feature cards ──────────────────────────────────── */
.f-card {
  padding: 32px;
  border-radius: var(--radius-card);
  background: var(--rf-raised);
  border: 1px solid var(--rf-border);
  transition: border-color 0.25s, box-shadow 0.25s, transform 0.25s;
}
.f-card:hover           { border-color: #cfdeeb; box-shadow: 0 8px 32px rgba(44,95,150,0.10); transform: translateY(-4px); }
.dark .f-card:hover     { border-color: rgba(78,159,209,0.26); box-shadow: 0 8px 32px rgba(78,159,209,0.08); }

.f-icon {
  width: 50px;
  height: 50px;
  border-radius: 13px;
  display: flex;
  align-items: center;
  justify-content: center;
  margin-bottom: 20px;
}


/* ── 9. News cards ─────────────────────────────────────── */
.n-card {
  display: flex;
  gap: 20px;
  padding: 24px 28px;
  border-radius: var(--radius-card);
  border: 1px solid var(--rf-border);
  background: var(--rf-raised);
  text-decoration: none;
  cursor: pointer;
  transition: border-color 0.24s, box-shadow 0.22s, transform 0.22s;
}
.n-card:hover        { border-color: #cfdeeb; box-shadow: 0 8px 28px rgba(44,95,150,0.10); transform: translateY(-3px); }
.dark .n-card:hover  { border-color: rgba(78,159,209,0.30); box-shadow: 0 8px 28px rgba(78,159,209,0.08); }


/* ── 10. Product cards ─────────────────────────────────── */
.p-card {
  border-radius: 22px;
  border: 1px solid var(--rf-border);
  background: var(--rf-raised);
  overflow: hidden;
  transition: box-shadow 0.25s, transform 0.25s;
}
.p-card:hover        { box-shadow: 0 20px 52px rgba(0,0,0,0.12); transform: translateY(-6px); }


/* ── 11. Badges ────────────────────────────────────────── */
.badge-orange {
  display: inline-flex;
  align-items: center;
  padding: 3px 9px;
  border-radius: 6px;
  background: rgba(200, 98, 47, 0.10);
  color: #a8501f;
  font-size: 0.70rem;
  font-weight: 700;
  letter-spacing: 0.07em;
  text-transform: uppercase;
  border: 1px solid rgba(200, 98, 47, 0.24);
}
.dark .badge-orange { background: rgba(200, 98, 47, 0.14); color: #e0a077; border-color: rgba(200, 98, 47, 0.32); }
.badge-gray {
  display: inline-flex;
  align-items: center;
  padding: 3px 9px;
  border-radius: 6px;
  background: #f3f4f6;
  color: #6b7280;
  font-size: 0.70rem;
  font-weight: 700;
  letter-spacing: 0.07em;
  text-transform: uppercase;
  border: 1px solid #e5e7eb;
}
.dark .badge-gray { background: #1f2937; color: #9ca3af; border-color: #374151; }


/* ── 11b. Site footer ───────────────────────────────────────
   .site-footer carries no background of its own. It shares the declaration
   with .hero-bg in section 6, which is what keeps the top and the bottom of a
   page the same colour. The footer used to be `bg-rf-blue dark:bg-gray-950`,
   and rf-blue is the mid navy meant for headings, not for a full-bleed band,
   so in light mode it sat visibly lighter than the hero on the same page. */


/* ── 12. Divider ───────────────────────────────────────── */
.hr-fade {
  height: 1px;
  background: linear-gradient(90deg, transparent, #e5e7eb 20%, #e5e7eb 80%, transparent);
}
.dark .hr-fade { background: linear-gradient(90deg, transparent, #1f2937 20%, #1f2937 80%, transparent); }


/* ── 13. Mobile drawer ─────────────────────────────────── */
#drawer             { position: fixed; inset: 0; z-index: 1001; pointer-events: none; }
#drawer.open        { pointer-events: all; }
#d-overlay          { position: absolute; inset: 0; background: rgba(0,0,0,0.50); opacity: 0; transition: opacity 0.28s; }
#drawer.open #d-overlay { opacity: 1; }
#d-panel {
  position: absolute;
  right: 0; top: 0; bottom: 0;
  width: min(300px, 88vw);
  background: var(--rf-raised);
  padding: 24px 20px;
  display: flex;
  flex-direction: column;
  transform: translateX(100%);
  transition: transform 0.34s var(--ease);
  box-shadow: -6px 0 28px rgba(0,0,0,0.12);
}
.dark #d-panel         { background: #0d1525; }
#drawer.open #d-panel  { transform: none; }


/* ── 14. Coming Soon modal ─────────────────────────────── */
#cs-modal             { position: fixed; inset: 0; z-index: 2000; pointer-events: none; display: flex; align-items: center; justify-content: center; }
#cs-modal.open        { pointer-events: all; }
#cs-overlay2          { position: absolute; inset: 0; background: rgba(0,0,0,0.52); backdrop-filter: blur(6px); -webkit-backdrop-filter: blur(6px); opacity: 0; transition: opacity 0.28s; }
#cs-modal.open #cs-overlay2 { opacity: 1; }
#cs-box {
  position: relative;
  z-index: 1;
  width: min(420px, 92vw);
  background: var(--rf-raised);
  border-radius: 24px;
  padding: 44px 36px 36px;
  text-align: center;
  box-shadow: 0 28px 72px rgba(0,0,0,0.20);
  border: 1px solid rgba(0,0,0,0.06);
  transform: scale(0.93) translateY(12px);
  opacity: 0;
  transition: transform 0.30s var(--ease-pop), opacity 0.26s var(--ease);
}
.dark #cs-box { border-color: var(--rf-border); }
#cs-modal.open #cs-box { transform: none; opacity: 1; }
#cs-close-btn {
  position: absolute;
  top: 16px; right: 16px;
  width: 32px; height: 32px;
  border-radius: 8px;
  background: #f3f4f6;
  border: none;
  cursor: pointer;
  display: flex; align-items: center; justify-content: center;
  color: #6b7280;
  transition: background 0.18s, color 0.18s;
}
.dark #cs-close-btn { background: #1f2937; color: #9ca3af; }
#cs-close-btn:hover { background: #e5e7eb; color: #111827; }
.dark #cs-close-btn:hover { background: #374151; color: #fff; }

.cs-icon {
  width: 72px; height: 72px;
  margin: 0 auto 20px;
  border-radius: 20px;
  display: flex; align-items: center; justify-content: center;
  background: linear-gradient(135deg, var(--rf-blue), var(--rf-lblue));
}


/* ── 15. Quote block ───────────────────────────────────── */
.quote-block {
  background: var(--rf-raised);
  border-radius: 20px;
  border: 1px solid var(--rf-border);
  box-shadow: 0 2px 12px rgba(0,0,0,0.04);
}


/* ── 16. Process step numbers ──────────────────────────── */
.step-num {
  width: 96px; height: 96px;
  border-radius: 26px;
  display: flex; align-items: center; justify-content: center;
  margin: 0 auto 24px;
  font-size: 1.875rem;
  font-weight: 900;
  color: #fff;
}
.step-num-1 { background: linear-gradient(145deg, var(--rf-cyan), var(--rf-lblue));  box-shadow: 0 6px 22px rgba(78,159,209,0.20); }
.step-num-2 { background: linear-gradient(145deg, var(--rf-orange), var(--rf-red));  box-shadow: 0 6px 22px rgba(200,98,47,0.20); }
.step-num-3 { background: linear-gradient(145deg, var(--rf-yellow), var(--rf-orange)); box-shadow: 0 6px 22px rgba(200,98,47,0.18); }


/* ── 17. News / help accordion ─────────────────────────── */
/* max-height is set inline by rf.js from scrollHeight, so long help
   sections cannot be clipped and the transition stays proportional. */
.article-body {
  max-height: 0;
  overflow: hidden;
  transition: max-height 0.35s ease-out;
}
.article-body.open {
  transition: max-height 0.45s ease-in;
}
.chevron             { transition: transform 0.28s ease; flex-shrink: 0; }
.chevron.rotate      { transform: rotate(180deg); }

/* ── 18. Arrow link ────────────────────────────────────── */
.arrow-link {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-size: 0.875rem;
  font-weight: 600;
  transition: gap 0.2s var(--ease);
  text-decoration: none;
}
.arrow-link:hover { gap: 10px; }
.arrow-link svg   { flex-shrink: 0; transition: transform 0.2s var(--ease); }
.arrow-link:hover svg { transform: translateX(2px); }


/* ── 19. Scope note ────────────────────────────────────────
   Sits at the top of every legal document and states which
   product or website that document governs. */
.scope-note {
  border-radius: 14px;
  border: 1px solid #e5e7eb;
  border-left: 4px solid var(--rf-orange);
  background: #fbf6ef;
  padding: 20px 24px;
  font-size: 0.9375rem;
  line-height: 1.65;
  color: #4b5563;
}
.dark .scope-note { background: #1a1510; border-color: #362c1e; border-left-color: var(--rf-orange); color: #cbd5e1; }
.scope-note strong { color: #111827; font-weight: 700; }
.dark .scope-note strong { color: #f9fafb; }
.scope-note a { color: var(--rf-lblue); font-weight: 600; }
.dark .scope-note a { color: var(--rf-cyan); }


/* ── 19b. Conspicuous legal notice ──────────────────────────
   Warranty disclaimers and liability limits are conventionally set in ALL
   CAPS. That is not decoration: a disclaimer that looks like ordinary body
   text is easier to attack later as never having been properly drawn to the
   reader's attention. All caps is also very hard to read, so these clauses
   use a bordered, tinted panel with slightly heavier text instead, which is
   conspicuous without shouting.

   Do NOT strip the border to tidy up a page. Being visibly set apart from
   the surrounding text is the entire purpose of this rule. */
.legal-notice {
  border: 1px solid #e8ccd0;
  border-left: 4px solid var(--rf-red);
  background: #fbf5f5;
  border-radius: 14px;
  padding: 22px 26px;
  font-weight: 500;
  color: #4b5563;
}
.legal-notice > :last-child { margin-bottom: 0; }
.dark .legal-notice {
  background: #1c1315;
  border-color: #45292d;
  border-left-color: var(--rf-red);
  color: #d1d5db;
}
.legal-notice strong { color: #111827; }
.dark .legal-notice strong { color: #f9fafb; }

/* Legal documents get printed. Keep the panel visible on paper, where
   background colours are usually dropped by the browser. */
@media print {
  .legal-notice {
    background: transparent;
    border: 2px solid #000;
    border-left-width: 5px;
  }
}


/* ── 20. Legal index table ─────────────────────────────── */
.legal-table { width: 100%; border-collapse: collapse; font-size: 0.9375rem; }
.legal-table th {
  text-align: left;
  font-size: 0.70rem;
  font-weight: 700;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: #9ca3af;
  padding: 0 16px 12px;
  border-bottom: 1px solid #e5e7eb;
}
.dark .legal-table th { border-bottom-color: #1f2937; }
.legal-table td { padding: 18px 16px; border-bottom: 1px solid #f3f4f6; vertical-align: top; }
.dark .legal-table td { border-bottom-color: #111827; }
.legal-table tr:last-child td { border-bottom: none; }
.legal-table .lt-doc  { font-weight: 600; color: #111827; }
.dark .legal-table .lt-doc { color: #f9fafb; }
.legal-table .lt-applies { color: #6b7280; }
.dark .legal-table .lt-applies { color: #9ca3af; }


/* ── 20b. Application mark tile ─────────────────────────────
   The RF Command icon keeps the application's own colours, and its folder
   is white, so it needs a dark surface behind it or it vanishes on a light
   page. This is the standard app-icon treatment: a rounded dark tile.
   Set the size on the tile, not on the image.
     <span class="app-mark" style="width:36px;height:36px"><img ...></span>  */
.app-mark {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  background: linear-gradient(145deg, #1b2f57 0%, #0a1428 100%);
  border: 1px solid rgba(255, 255, 255, 0.12);
  border-radius: 24%;
  overflow: hidden;
}
.app-mark img { width: 74%; height: 74%; display: block; }


/* ── 21. Parent-site link (product sites) ──────────────── */
.parent-link {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  font-size: 0.75rem;
  font-weight: 500;
  color: rgba(255, 255, 255, 0.45);
  text-decoration: none;
  transition: color 0.2s;
  white-space: nowrap;
}
.parent-link:hover                  { color: rgba(255, 255, 255, 0.9); }
#navbar.scrolled .parent-link       { color: #9ca3af; }
#navbar.scrolled .parent-link:hover { color: var(--rf-blue); }
.dark #navbar.scrolled .parent-link:hover { color: var(--rf-cyan); }


/* ── 22. Feature showcase (tabs + carousel) ────────────── */
.sc { --sc-radius: 20px; }

/* The tabs wrap at every width. They used to be a horizontal scroll strip
   below 1024px, which hid most of the categories on a phone: the fade on the
   right edge was the only hint that anything else existed. Wrapping costs a
   few rows of height and shows all ten at once. */
.sc-tabs {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 8px;
  margin-bottom: 22px;
}

.sc-tab {
  flex-shrink: 0;
  padding: 9px 18px;
  min-height: 44px;
  border-radius: 999px;
  border: 1px solid var(--rf-border);
  background: var(--rf-raised);
  color: #4b5563;
  font-size: 0.875rem;
  font-weight: 600;
  cursor: pointer;
  white-space: nowrap;
  transition: background 0.2s, color 0.2s, border-color 0.2s, transform 0.15s;
}
.sc-tab:hover { border-color: #cfdeeb; color: var(--rf-blue); transform: translateY(-1px); }
.sc-tab.is-active {
  background: var(--rf-blue);
  border-color: var(--rf-blue);
  color: #fff;
  box-shadow: 0 3px 12px rgba(29, 43, 78, 0.18);
}
.dark .sc-tab           { color: #9ca3af; }
.dark .sc-tab:hover     { border-color: rgba(78,159,209,0.32); color: #fff; }
.dark .sc-tab.is-active { background: var(--rf-lblue); border-color: var(--rf-lblue); color: #fff; }
@media (max-width: 640px) {
  .sc-tab { padding: 8px 13px; font-size: 0.8125rem; }
}

.sc-panel { display: none; }
.sc-panel.is-active { display: block; }

/* Fixed-ratio stage so nothing shifts while media loads, drawn as a matte
   around the clip. The clips are filmed at whatever size RF Command happens to
   be open at, so their shape changes from one capture to the next. When the
   picture filled the stage edge to edge, every capture that was not exactly
   16:10 left thin bars of a different navy along two sides, and they moved
   each time the set was re-filmed. Now the stage is the frame: a muted navy
   ground with padding all round, and the clip sits centred inside it at its own
   shape, with its own corners and shadow. Any spare room is part of the frame,
   so a clip of any size looks deliberate. The side padding also keeps the
   carousel arrows on the matte rather than over the picture. */
.sc-stage {
  position: relative;
  aspect-ratio: 16 / 10;
  border-radius: var(--sc-radius);
  overflow: hidden;
  background:
    radial-gradient(ellipse 75% 65% at 50% 45%, rgba(78, 159, 209, 0.14) 0%, transparent 70%),
    linear-gradient(160deg, #1d2b4e 0%, #111b33 55%, #0b1424 100%);
  border: 1px solid #e5e7eb;
}
.dark .sc-stage { border-color: #1f2937; }

.sc-slide {
  position: absolute;
  inset: 0;
  margin: 0;
  box-sizing: border-box;
  padding: 4.5% 7.5%;
  display: flex;
  align-items: center;
  justify-content: center;
  opacity: 0;
  visibility: hidden;
  transition: opacity 0.35s var(--ease), visibility 0.35s;
}
.sc-slide.is-active { opacity: 1; visibility: visible; }
/* Sized by max-width and max-height rather than filling the slide, so the
   element's box is exactly the picture and the corners, edge and shadow hug the
   clip instead of an invisible letterbox around it. */
.sc-slide img,
.sc-slide video {
  display: block;
  width: auto;
  height: auto;
  max-width: 100%;
  max-height: 100%;
  min-width: 0;
  min-height: 0;
  border-radius: 10px;
  outline: 1px solid rgba(255, 255, 255, 0.10);
  outline-offset: -1px;
  box-shadow: 0 14px 38px rgba(0, 0, 0, 0.45), 0 2px 8px rgba(0, 0, 0, 0.30);
}
@media (max-width: 640px) {
  .sc-slide { padding: 5% 4%; }
  .sc-slide img,
  .sc-slide video { border-radius: 6px; }
}

/* The caption sits between the tabs and the stage, not under everything. It is
   the claim the slide is making, so it is read before the clip rather than
   after it, and it is sized to be read: 1.125rem, and white on dark rather
   than the grey it used to be, which disappeared against the band. */
.sc-cap {
  min-height: 3.25rem;
  margin: 0 0 16px;
  font-size: 1.125rem;
  line-height: 1.55;
  font-weight: 500;
  color: var(--rf-blue);
  text-align: center;
  max-width: 62ch;
  margin-inline: auto;
}
.dark .sc-cap { color: #fff; }
@media (max-width: 640px) {
  .sc-cap { font-size: 1rem; min-height: 3.75rem; }
}

.sc-prev, .sc-next {
  position: absolute;
  top: 50%;
  transform: translateY(-50%);
  width: 48px; height: 48px;
  border-radius: 999px;
  border: 1px solid rgba(255, 255, 255, 0.9);
  background: rgba(255, 255, 255, 0.94);
  backdrop-filter: blur(8px);
  -webkit-backdrop-filter: blur(8px);
  color: var(--rf-blue);
  display: flex; align-items: center; justify-content: center;
  cursor: pointer;
  /* Always visible, and light on purpose. They used to fade in on hover, so the
     showcase looked like a single picture and most people never found the other
     slides. Then they were dark translucent, which put a dark circle on top of a
     dark screenshot: technically visible, actually invisible. A near-white disc
     with a navy arrow is the one combination that reads against every clip in
     the set, all of which are screenshots of a dark application. */
  opacity: 1;
  box-shadow: 0 2px 14px rgba(0, 0, 0, 0.45);
  transition: background 0.2s, transform 0.15s, border-color 0.2s;
  z-index: 2;
}
.sc-prev { left: 14px; }
.sc-next { right: 14px; }
.sc-prev:hover, .sc-next:hover {
  background: var(--rf-lblue);
  border-color: #fff;
  color: #fff;
  transform: translateY(-50%) scale(1.06);
}
.sc-prev:focus-visible, .sc-next:focus-visible {
  outline: 2px solid var(--rf-cyan);
  outline-offset: 2px;
}

/* "3 / 5", bottom right of the stage. Sits over the picture so it cannot fall
   off the bottom of a short window the way the dot bar can, and so the answer to
   "am I back at the first one" is a number rather than a count of dots. */
.sc-count {
  position: absolute;
  right: 14px;
  bottom: 14px;
  z-index: 2;
  padding: 5px 12px;
  border-radius: 999px;
  border: 1px solid rgba(255, 255, 255, 0.28);
  background: rgba(6, 12, 26, 0.82);
  backdrop-filter: blur(8px);
  -webkit-backdrop-filter: blur(8px);
  color: #fff;
  font-size: 0.875rem;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
  letter-spacing: 0.02em;
  pointer-events: none;
}

.sc-dots { display: flex; justify-content: center; gap: 10px; margin-top: 18px; }
.sc-dot {
  width: 11px; height: 11px;
  border-radius: 999px;
  border: none;
  padding: 0;
  background: #d1d5db;
  cursor: pointer;
  transition: background 0.2s, width 0.24s var(--ease);
}
.dark .sc-dot { background: #4b5563; }
.sc-dot:hover { background: var(--rf-lblue); }
.sc-dot.is-active { width: 30px; background: var(--rf-lblue); }
.dark .sc-dot.is-active { background: var(--rf-cyan); }


/* ── 23. Image placeholder ─────────────────────────────────
   Stands in for artwork that has not been captured yet.
   Delete the .ph element once the real asset is dropped in. */
.ph {
  position: absolute;
  inset: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 8px;
  padding: 24px;
  text-align: center;
  border: 2px dashed rgba(255,255,255,0.16);
  border-radius: inherit;
  background:
    repeating-linear-gradient(45deg, rgba(255,255,255,0.018) 0 12px, transparent 12px 24px),
    #0b1424;
  color: rgba(255,255,255,0.5);
}
/* Keep the text clear of the carousel arrows, which sit 14px from each edge. */
.ph > * { max-width: min(100%, 30ch); }
.ph-label { font-size: 0.8125rem; font-weight: 700; letter-spacing: 0.06em; text-transform: uppercase; color: rgba(255,255,255,0.75); }
.ph-path  { font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace; font-size: 0.75rem; color: var(--rf-cyan); word-break: break-all; }
.ph-size  { font-size: 0.6875rem; letter-spacing: 0.08em; text-transform: uppercase; color: rgba(255,255,255,0.35); }
@media (max-width: 640px) {
  .ph { padding: 24px 56px; }
  .ph-path { font-size: 0.6875rem; }
}

/* Standalone (non-absolute) placeholder box */
.ph-box { position: relative; aspect-ratio: 16 / 10; border-radius: var(--radius-card); overflow: hidden; }


/* ── 24. Help page: contents rail and key tables ───────── */
.help-toc { position: sticky; top: calc(var(--nav-h) + 24px); }
.help-toc a {
  display: block;
  padding: 7px 12px;
  border-radius: 8px;
  font-size: 0.8125rem;
  line-height: 1.4;
  color: #6b7280;
  text-decoration: none;
  border-left: 2px solid transparent;
  transition: color 0.18s, background 0.18s, border-color 0.18s;
}
.help-toc a:hover { color: var(--rf-blue); background: #f9fafb; border-left-color: var(--rf-lblue); }
.dark .help-toc a { color: #9ca3af; }
.dark .help-toc a:hover { color: #fff; background: #111827; border-left-color: var(--rf-cyan); }

.key-table { width: 100%; border-collapse: collapse; font-size: 0.875rem; }
.key-table th {
  text-align: left;
  font-size: 0.6875rem;
  font-weight: 700;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: #9ca3af;
  padding: 0 14px 10px;
  border-bottom: 1px solid #e5e7eb;
  white-space: nowrap;
}
.dark .key-table th { border-bottom-color: #1f2937; }
.key-table td { padding: 11px 14px; border-bottom: 1px solid #f3f4f6; vertical-align: top; color: #4b5563; }
.dark .key-table td { border-bottom-color: #111827; color: #9ca3af; }
.key-table tr:last-child td { border-bottom: none; }
.key-table td:first-child { white-space: nowrap; }

/* Wide tables scroll inside their own box, never the page */
.table-scroll { overflow-x: auto; -webkit-overflow-scrolling: touch; }

kbd, .kbd {
  display: inline-block;
  padding: 2px 7px;
  border-radius: 6px;
  border: 1px solid #d1d5db;
  border-bottom-width: 2px;
  background: #f9fafb;
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  font-size: 0.75rem;
  font-weight: 600;
  line-height: 1.5;
  color: #374151;
  white-space: nowrap;
}
.dark kbd, .dark .kbd { background: #1f2937; border-color: #374151; color: #e5e7eb; }


/* ── 25. Numbered steps (support / how-to) ─────────────── */
.step-row { display: flex; gap: 18px; }
.step-dot {
  flex-shrink: 0;
  width: 34px; height: 34px;
  border-radius: 10px;
  display: flex; align-items: center; justify-content: center;
  font-size: 0.875rem;
  font-weight: 800;
  color: #fff;
  background: linear-gradient(145deg, var(--rf-cyan), var(--rf-lblue));
}


/* ── 26. Reduced motion ────────────────────────────────── */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
    scroll-behavior: auto !important;
  }
  .reveal { opacity: 1; transform: none; }
  .h-title, .h-sub, .h-scroll { opacity: 1; transform: none; }
  .hero-win { opacity: 1; transform: none; animation: none; }
  .hero-win:hover { scale: var(--zoom); }
}


/* ── 27. Phone layout and touch targets ────────────────────
   Everything in this section applies only at phone widths, and
   nothing above it was changed to make room for it. Three things
   drive it.

   A fingertip covers roughly 44px and a mouse pointer covers one,
   so controls sized for the pointer (the theme and menu buttons,
   the carousel dots, the modal close, the footer link columns)
   get a larger hit area without looking any different.

   A three-column key table has nowhere to go at 375px: the first
   column is nowrap, so on the wider tables the description was
   being squeezed into 119px and wrapping to six lines. Below
   640px each row stacks instead, one cell per line.

   The one thing not fixed by CSS is the showcase tab strip, which
   used to scroll sideways and hid eight of its ten categories off
   the right edge. That is fixed in section 22, where the strip now
   wraps at every width. */

@media (max-width: 767px) {

  /* Navbar controls. The icon stays 20px; only the padding grows. */
  #themeToggle,
  #menuBtn { padding: 12px; }

  /* Coming Soon modal close button. */
  #cs-close-btn { width: 40px; height: 40px; top: 12px; right: 12px; }

  /* Footer link columns and the legal row under them. Inline-block
     so the padding actually applies to the anchor box. */
  footer li > a,
  footer .flex-wrap > a { display: inline-block; padding: 8px 0; }

  /* "Read the help", "View all news" and the rest. */
  .arrow-link { padding: 8px 0; }

  /* Help page jump list. Uppercase at 11px is the smallest type on
     the site, and here it is a link rather than a label. */
  .badge-gray { padding: 7px 12px; font-size: 0.75rem; }

  /* Carousel dots. The dot itself is unchanged; it moves into a
     pseudo-element so the button around it can be a real target. */
  .sc-dots { gap: 2px; }
  .sc-dot {
    width: 26px; height: 34px;
    background: none;
    display: flex; align-items: center; justify-content: center;
  }
  .sc-dot::before {
    content: '';
    width: 8px; height: 8px;
    border-radius: 999px;
    background: #d1d5db;
    transition: width 0.24s var(--ease), background 0.2s;
  }
  .dark .sc-dot::before { background: #374151; }
  .sc-dot.is-active { width: 42px; background: none; }
  .sc-dot.is-active::before { width: 24px; background: var(--rf-lblue); }
  .dark .sc-dot.is-active::before { background: var(--rf-cyan); }
}

@media (max-width: 640px) {

  /* Hero window cascade. Four cascading windows at 360px wide leave each
     one about 180px across, too small to read anything in. The main
     window goes full width on its own and the other three drop. */
  .hero-stack { aspect-ratio: auto; }
  .hero-win-1 { position: static; width: 100%; }
  .hero-win-2,
  .hero-win-3,
  .hero-win-4 { display: none; }

  /* Cards. 32px of padding either side is a fifth of a 320px
     screen spent on nothing. */
  .f-card { padding: 24px; }

  /* An email address is one unbreakable token, and a grid row is
     as wide as its widest cell, so Support@RationalForge.com sitting
     in a button was pushing the whole About row past the edge of a
     320px screen. "anywhere" rather than "break-word": only
     "anywhere" lowers the min-content width, which is the
     measurement that was doing the damage. It still breaks as a last
     resort, so nothing changes at 375px and up. */
  a[href^="mailto:"],
  a[href^="mailto:"] * { overflow-wrap: anywhere; }

  /* Key tables stack. The header row is dropped rather than hidden
     with display:none, so a screen reader still reads it. */
  .key-table thead {
    position: absolute;
    width: 1px; height: 1px;
    margin: -1px;
    overflow: hidden;
    clip-path: inset(50%);
    white-space: nowrap;
  }
  /* Each row becomes its own flex line, which is the whole point:
     a table shares one column width across every row, so the single
     widest key ("Shift + Enter") was setting the key column for all
     of them and leaving the description 119px. A flex row sizes to
     its own key instead. */
  .key-table tr {
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    column-gap: 12px;
    row-gap: 4px;
    padding: 12px 0;
    border-bottom: 1px solid #f3f4f6;
  }
  .dark .key-table tr { border-bottom-color: #111827; }
  .key-table tr:last-child { border-bottom: none; }
  .key-table td { display: block; padding: 0; border: none; }
  .key-table td:first-child { flex: 0 0 auto; }

  /* Two-column rows: the description sits beside the key when at
     least 170px is left for it, and drops to its own full-width
     line when the key is long. That is what the flex-basis buys. */
  .key-table td:nth-child(2) { flex: 1 1 170px; min-width: 0; }

  /* Three-column rows: key and verb share the first line, the note
     always takes the second. */
  .key-table tr:has(td:nth-child(3)) td:nth-child(2) {
    flex: 0 1 auto;
    font-weight: 600;
    color: #374151;
  }
  .dark .key-table tr:has(td:nth-child(3)) td:nth-child(2) { color: #e5e7eb; }
  .key-table td:nth-child(3) { flex: 1 1 100%; }
}
