/* ============================================================================
   SHOGUN — shared stylesheet for index.html, docs.html, buy.html.

   Full light palette on bare :root so the un-stamped "system" state resolves;
   the dark block is guarded so an explicit light choice still wins; the
   [data-theme="dark"] block repeats it so a toggle wins in both directions.
   ========================================================================= */

:root {
  --paper:      #E9ECF0;
  --surface:    #FDFDFE;
  --surface-2:  #F3F5F8;
  --ink:        #14181E;
  --ink-2:      #39424F;
  --muted:      #656F7D;
  --rule:       #CFD6DF;
  --rule-soft:  #E1E6EC;
  --brass:      #8A5F14;
  --brass-ink:  #6E4B0F;
  --brass-wash: #F5EDDC;
  /* SEMANTIC ONLY. In this subject red and green already mean stop and fill - they are
     never decoration, which is exactly why the accent above is brass. */
  --fill:       #1C6B45;
  --stop:       #A6302A;
  --stop-wash:  #FBEEED;
  --shadow:     0 1px 2px rgba(20,24,30,.06), 0 8px 24px -12px rgba(20,24,30,.18);
}
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    --paper:      #0D1014;
    --surface:    #14181E;
    --surface-2:  #1A1F26;
    --ink:        #E7EBF0;
    --ink-2:      #B7C0CC;
    --muted:      #8D98A6;
    --rule:       #262D36;
    --rule-soft:  #1E242C;
    --brass:      #D8A44B;
    --brass-ink:  #E9BC6E;
    --brass-wash: #221B0E;
    --fill:       #4FB383;
    --stop:       #E0685F;
    --stop-wash:  #24110F;
    --shadow:     0 1px 2px rgba(0,0,0,.4), 0 8px 24px -12px rgba(0,0,0,.6);
  }
}
:root[data-theme="dark"] {
  --paper:#0D1014; --surface:#14181E; --surface-2:#1A1F26; --ink:#E7EBF0; --ink-2:#B7C0CC;
  --muted:#8D98A6; --rule:#262D36; --rule-soft:#1E242C; --brass:#D8A44B; --brass-ink:#E9BC6E;
  --brass-wash:#221B0E; --fill:#4FB383; --stop:#E0685F; --stop-wash:#24110F;
  --shadow:0 1px 2px rgba(0,0,0,.4), 0 8px 24px -12px rgba(0,0,0,.6);
}

* { box-sizing: border-box; }
body {
  margin: 0;
  background: var(--paper);
  color: var(--ink);
  font-family: "IBM Plex Sans", ui-sans-serif, system-ui, sans-serif;
  font-size: 16px;
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
}
.wrap { max-width: 1060px; margin: 0 auto; padding: 0 28px; }
.narrow { max-width: 660px; }

/* ⭐ TRACKING IS BOUND TO SIZE, NOT SET ONCE. Type that is optically correct at 17px is
   visibly loose at 66px: the bigger the glyphs, the more air there already is between
   them, so display sizes need MORE negative tracking and body sizes need almost none.
   Setting one global value is the single most common reason a page with good content
   still reads as amateur. Leading runs the other way — tight at display size, open at
   reading size. */
h1, h2, h3 { font-family: "IBM Plex Sans Condensed", "IBM Plex Sans", sans-serif; font-weight: 700;
             text-wrap: balance; margin: 0; }
h1 { font-size: clamp(2.6rem, 6vw, 4.1rem); line-height: 1.02; letter-spacing: -.024em; }
h2 { font-size: clamp(1.7rem, 3.2vw, 2.3rem); line-height: 1.08; letter-spacing: -.018em; }
h3 { font-size: 1.06rem; font-weight: 600; line-height: 1.35; letter-spacing: -.004em;
     font-family: "IBM Plex Sans", sans-serif; }
p  { margin: 0; }
a  { color: var(--brass-ink); }
code, .mono { font-family: "IBM Plex Mono", ui-monospace, "Cascadia Mono", monospace;
              font-variant-numeric: tabular-nums; }
code { font-size: .92em; }

.eyebrow {
  font-family: "IBM Plex Mono", monospace; font-size: .72rem; font-weight: 500;
  letter-spacing: .16em; text-transform: uppercase; color: var(--muted);
}

/* ---- masthead ---- */
header.top {
  border-bottom: 1px solid var(--rule);
  background: color-mix(in srgb, var(--surface) 80%, transparent);
  position: sticky; top: 0; z-index: 10; backdrop-filter: blur(8px);
}
.top .wrap { display: flex; align-items: center; justify-content: space-between; gap: 20px; height: 62px; }
.brand { display: flex; align-items: baseline; gap: 11px; text-decoration: none; color: inherit; }
.brand b { font-family: "IBM Plex Sans Condensed", sans-serif; font-size: 1.3rem; letter-spacing: .02em; }
.brand span { font-family: "IBM Plex Mono", monospace; font-size: .68rem; letter-spacing: .14em;
              color: var(--muted); text-transform: uppercase; }
nav.top-nav { display: flex; gap: 24px; font-size: .88rem; }
nav.top-nav a { color: var(--ink-2); text-decoration: none; }
nav.top-nav a:hover, nav.top-nav a[aria-current="page"] { color: var(--brass-ink); }
@media (max-width: 720px) { nav.top-nav { display: none; } }

/* ---- buttons ---- */
.btn {
  display: inline-block; padding: 11px 20px; border-radius: 3px; text-decoration: none;
  font-weight: 600; font-size: .94rem; border: 1px solid transparent;
}
.btn-primary { background: var(--brass); color: #fff; }
:root[data-theme="dark"] .btn-primary, :root:not([data-theme="light"]) .btn-primary { color: #14181E; }
@media (prefers-color-scheme: light) { :root:not([data-theme="dark"]) .btn-primary { color: #fff; } }
.btn-primary:hover { background: var(--brass-ink); }
.btn-ghost { border-color: var(--rule); color: var(--ink); }
.btn-ghost:hover { border-color: var(--brass); color: var(--brass-ink); }
.req { font-size: .82rem; color: var(--muted); font-family: "IBM Plex Mono", monospace; }

/* ---- section frame ---- */
/* ⛔ `scroll-margin-top` IS NOT OPTIONAL HERE. The masthead is `position: sticky` at 62px,
   so without this every in-page anchor in the nav lands with its own heading hidden behind
   the bar — the reader clicks "Safety" and arrives at a paragraph with no title. 78px is
   the bar plus a little air. (docs.html already did this for its h2s; the home page simply
   never got the same rule.) */
section { padding: 66px 0; border-top: 1px solid var(--rule); scroll-margin-top: 78px; }
.sec-head { margin-bottom: 34px; }
.sec-head h2 { margin-top: 8px; }
.sec-head p { color: var(--ink-2); margin-top: 12px; max-width: 58ch; }

/* ---- code ---- */
pre { margin: 14px 0 0; background: var(--surface-2); border: 1px solid var(--rule-soft);
      border-radius: 3px; padding: 13px 15px; overflow-x: auto; font-size: .78rem; line-height: 1.55; }
pre code { color: var(--ink-2); font-size: 1em; }
.k { color: var(--brass-ink); }
.s { color: var(--fill); }
.c { color: var(--muted); }

/* ---- callouts: the docs page lives or dies on these ---- */
.note {
  border: 1px solid var(--rule); border-left: 3px solid var(--brass); background: var(--surface);
  border-radius: 3px; padding: 15px 18px; margin-top: 18px;
}
.note .lbl { font-family: "IBM Plex Mono", monospace; font-size: .68rem; letter-spacing: .14em;
             text-transform: uppercase; color: var(--brass-ink); display: block; margin-bottom: 6px; }
.note p { font-size: .92rem; color: var(--ink-2); }
.note p + p { margin-top: 9px; }
.note.warn { border-left-color: var(--stop); background: var(--stop-wash); }
.note.warn .lbl { color: var(--stop); }
.note.warn p { color: var(--ink-2); }

/* ---- tables: the triage table is the whole point of the docs page ---- */
.table-scroll { overflow-x: auto; margin-top: 18px; border: 1px solid var(--rule); border-radius: 4px; }
table { border-collapse: collapse; width: 100%; background: var(--surface); font-size: .92rem; }
th, td { text-align: left; padding: 12px 15px; border-bottom: 1px solid var(--rule-soft);
         vertical-align: top; }
thead th { background: var(--surface-2); font-family: "IBM Plex Mono", monospace; font-weight: 500;
           font-size: .68rem; letter-spacing: .12em; text-transform: uppercase; color: var(--muted);
           white-space: nowrap; }
tbody tr:last-child td { border-bottom: 0; }
td:first-child { color: var(--ink); }
td { color: var(--ink-2); }

/* ---- marks ---- */
.mk { font-family: "IBM Plex Mono", monospace; font-weight: 600; line-height: 1.5; }
.mk-y { color: var(--fill); }
.mk-n { color: var(--stop); }

/* ---- the risk block. Deliberately not styled to be skimmed past. ---- */
.risk-block { border: 1px solid var(--rule); border-left: 3px solid var(--stop);
              background: var(--surface); border-radius: 3px; padding: 26px 28px; }
.risk-block h3 { font-family: "IBM Plex Sans Condensed", sans-serif; font-size: 1.15rem;
                 font-weight: 700; margin-bottom: 6px; }
.risk-block h4 { font-size: .95rem; font-weight: 600; margin: 20px 0 0; color: var(--ink); }
.risk-block p { font-size: .92rem; color: var(--ink-2); margin-top: 8px; max-width: 74ch; }
.risk-block ul { margin: 10px 0 0; padding-left: 20px; color: var(--ink-2); font-size: .92rem;
                 max-width: 74ch; }
.risk-block li { margin-top: 7px; }
.risk-block li::marker { color: var(--stop); }
.risk-block .lede-risk { font-size: .96rem; color: var(--ink); }

/* ---- footer ---- */
footer { border-top: 1px solid var(--rule); padding: 34px 0 54px; color: var(--muted); font-size: .84rem; }
.foot-grid { display: flex; justify-content: space-between; gap: 24px; flex-wrap: wrap; align-items: baseline; }
.foot-nav { display: flex; gap: 20px; }
.foot-nav a { color: var(--muted); text-decoration: none; }
.foot-nav a:hover { color: var(--brass-ink); }
.risk { margin-top: 18px; max-width: 72ch; line-height: 1.6; }

summary:focus-visible, a:focus-visible, .btn:focus-visible { outline: 2px solid var(--brass); outline-offset: 3px; }

/* ============================================================================
   MOTION AND RHYTHM (S193).

   🩸 THE PROBLEM THIS SOLVES, IN MARK'S WORDS: "ours is VERY boring." He was right,
   and the cause was not the writing — it was that every section looked identical, so
   a page of genuinely specific content read as one undifferentiated wall.

   ⛔ WHAT WE DID NOT DO ABOUT IT. The competitor we were compared against leads with
   testimonials, five-star reviews and "99% of traders aren't profitable". We have no
   customers yet, so we have no testimonials — and inventing them is not on the table at
   any price. Everything below adds RHYTHM, DEPTH AND MOVEMENT to claims that were
   already true. Not one word of evidence was manufactured to make the page livelier.

   ⭐ EVERY ANIMATED STATE IS KEYED OFF `html.js-on`, which site.js sets and which is
   never set when the reader has asked for reduced motion. With scripts off, the page is
   the same page.
   ========================================================================= */

/* ---- section rhythm: alternating ground, so the eye has somewhere to rest ---- */
section.tint { background: var(--surface-2); }
section.tint + section { border-top-color: var(--rule); }

/* ---- scroll progress. A one-pixel line that says the page is alive and how far in. ---- */
.progress {
  position: fixed; top: 0; left: 0; right: 0; height: 2px; z-index: 30;
  background: transparent; pointer-events: none;
}
.progress::after {
  content: ""; display: block; height: 100%; transform-origin: 0 50%;
  transform: scaleX(var(--progress, 0));
  background: linear-gradient(90deg, var(--brass), var(--fill));
}
:root:not(.js-on) .progress { display: none; }

/* ---- parallax. ⭐ `--py` runs -1 (element low on screen) to +1 (high), set by site.js;
   every rule below is a TRANSFORM, so nothing here triggers layout. ---- */
[data-parallax] { will-change: transform; }
.js-on [data-parallax="slow"]  { transform: translate3d(0, calc(var(--py, 0) * 26px), 0); }
.js-on [data-parallax="fast"]  { transform: translate3d(0, calc(var(--py, 0) * -34px), 0); }
.js-on [data-parallax="tilt"]  {
  transform: translate3d(0, calc(var(--py, 0) * 14px), 0)
             rotate(calc(var(--py, 0) * -0.5deg));
}

/* ---- a quiet field behind the hero. Instrument, not outer space. ---- */
.hero-field { position: relative; isolation: isolate; overflow: hidden; }
.hero-field::before {
  content: ""; position: absolute; inset: -40% -10% auto -10%; height: 150%;
  z-index: -1; pointer-events: none;
  background:
    radial-gradient(58% 52% at 20% 2%, color-mix(in srgb, var(--brass) 30%, transparent), transparent 68%),
    radial-gradient(44% 44% at 86% 14%, color-mix(in srgb, var(--fill) 20%, transparent), transparent 70%);
}
/* ⭐ A DRIFT SLOW ENOUGH THAT NOBODY WATCHES IT. The point is that the page is not a
   photograph — ⛔ not that anything is happening. 34s and a 2% travel: noticeable only if
   you look away and back, which is exactly the budget a page like this should spend. */
@keyframes shogun-drift {
  0%, 100% { transform: translate3d(0, 0, 0)      scale(1);    }
  50%      { transform: translate3d(2%, -1.5%, 0) scale(1.06); }
}
.js-on .hero-field::before { animation: shogun-drift 34s ease-in-out infinite; }
/* A fine rule grid — the background of every charting tool ever made. */
.hero-field::after {
  content: ""; position: absolute; inset: 0; z-index: -1; pointer-events: none;
  background-image:
    linear-gradient(to right, var(--rule-soft) 1px, transparent 1px),
    linear-gradient(to bottom, var(--rule-soft) 1px, transparent 1px);
  background-size: 58px 58px;
  /* 🔒 "as you move the page it moves too" — the grid slides at a fraction of the scroll,
     which is the cheapest honest parallax there is: one background-position, no layout,
     no extra element. `--sy` is the page offset, written once per frame by site.js. */
  background-position: 0 calc(var(--sy, 0) * 0.18px);
  -webkit-mask-image: radial-gradient(75% 65% at 50% 25%, #000 25%, transparent 78%);
  mask-image: radial-gradient(75% 65% at 50% 25%, #000 25%, transparent 78%);
  opacity: .75;
}

/* ============================================================================
   THE SIGNAL FLOW — the one piece of real imagery on this page.

   ⭐ WHY A SCHEMATIC AND ⛔ NOT A CHART. The obvious "not boring" move for a trading
   site is a rising line, a candle chart or an equity curve. Every one of those implies a
   RESULT, and we sell execution, not results — an animated green line climbing behind a
   buy button is the exact thing the risk section spends four paragraphs undoing.
   ⭐ A diagram of how the thing is wired is honest, it is ours, it moves, and it teaches
   the reader the one fact most competitors hide: where the software actually sits.
   ========================================================================= */
/* 🩸 THIS WAS AN SVG WITH `min-width: 640px` AND IT PUT A 98px HORIZONTAL SCROLL ON EVERY
   PHONE. An SVG cannot reflow: its viewBox is fixed, so the only two options were "scale it
   down" — which takes the 13px labels to under 6px — or "let it scroll sideways", which is
   the single most recognisable amateur tell on a mobile page. ⭐ Real HTML boxes reflow:
   four across on a desktop, stacked on a phone, with the connector rotating to match. They
   are also selectable, searchable and readable by a screen reader, which SVG <text> is not.
   ⛔ Do not put it back as an SVG to "keep it crisp" — it was never crisp on the device
   most people will open this on. */
.flow { position: relative; margin-top: 8px; }
.flow-steps {
  list-style: none; margin: 0; padding: 0;
  display: grid; grid-template-columns: repeat(4, 1fr); gap: 34px;
}
.f-node {
  position: relative; background: var(--surface); border: 1px solid var(--rule);
  border-radius: 4px; padding: 15px 16px 17px;
}
/* ⭐ The one box that is ours, marked the way the heading says it is. */
.f-node.is-ours { border-color: var(--brass); }
.f-node b { display: block; font-size: .98rem; font-weight: 600; color: var(--ink); }
.f-node span {
  display: block; margin-top: 5px; font-family: "IBM Plex Mono", monospace;
  font-size: .66rem; letter-spacing: .13em; text-transform: uppercase; color: var(--muted);
}
/* The connector lives in the gap, so it never affects layout width. */
.f-node:not(:last-child)::after {
  content: ""; position: absolute; top: 50%; left: 100%; width: 34px; height: 2px;
  transform: translateY(-50%);
  background-image: repeating-linear-gradient(to right,
    var(--brass) 0 5px, transparent 5px 14px);
  background-size: 14px 2px;
}
.js-on .f-node:not(:last-child)::after { animation: flow-dash 1.1s linear infinite; }
@keyframes flow-dash { to { background-position: 14px 0; } }

@media (max-width: 760px) {
  .flow-steps { grid-template-columns: 1fr; gap: 30px; }
  /* ⭐ The connector rotates with the layout: across on desktop, down on a phone. */
  .f-node:not(:last-child)::after {
    top: 100%; left: 26px; width: 2px; height: 30px; transform: none;
    background-image: repeating-linear-gradient(to bottom,
      var(--brass) 0 5px, transparent 5px 14px);
    background-size: 2px 14px;
  }
  @keyframes flow-dash { to { background-position: 0 14px; } }
}
.flow-note { margin-top: 26px; font-size: .86rem; color: var(--muted); max-width: 64ch; }

/* ---- reveal on first sight. ⛔ Once, never on every pass. ---- */
.js-on [data-reveal] { opacity: 0; transform: translateY(14px); }
.js-on [data-reveal].shown {
  opacity: 1; transform: none;
  transition: opacity .62s cubic-bezier(.22,.61,.36,1), transform .62s cubic-bezier(.22,.61,.36,1);
}
.js-on [data-reveal][data-delay="1"].shown { transition-delay: .07s; }
.js-on [data-reveal][data-delay="2"].shown { transition-delay: .14s; }
.js-on [data-reveal][data-delay="3"].shown { transition-delay: .21s; }

/* ---- the log plays itself. The one object worth animating: it is the product. ---- */
.js-on [data-log] .log-row { opacity: 0; transform: translateY(6px); }
.js-on [data-log] .log-row.in {
  opacity: 1; transform: none;
  transition: opacity .34s ease-out, transform .34s cubic-bezier(.22,.61,.36,1);
}
@keyframes shogun-pulse {
  0%, 100% { opacity: 1; box-shadow: 0 0 0 0 color-mix(in srgb, var(--fill) 55%, transparent); }
  50%      { opacity: .55; box-shadow: 0 0 0 5px color-mix(in srgb, var(--fill) 0%, transparent); }
}
.js-on .dot { animation: shogun-pulse 2.1s ease-in-out infinite; }

/* ---- cards that respond to a cursor. Cheap, and it makes a page feel awake. ---- */
.guard, .step, .price-card, .stat {
  transition: border-color .2s ease, transform .2s ease, box-shadow .2s ease;
}
.guard:hover { transform: translateY(-2px); box-shadow: var(--shadow); }

/* ---- fact strip: numbers we can actually stand behind ---- */
.stats {
  display: grid; grid-template-columns: repeat(4, 1fr); gap: 1px;
  background: var(--rule); border: 1px solid var(--rule); border-radius: 4px;
  overflow: hidden; margin-top: 44px;
}
@media (max-width: 760px) { .stats { grid-template-columns: repeat(2, 1fr); } }
.stat { background: var(--surface); padding: 18px 18px 20px; }
.stat b {
  display: block; font-family: "IBM Plex Sans Condensed", sans-serif; font-weight: 700;
  font-size: 1.62rem; line-height: 1.1; color: var(--ink); letter-spacing: -.01em;
}
.stat span { display: block; margin-top: 5px; font-size: .84rem; color: var(--muted); }

/* ---- a closing call to action, repeated where a reader is ready to act ---- */
.cta-strip {
  margin-top: 42px; border: 1px solid var(--rule); border-left: 3px solid var(--brass);
  border-radius: 4px; background: var(--surface); padding: 22px 24px;
  display: flex; gap: 18px; align-items: center; justify-content: space-between; flex-wrap: wrap;
}
.cta-strip p { color: var(--ink-2); font-size: .95rem; max-width: 56ch; }
.cta-strip strong { color: var(--ink); }

/* ---- the honest substitute for a wall of five-star reviews ---- */
/* 🩸 THIS WAS `1px dashed` AND `max-width: 720px`, AND THE CSS WAS ARGUING WITH THE COPY.
   A dashed border is the universal convention for a placeholder — a drop zone, a missing
   image, content pending. The words in this block say "having no testimonials is a
   deliberate policy"; the styling said "something is supposed to go here and has not
   arrived yet". A reader resolves that conflict in favour of the picture every time.
   ⭐ It now gets the same solid, full-width, brass-edged treatment as the sections we are
   confident about — because it IS one of them. */
.no-proof {
  border: 1px solid var(--rule); border-left: 3px solid var(--brass); border-radius: 4px;
  background: var(--surface); padding: 28px 30px 30px;
}
.no-proof h3 { font-family: "IBM Plex Sans Condensed", sans-serif; font-size: 1.18rem;
               font-weight: 700; margin-bottom: 8px; }
.no-proof p { color: var(--ink-2); font-size: .94rem; }
.no-proof p + p { margin-top: 10px; }

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