/* ===== Bigul Connect — API Docs (dark, static) ===== */
  *,*::before,*::after{box-sizing:border-box;margin:0;padding:0;}
  :root{
    --accent:#5367fc;
    --groww:#5367fc;
    --blue:#60a5fa;
    --teal:#00ffc1;
    --bg-primary:#000000;
    --bg-secondary:#0a0f24;
    --bg-tertiary:#0d1235;
    --border-dark:#1a2560;
    --border-soft:rgba(83,103,252,0.18);
    --text-primary:#ffffff;
    --text-secondary:#94a3b8;
    --text3:#64748b;
    --cyan:#00d2ff;
    --topbar-h:64px;
    /* Single family for the whole documentation site. Code/monospace contexts
       reuse it too — no separate monospace face is loaded (see fonts.css). */
    --font-primary:"Poppins",sans-serif;
    --mono:var(--font-primary);
  }
  html{scroll-behavior:smooth;}
  html,body,button,input,select,textarea,table,code,pre,dialog{font-family:var(--font-primary);}
  body{
    color:var(--text-primary);
    background:var(--bg-primary);
    -webkit-font-smoothing:antialiased;
    min-height:100vh;
  }
  h1,h2,h3,h4,h5{font-family:var(--font-primary);letter-spacing:-0.02em;}
  a{color:inherit;text-decoration:none;}
  .mono,code,pre{font-family:var(--mono);}

  /* Screen-reader-only text that stays focusable/announced. */
  .sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;
    clip:rect(0 0 0 0);clip-path:inset(50%);white-space:nowrap;border:0;}
  /* Skip link — off-screen until keyboard focus pulls it into view. */
  .skip-link{position:absolute;left:8px;top:-48px;z-index:200;padding:9px 14px;border-radius:10px;
    background:var(--accent);color:#fff;font-size:13px;font-weight:600;transition:top .18s ease;}
  .skip-link:focus{top:8px;}
  .main:focus{outline:none;}

  /* ===== Top bar =====
     64px bar with its content constrained to a 1280px column, centred by the
     padding expression rather than an extra wrapper element.

     The gutter is 24px — home's `nav.topnav .inner{padding:0 24px}` — not the
     32px it used to be. Together with the -20px pull on .brand below (also
     home's value) this reproduces home's logo position EXACTLY at every width,
     because both resolve their `100%` against the same box: the element's own
     width, which excludes the scrollbar. */
  .topbar{position:sticky;top:0;z-index:70;display:flex;align-items:center;justify-content:space-between;gap:16px;
    height:var(--topbar-h);padding:0 max(24px, calc((100% - 1280px) / 2 + 24px));
    border-bottom:1px solid rgba(255,255,255,0.06);
    background:rgba(5,7,15,0.85);backdrop-filter:blur(14px);}
  /* margin-right:auto keeps the mark hard left, matching the home navbar.
     Without it the row's space-between pushes .brand into the middle as soon
     as .menu-btn appears below 1024px, which read as a centred logo. */
  .brand{display:flex;align-items:center;min-width:0;flex-shrink:0;margin-right:auto;}
  /* Sized to the home navbar (`nav.topnav .logo img`: 96px, 128px from 640px),
     so the mark is identical across the two headers. The intrinsic ratio is
     kept and the taller logo deliberately overhangs the 64px bar, as upstream. */
  .brand img{height:96px;width:auto;max-width:100%;object-fit:contain;}
  @media(min-width:640px){.brand img{height:128px;}}
  /* Home's own pull (`nav.topnav .logo{margin-left:-20px}`), which optically
     compensates the mark's transparent left margin. With the 24px gutter above,
     this puts the artwork on the same pixel as home's at every width.

     The mark previously sat absolutely at left:12px to line up with .sidebar's
     nav items instead. That held the logo at a constant 16px while home's
     tracked the centred column, so the two headers diverged by up to 145px on
     a wide screen — matching home is what was actually wanted.

     Only above 1024px: below that .menu-btn is visible and sits immediately to
     the mark's left, so a negative margin would collide with it. */
  @media(min-width:1024px){ .brand{margin-left:-20px;} }
  .topbar-right{display:flex;align-items:center;gap:12px;}
  @media(min-width:640px){.topbar-right{gap:24px;}}

  /* Primary nav links */
  .nav-btn{font-size:12px;font-weight:600;letter-spacing:.025em;text-transform:uppercase;
    color:var(--text-secondary);white-space:nowrap;transition:color .2s ease;}
  @media(min-width:640px){.nav-btn{font-size:14px;}}
  .nav-btn:hover{color:var(--text-primary);}
  .nav-btn.active{color:#5367fc;text-transform:none;}
  html.light .nav-btn{color:#475569;}
  html.light .nav-btn:hover{color:#0f172a;}
  html.light .nav-btn.active{color:#5367fc;}

  /* Theme toggle pill */
  .theme-pill{display:inline-flex;align-items:center;gap:6px;padding:6px 10px;border-radius:9999px;
    border:1px solid rgba(26,37,96,0.6);background:rgba(13,18,53,0.4);cursor:pointer;flex-shrink:0;
    transition:background .2s ease,border-color .2s ease,transform .2s ease,box-shadow .2s ease;}
  @media(min-width:640px){.theme-pill{padding:6px 12px;}}
  .theme-pill:hover{background:var(--bg-tertiary);border-color:rgba(83,103,252,0.4);
    transform:scale(1.04);box-shadow:0 0 12px rgba(83,103,252,0.2);}
  .theme-pill svg{width:14px;height:14px;flex-shrink:0;}
  .theme-pill [data-theme-label]{font-size:11px;font-weight:600;color:var(--text-secondary);}
  @media(max-width:639px){.theme-pill [data-theme-label]{display:none;}}
  html.light .theme-pill{border-color:var(--border-dark);background:#ffffff;}
  html.light .theme-pill [data-theme-label]{color:#475569;}
  /* Hamburger — hidden on desktop, shown at mobile breakpoint */
  .menu-btn{display:none;align-items:center;justify-content:center;flex-shrink:0;width:38px;height:38px;
    border-radius:10px;border:1px solid var(--border-dark);background:transparent;color:#cbd5e1;cursor:pointer;transition:.2s;}
  .menu-btn:hover{color:#fff;border-color:var(--border-soft);}
  .menu-btn svg{width:18px;height:18px;}

  /* ===== Layout — three columns: sidebar | main | on-this-page ===== */
  /* ---- Embedded mode (api-docs.html?embed=1) --------------------
     Shown inside the signed-in dashboard, which provides the header. Drop
     this page's own public bar and collapse the sticky offset it created,
     so .sidebar still fills the frame instead of leaving a 64px gap at the
     top. The sidebar itself stays — it is the only route to a group's
     sibling sub-pages, which the dashboard's topic list does not cover. */
  html.docs-embed .topbar{display:none;}
  html.docs-embed .skip-link{display:none;}
  html.docs-embed{--topbar-h:0px;}

  .shell{display:flex;align-items:flex-start;}
  .sidebar{position:sticky;top:var(--topbar-h);align-self:flex-start;width:288px;flex-shrink:0;height:calc(100vh - var(--topbar-h));
    overflow-y:auto;border-right:1px solid var(--border-dark);background:#04050c;padding:14px 12px 24px;display:none;}
  /* flex column, not block: this is what lets .nav-foot's margin-top:auto
     absorb the leftover height and sit at the bottom of the panel. */
  @media(min-width:1024px){.sidebar{display:flex;flex-direction:column;}}
  /* The sidebar's own 8px/4px scrollbar rules were removed: being class-scoped
     they outranked the global themed scrollbar in animations.css, so this one
     panel kept a different width, radius and no track while every other
     scroller picked up the new styling. */

  /* Sidebar search — a real input, and the only search field on the page. */
  .nav-search{position:relative;display:flex;align-items:center;gap:8px;background:rgba(20,20,22,0.9);
    border:1px solid var(--border-dark);border-radius:12px;padding:8px 10px;color:var(--text3);margin-bottom:10px;
    transition:border-color .18s ease;}
  .nav-search:focus-within{border-color:var(--groww);}
  .nav-search svg{width:14px;height:14px;flex-shrink:0;}
  .nav-search input{flex:1;min-width:0;border:0;background:transparent;color:var(--text-primary);
    font-size:12px;font-weight:600;padding:0;outline:none;}
  .nav-search input::placeholder{color:var(--text3);font-weight:600;}
  .nav-search input::-webkit-search-cancel-button{-webkit-appearance:none;appearance:none;}
  .nav-search .kbd{display:flex;gap:2px;font-size:9px;font-weight:700;flex-shrink:0;
    background:var(--bg-tertiary);border:1px solid var(--border-dark);border-radius:4px;padding:1px 4px;}

  /* Search results list */
  .search-results{margin-bottom:12px;border:1px solid var(--border-dark);border-radius:12px;
    background:var(--bg-secondary);overflow:hidden;max-height:320px;overflow-y:auto;}
  .search-results[hidden]{display:none;}
  .search-results .sr-item{display:block;width:100%;text-align:left;padding:9px 12px;border:0;background:transparent;
    color:#e5e7eb;font-size:11.5px;font-weight:600;cursor:pointer;line-height:1.35;
    border-bottom:1px solid rgba(26,37,96,0.5);}
  .search-results .sr-item:last-child{border-bottom:none;}
  .search-results .sr-item:hover,.search-results .sr-item:focus-visible{background:rgba(83,103,252,0.16);color:#fff;}
  .search-results .sr-item .sr-group{display:block;font-size:9.5px;font-weight:700;text-transform:uppercase;
    letter-spacing:.08em;color:var(--text3);margin-top:2px;}
  .search-results .sr-item mark{background:rgba(83,103,252,0.32);color:inherit;border-radius:3px;padding:0 1px;}
  .search-results .sr-empty{padding:12px;font-size:11.5px;font-weight:600;color:var(--text3);}
  html.light .search-results{background:#ffffff;border-color:var(--border-dark);}
  html.light .search-results .sr-item{color:#0f172a;border-bottom-color:#eef2f7;}
  html.light .search-results .sr-item:hover,
  html.light .search-results .sr-item:focus-visible{background:#eef2ff;}
  html.light .search-results .sr-item mark{background:rgba(83,103,252,0.22);}

  /* ===== Right "On this page" panel ===== */
  /* Viewport-tall like .sidebar so the left border forms a full-height rail
     (the baseline aside is self-stretch inside its own scroll container). */
  .toc{display:none;position:sticky;top:var(--topbar-h);align-self:flex-start;
    width:256px;flex-shrink:0;height:calc(100vh - var(--topbar-h));overflow-y:auto;
    padding:24px;border-left:1px solid var(--border-dark);background:var(--bg-primary);}
  @media(min-width:1024px){.toc{display:block;}}
  @media(min-width:1280px){.toc{width:288px;}}
  .toc-head{display:flex;align-items:center;gap:6px;margin-bottom:16px;
    font-size:10px;font-weight:700;text-transform:uppercase;letter-spacing:.05em;
    color:var(--text-secondary);letter-spacing:.08em;user-select:none;}
  .toc-head svg{width:14px;height:14px;flex-shrink:0;}
  .toc-list{display:flex;flex-direction:column;gap:16px;margin-top:8px;
    border-left:1px solid var(--border-dark);padding-left:16px;}
  .toc-link{display:block;width:100%;text-align:left;border:0;background:transparent;padding:0;cursor:pointer;
    font-size:12px;font-weight:600;line-height:1.45;color:var(--text3);
    transition:color .18s ease,transform .18s ease;}
  .toc-link:hover{color:#e5e7eb;transform:translateX(2px);}
  .toc-link.active{color:#fff;font-weight:800;margin-left:-17px;padding-left:15px;
    border-left:2px solid var(--groww);transform:none;}
  html.light .toc{background:var(--bg-primary);border-left-color:var(--border-dark);}
  html.light .toc-link{color:#64748b;}
  html.light .toc-link:hover{color:#0f172a;}
  html.light .toc-link.active{color:#0f172a;border-left-color:var(--accent);}
  .nav-group{margin-bottom:4px;}
  /* Real <button> elements (so Enter/Space activate them natively) — reset the
     UA button chrome so they look exactly like the previous div did. */
  .nav-group>.nav-top{display:flex;align-items:center;gap:8px;padding:9px 10px;border-radius:12px;width:100%;
    background:transparent;border:0;color:inherit;font:inherit;text-align:left;}
  .nav-group>.nav-top .gi{color:var(--blue);display:flex;flex-shrink:0;}
  .nav-group>.nav-top .gi svg{width:15px;height:15px;}
  .nav-group>.nav-top .gt{font-size:12px;font-weight:700;color:#e5e7eb;}
  .nav-group>.nav-top .chev{margin-left:auto;color:var(--text3);}
  .nav-group>.nav-top .chev svg{width:11px;height:11px;transform:rotate(90deg);}
  .nav-sub{margin-left:20px;border-left:1px solid rgba(55,65,81,0.5);padding:2px 0;}
  .nav-sub a{display:block;padding:6px 4px 6px 16px;font-size:11px;font-weight:500;color:#9ca3af;
    border-left:2px solid transparent;margin-left:-1px;border-radius:0 8px 8px 0;transition:.15s;}
  .nav-sub a:hover{color:#fff;background:rgba(30,41,59,0.4);}
  /* Pinned to the BOTTOM of the sidebar rather than trailing the last nav
     group. .sidebar is a fixed-height scrolling column, so it becomes a flex
     column (below) and this takes the leftover space above it via margin-top.
     When the nav list is taller than the panel the note simply follows the
     content and scrolls into view, which is the behaviour you want — it is
     never clipped or overlapped. 18px is kept as a MINIMUM gap so the note
     doesn't butt against the last group on a tall viewport. */
  .nav-foot{margin-top:auto;padding:14px;text-align:center;border-top:1px solid rgba(55,65,81,0.5);flex-shrink:0;}
  .nav-foot span{font-family:var(--mono);font-size:10px;font-weight:700;letter-spacing:.12em;color:var(--text3);text-transform:uppercase;}
  /* The nav groups sit in a wrapper-less flow, so give the last one breathing
     room from the pinned note when the column is fully packed. */
  .nav-group:last-of-type{margin-bottom:18px;}

  /* ===== Main ===== */
  .main{flex:1;min-width:0;}
  .crumb{position:sticky;top:var(--topbar-h);z-index:30;display:flex;align-items:center;gap:8px;height:40px;
    padding:0 24px;font-size:11px;font-weight:500;color:var(--text3);
    background:rgba(5,7,15,0.9);backdrop-filter:blur(8px);border-bottom:1px solid var(--border-dark);}
  @media(min-width:640px){.crumb{padding:0 40px;}}
  .crumb svg{width:14px;height:14px;}
  .crumb .cur{color:#fff;font-weight:600;}
  /* Baseline content column: max-w-4xl (896px) with p-6 / sm:p-10 / md:p-14.
     React's padding is symmetric, so the bottom value must equal the top one —
     the old 80/96/120px bottom values were the "excessive blank space at the
     bottom of every API screen". */
  .content{max-width:896px;margin:0 auto;padding:24px;}
  @media(min-width:640px){.content{padding:40px;}}
  @media(min-width:768px){.content{padding:56px;}}

  /* ===== Section hero ===== */
  /* React renders the title block as the first child of the padded column with
     no extra top margin (space-y-12 only inserts gaps *between* children), so
     any margin-top here is pure dead space above the page title. */
  .doc-section{padding-top:0;}
  .sec-hero{border-bottom:1px solid var(--border-dark);padding-bottom:24px;margin:0 0 48px;}
  .sec-hero .eyebrow{display:inline-block;font-family:var(--font-primary);font-size:12px;line-height:1.5;
    text-transform:uppercase;letter-spacing:.1em;color:#8da9c4;font-weight:800;}
  /* text-3xl sm:text-5xl */
  .sec-hero h1{font-size:30px;font-weight:800;margin-top:4px;line-height:1.1;}
  @media(min-width:640px){.sec-hero h1{font-size:48px;line-height:1;}}
  /* Intro description: React is text-sm md:text-base, font-medium, gray-400.
     The old 70ch clamp narrowed it well inside the 896px column — React lets it
     run the full width of the container. */
  .sec-hero p{color:#9ca3af;font-size:14px;font-weight:500;margin-top:8px;line-height:1.6;white-space:pre-wrap;max-width:none;}
  @media(min-width:768px){.sec-hero p{font-size:16px;}}

  /* ===== Subsection ===== */
  /* space-y-12 (48px) between blocks; the trailing margin on the last visible
     subsection is dropped so it does not stack with the column padding. */
  /* Top-only margin: adjacent-sibling collapse still gives the 48px gap after
     the hero, but nothing is added below the last block — that trailing margin
     was stacking with the column padding into the reported bottom gap. */
  .subsec{margin:48px 0 0;scroll-margin-top:112px;}
  .subsec-title{font-size:24px;font-weight:800;margin-bottom:22px;}
  @media(min-width:640px){.subsec-title{font-size:30px;}}

  /* ===== Content primitives ===== */
  .subsec p+p{margin-top:12px;}
  /* Baseline: rounded-3xl (24px), p-6 (24px), bg-blue-950/20, border-blue-900/30 */
  .callout{background:rgba(23,37,84,0.20);border:1px solid rgba(30,58,138,0.30);border-radius:24px;padding:24px;margin:20px 0;}
  .callout.soft{background:rgba(23,37,84,0.12);}
  .callout>*+*{margin-top:10px;}
  /* Standardised type scale — mirrors the React scale exactly so every doc
     screen uses the same sizes/weights for titles and descriptions:
       section title  h4  18px / 600   (text-lg font-semibold)
       callout title  h5  14px / 600   (text-sm font-semibold)
       body copy          14px / 400   (text-sm)
       card title         14px / 600   (text-sm font-semibold)
       card description   12px / 400   (text-xs) */
  .headline{font-size:18px;font-weight:600;border-bottom:1px solid var(--border-dark);padding-bottom:8px;margin:28px 0 12px;color:#fff;}
  .callout .headline{margin-top:0;}
  .subhead{font-size:14px;font-weight:600;color:#fff;margin:8px 0 10px;}
  .mini{font-size:10px;text-transform:uppercase;letter-spacing:.09em;font-weight:800;color:var(--text3);margin:20px 0 10px;}
  .lead{color:var(--text-secondary);font-size:14px;line-height:1.65;}
  .sdk-links{display:flex;flex-wrap:wrap;align-items:center;gap:16px;}
  .sdk-link{display:inline-flex;align-items:center;gap:8px;}
  .sdk-link img{width:18px;height:18px;flex:0 0 auto;}
  .lead+.lead{margin-top:10px;}
  .note{font-size:12px;color:var(--text3);background:var(--bg-secondary);border:1px solid var(--border-dark);border-radius:12px;padding:12px 14px;margin:12px 0;line-height:1.6;}
  /* Informational / warning callouts use the brand blue on a brand-blue tint,
     matching React's `text-groww/80 bg-groww/10 border-groww/20`. */
  .tip{font-size:12px;color:#ffffff;background:rgba(83,103,252,0.10);border:1px solid rgba(83,103,252,0.22);border-radius:12px;padding:12px 14px;margin:12px 0;font-weight:600;line-height:1.6;}
  .tip strong{color:#5367fc;}
  .warn{font-size:12px;color:#5367fc;background:rgba(83,103,252,0.10);border:1px solid rgba(83,103,252,0.22);border-radius:12px;padding:12px 14px;margin:12px 0;font-weight:600;line-height:1.6;}
  .stack>*+*{margin-top:12px;}

  .grid2{display:grid;grid-template-columns:1fr;gap:12px;margin:14px 0;}
  .grid3{display:grid;grid-template-columns:1fr;gap:12px;margin:14px 0;}
  @media(min-width:640px){.grid2{grid-template-columns:1fr 1fr;}.grid3{grid-template-columns:1fr 1fr;}}
  .grid2>*,.grid3>*{min-width:0;}
  html,body{max-width:100%;}
  @media(min-width:900px){.grid3{grid-template-columns:1fr 1fr 1fr;}}
  /* Card borders follow the shared token (#1a2560 dark / #E2E8F0 light). */
  .itembox{background:var(--bg-secondary);border:1px solid var(--border-dark);border-radius:16px;padding:14px 16px;margin-bottom:16px;}
  /* Card title -> description gap is 2px in React (mt-0.5); the block title's
     own line-height is tightened so the pair reads as one unit. */
  .itembox strong,.itembox .t{display:block;font-size:14px;font-weight:600;line-height:1.35;color:#fff;}
  .itembox p,.itembox span{font-size:12px;color:var(--text-secondary);line-height:1.6;}
  .itembox strong+p,.itembox .t+p,.itembox strong+span,.itembox .t+span{margin-top:2px;}
  .itembox p+p{margin-top:2px;}
  .itembox .em{font-size:20px;margin-bottom:2px;display:inline-block;}

  div#intro .grid2 .itembox .check { margin: 8px 0; }

  /* ==============================
     .formula-card — the OTR formula block.

     .formula-card, .formula-line, .formula-result and .mini-strong were all
     used in api-docs.html with NO rules, so the card fell back to the generic
     .itembox treatment: every line took .itembox p's 12px --text-secondary and
     .itembox p+p's 2px gap, which jammed four lines together and left the
     result reading exactly like its own inputs. .mini also brought a standalone
     margin (20px 0 10px) into a 14px-padded card, so the label sat lopsided.

     Alignment stays flush-left rather than centred: the A and B lines are
     descriptive prose ("API hits for Order Place, Modify, and Cancel
     requests"), and centring a wrapped sentence breaks the eye's return
     path. The definitions now share one left edge and the result is separated
     by a hairline so it reads as the conclusion, not a third input.
     ============================== */
  .formula-card{padding:16px 18px 18px;}
  /* .mini's own 10px never applied inside a card: .itembox p is (0,1,1) and
     outranks .mini's (0,1,0), so the kicker had always rendered at 12px —
     level with the body copy and carrying no hierarchy. Restated here, along
     with neutralising .mini's standalone 20px/10px margins. */
  .formula-card .mini{font-size:10px;margin:0 0 12px;}
  .formula-card .mini-strong{color:var(--blue);letter-spacing:.12em;}
  /* Override .itembox p (12px/--text-secondary) and .itembox p+p (2px). The
     first line follows the label <p>, so .itembox p+p hits it too. */
  .formula-card .formula-line{font-size:13px;line-height:1.65;color:var(--text-primary);margin-top:0;}
  .formula-card .formula-line+.formula-line{margin-top:7px;}
  /* The result is the payoff: hairline above it, accent-tinted, slightly
     larger. 15px against the 13px definitions is a deliberate step, not a jump.

     Selector needs the sibling combinator, not just .formula-card
     .formula-result: the element carries BOTH formula-line and formula-result,
     so the rule above (0,3,0) matches it and would otherwise beat a (0,2,0)
     rule and clamp this 13px back down to 7px. */
  .formula-card .formula-line+.formula-result{margin-top:13px;padding-top:13px;
    border-top:1px solid var(--border-dark);
    font-size:15px;font-weight:700;color:var(--accent);letter-spacing:.01em;}

  /* List rows sit further apart than before (7/8px -> 10px) so bulleted and
     checked lists breathe the way the React lists do. */
  .check{display:flex;align-items:flex-start;gap:9px;font-size:14px;color:var(--text-secondary);line-height:1.6;margin:10px 0;}
  .ic-check{color:var(--groww);}
  .grid2 .check,.grid3 .check{background:var(--bg-secondary);border:1px solid var(--border-dark);border-radius:14px;padding:11px 13px;margin:0;font-size:12px;}
  .ic{width:15px;height:15px;flex-shrink:0;margin-top:2px;}
  .ic-check{width:15px;height:15px;flex-shrink:0;margin-top:1px;}
  /* .itembox-row had NO rule, so these check-icon cards fell back to .itembox's
     plain block layout: the <svg> and <span> ran as inline siblings with no gap
     (the tick touched the first character) and wrapped lines returned to the
     card's left edge, tucking under the icon instead of holding the text
     column. The .check family two rules up already solves exactly this, so this
     borrows its flex treatment verbatim — same 9px gap, same flex-start — which
     keeps the two card styles consistent on the page. .ic-check already carries
     flex-shrink:0 and its optical nudge, so it needs no change.

     min-width:0 on the text guards the flex item against the min-content
     floor, the same trap that was pushing content out of .stepcard. */
  .itembox-row{display:flex;align-items:flex-start;gap:9px;}
  .itembox-row>span{min-width:0;}

  .dot{display:flex;align-items:flex-start;gap:9px;font-size:14px;color:var(--text-secondary);line-height:1.6;margin:10px 0;}
  .dot .dotmark{width:6px;height:6px;border-radius:9999px;background:var(--groww);flex-shrink:0;margin-top:7px;}

  .stepcard{display:flex;align-items:flex-start;gap:12px;background:var(--bg-secondary);border:1px solid var(--border-dark);border-radius:14px;padding:14px 16px;margin:10px 0;}
  .stepnum{width:28px;height:28px;border-radius:9999px;background:rgba(83,103,252,0.18);color:var(--accent);
    display:flex;align-items:center;justify-content:center;font-size:12px;font-weight:700;flex-shrink:0;}
  /* The content wrapper had NO rule, so it kept the flex default min-width:auto
     and could not shrink below its min-content width. The long unbreakable URLs
     in pre.code (white-space:pre) made that minimum far wider than the card, so
     the copy, code blocks and tables all overflowed the right edge. pre.code's
     own overflow:auto/max-width:100% could never engage, because they resolve
     against this wrapper — which had already blown past the card.

     min-width:0 lets it shrink to the track; the descendants' existing
     overflow-x:auto (.tablewrap, pre.code) then scroll internally as intended. */
  .stepcard > div{flex:1 1 auto;min-width:0;}
  .stepttl{font-size:14px;font-weight:600;line-height:1.35;color:#fff;}
  .stepcard .lead{margin-top:2px;font-size:12px;}
  .stepcard .mono{color:var(--blue);font-size:12px;}

  /* ===== Step / flow infographics =================================
     .steprow, .stepnode, .flowrow, .flowcard, .flowdown and .flowresult
     were used in api-docs.html but had NO rules at all, so the markup fell
     back to plain block/inline layout: the badge, "Step 1" and the label ran
     together on one line and the five nodes stacked vertically. These make
     them read as the intended horizontal flow.

     Colours follow the existing .stepcard family (--bg-secondary card,
     --border-dark hairline, 14px radius). Text uses --blue rather than
     --accent: #5367fc on the dark card is only 4.0:1, which the small
     uppercase kicker cannot carry. ============================== */
  .steprow{display:grid;grid-template-columns:repeat(5,1fr);gap:26px;margin:16px 0 6px;}
  .stepnode{position:relative;display:flex;flex-direction:column;align-items:center;text-align:center;gap:7px;
    background:var(--bg-secondary);border:1px solid var(--border-dark);border-radius:14px;padding:16px 10px 14px;}
  /* Chevron sits in the grid gap, so it never overlaps a card. */
  .stepnode::after{content:"";position:absolute;top:50%;right:-19px;width:11px;height:11px;
    border-right:1.5px solid var(--accent);border-top:1.5px solid var(--accent);
    transform:translateY(-50%) rotate(45deg);}
  .stepnode:last-child::after{display:none;}
  .stepbadge{font-size:20px;line-height:1;}
  .stepkicker{font-size:10px;font-weight:700;letter-spacing:.14em;text-transform:uppercase;color:var(--blue);}
  .stepname{font-size:13px;font-weight:600;line-height:1.35;color:var(--text-primary);}

  .flowrow{display:flex;align-items:stretch;flex-wrap:wrap;gap:12px;margin:16px 0;}
  /* 140px basis, not 170: the widest of these rows is 4 cards + 3 arrows in a
     737px column. At 170 the row needed 4x170 + 45 + 72 = 797px, so the fourth
     card wrapped to its own line and flex-grow stretched it to the full 737px.
     140 keeps all four on one row (4x140 + 45 + 72 = 617). */
  .flowcard{flex:1 1 140px;display:flex;flex-direction:column;justify-content:center;gap:6px;
    background:var(--bg-secondary);border:1px solid var(--border-dark);border-radius:14px;padding:14px 16px;}
  .flowcard-eq{align-items:center;text-align:center;}
  .flownum{font-size:11px;font-weight:800;letter-spacing:.12em;color:var(--blue);}
  .flowttl{font-size:13px;font-weight:600;line-height:1.35;color:var(--text-primary);}
  .flowarrow{flex:0 0 auto;display:flex;align-items:center;justify-content:center;
    font-size:15px;font-weight:700;color:var(--accent);}
  .flowdown{display:flex;justify-content:center;font-size:17px;line-height:1;color:var(--accent);margin:9px 0;}
  .flowresult{display:flex;align-items:center;justify-content:center;text-align:center;
    background:var(--bg-secondary);border:1px solid var(--border-dark);border-radius:14px;padding:14px 16px;}
  .flowresult-ok{background:rgba(0,220,140,0.10);border-color:rgba(0,220,140,0.42);}
  .flowresult-ok .flowttl{color:#34d399;}

  /* ==============================
     .iflow — the "Typical Integration Flow" infographic.

     Its own namespace rather than a reworked .flowrow: the second .flowrow on
     this page is the TOTP login composition (three inputs joined by "+", not a
     numbered sequence), so it must keep the plain card row.

     Layout is a 4-column grid so the medallion centres land on exact quarters
     (12.5% / 37.5% / 62.5% / 87.5%) — that lets the rail span left:12.5% to
     right:12.5% and terminate dead-centre under the first and last medallion
     without per-node connector hacks.

     Colours stay in the .flowcard family: --bg-secondary card, --border-dark
     hairline, --blue for the icon and kicker, --accent for the connector. The
     terminal node reuses the .flowresult-ok green (rgba(0,220,140) / #34d399)
     that already means "done" on this page. ============================== */
  /* The rail is a sibling of the <ol> rather than a child: only <li> and
     script-supporting elements are valid children of a list. */
  .iflow-wrap{position:relative;margin:18px 0 6px;}
  .iflow{list-style:none;display:grid;grid-template-columns:repeat(4,1fr);
    gap:0 12px;margin:0;padding:0;}

  /* Rail sits behind the medallions, pinned to their vertical centre (32px =
     half the 64px medallion) and terminating on the first and last centre.
     The inset is half a column, NOT 12.5%: with a 12px gap the columns are
     (100% - 3x12px)/4 wide, so a flat 12.5% overshoots each end by ~4.5px and
     the rail pokes out from under the medallion. */
  .iflow-rail{position:absolute;top:32px;height:2px;overflow:hidden;
    left:calc((100% - 36px) / 8);right:calc((100% - 36px) / 8);
    background:linear-gradient(90deg,rgba(83,103,252,0.22),rgba(83,103,252,0.55),rgba(83,103,252,0.22));
    border-radius:2px;}
  /* 28% wide spark travelling the full rail: -100% is fully off the left edge,
     357% (100/28 x 100) is fully off the right. */
  .iflow-spark{display:none;}
  @keyframes iflow-run{0%{transform:translateX(-100%);}100%{transform:translateX(357%);}}

  .iflow-step{position:relative;display:flex;flex-direction:column;align-items:center;
    text-align:center;gap:12px;}

  .iflow-node{position:relative;flex:0 0 auto;width:64px;height:64px;border-radius:50%;
    display:flex;align-items:center;justify-content:center;
    /* Two layers, not one: the tint fades to `transparent` over an OPAQUE
       base. A single gradient starting at rgba(...,0.10) is 90% see-through at
       its focal point, so .iflow-rail — which crosses the medallion at its
       own vertical centre (top:32px = this circle's midline) — showed straight
       through the glass. The opaque second layer hides the rail while the
       first keeps the light tint. */
    background:radial-gradient(circle at 32% 26%,rgba(83,103,252,0.10),transparent 72%),
      var(--bg-secondary);
    border:1.5px solid rgba(83,103,252,0.25);color:var(--blue);
    box-shadow:0 0 0 6px var(--bg-primary);}
  .iflow-node svg{width:24px;height:24px;}
  .iflow-step:hover .iflow-node,.iflow-step:focus-within .iflow-node{
    transform:translateY(-3px);border-color:var(--accent);color:var(--text-primary);
    box-shadow:0 0 0 6px var(--bg-primary),0 8px 22px rgba(83,103,252,0.30);}

  /* Number badge overlaps the medallion ring at 4-o'clock. White on #5367fc is
     4.6:1 — fine for 11px/800, not for a regular weight. */
  .iflow-num{position:absolute;right:-5px;bottom:-3px;min-width:24px;height:20px;padding:0 5px;
    border-radius:10px;display:flex;align-items:center;justify-content:center;
    background:var(--accent);color:#ffffff;font-size:11px;font-weight:800;letter-spacing:.06em;
    border:2px solid var(--bg-primary,#050a1e);}

  .iflow-body{display:flex;flex-direction:column;gap:5px;max-width:190px;}
  .iflow-ttl{margin:0;font-size:13.5px;font-weight:700;line-height:1.3;color:var(--text-primary);}
  .iflow-desc{margin:0;font-size:12px;font-weight:400;line-height:1.55;color:var(--text-secondary);}
  .iflow-desc code{font-size:11px;}

  /* Terminal node — the flow ends in access, so it reads as the success state. */
  .iflow-step.is-live .iflow-node{
    background:radial-gradient(circle at 32% 26%,rgba(0,220,140,0.20),transparent 72%),
      var(--bg-secondary);
    border-color:rgba(0,220,140,0.55);color:#34d399;}
  .iflow-step.is-live .iflow-num{background:#0f9d63;}
  .iflow-step.is-live:hover .iflow-node,.iflow-step.is-live:focus-within .iflow-node{
    border-color:#34d399;color:#ffffff;
    box-shadow:0 0 0 6px var(--bg-primary),0 8px 22px rgba(0,220,140,0.28);}

  /* Same 860px threshold the .steprow flow uses: four labelled nodes cannot
     hold a readable line length below it, so the rail turns vertical and each
     step becomes a left-aligned row. */
  @media(max-width:860px){
    .iflow{grid-template-columns:1fr;gap:22px 0;}
    .iflow-step{flex-direction:row;align-items:flex-start;text-align:left;gap:16px;}
    .iflow-body{max-width:none;}

    /* Vertical rail becomes a per-step connector rather than one spanning bar.
       A single bar would need its bottom pinned to the LAST medallion's centre,
       which is only 32px above the wrap's bottom edge when that row is exactly
       64px tall — a two-line caption breaks it. Each connector instead runs
       from its own node's bottom edge (64px) across the 22px row gap to the
       next node, so it self-adjusts to any caption height. */
    .iflow-rail{display:none;}
    .iflow-step::before{content:"";position:absolute;left:31px;top:64px;bottom:-22px;width:2px;
      background:linear-gradient(180deg,rgba(83,103,252,0.55),rgba(83,103,252,0.20));}
    .iflow-step:last-child::before{display:none;}
  }

  @media(prefers-reduced-motion:reduce){
    .iflow-spark{animation:none;opacity:.55;}
    .iflow-node{transition:none;}
  }

  /* Below 860px five columns cannot hold "Generate QR Code", so the flow
     becomes a single column and the chevron rotates to point down. */
  @media(max-width:860px){
    .steprow{grid-template-columns:1fr;gap:26px;}
    .stepnode{padding:14px 16px;}
    .stepnode::after{top:auto;bottom:-19px;right:auto;left:50%;transform:translateX(-50%) rotate(135deg);}
  }

  html.light .stepnode,
  html.light .flowcard,
  html.light .flowresult{background:#ffffff;border-color:var(--border-dark);}
  html.light .stepname,
  html.light .flowttl{color:#0f172a;}
  /* #5367fc is 4.07:1 on white — under 4.5 for these small labels. */
  html.light .stepkicker,
  html.light .flownum{color:#3b3fc0;}
  html.light .flowarrow,
  html.light .flowdown{color:#3b3fc0;}
  html.light .stepnode::after{border-right-color:#3b3fc0;border-top-color:#3b3fc0;}
  html.light .flowresult-ok{background:#ecfdf5;border-color:#6ee7b7;}
  html.light .flowresult-ok .flowttl{color:#15803d;}

  /* .iflow on white. The medallion icon takes #3b3fc0 for the same reason the
     kicker does above: --blue resolves to #5367fc in light mode, which is
     4.07:1 and under AA for a 24px hairline stroke. */
  html.light .iflow-node{
    background:radial-gradient(circle at 32% 26%,rgba(83,103,252,0.10),transparent 72%),#ffffff;
    border-color:rgba(83,103,252,0.35);color:#3b3fc0;}
  html.light .iflow-step:hover .iflow-node,
  html.light .iflow-step:focus-within .iflow-node{border-color:var(--accent);color:#1e1b8f;}
  html.light .iflow-ttl{color:#0f172a;}
  html.light .iflow-spark{background:linear-gradient(90deg,transparent,#3b3fc0,transparent);}
  html.light .iflow-step.is-live .iflow-node{
    background:radial-gradient(circle at 32% 26%,rgba(0,220,140,0.14),transparent 72%),#ffffff;
    border-color:#6ee7b7;color:#15803d;}
  html.light .iflow-step.is-live .iflow-num{background:#15803d;}
  html.light .iflow-step.is-live:hover .iflow-node,
  html.light .iflow-step.is-live:focus-within .iflow-node{border-color:#15803d;color:#0f5132;}
  @media(max-width:860px){
    html.light .iflow-step::before{
      background:linear-gradient(180deg,rgba(59,63,192,0.55),rgba(59,63,192,0.18));}
  }

  /* .tip-block is a two-line variant of .tip (an OTR limit and its
     explanation). The container inherits .tip, but .tip-title and .tip-body had
     no rules, so both paragraphs rendered identically and the figure carried no
     emphasis. The title also needs its own size — .tip sets 12px for the whole
     box, which is too small for a headline number. */
  .tip-block{display:block;}
  /* The title carries the figure ("Maximum Allowed OTR: 49 : 1"), so it takes
     --text-primary instead of inheriting .tip's #5367fc — white on the
     indigo-tinted panel is the strongest reading of the limit. .tip-body keeps
     the inherited accent, which is what separates the two lines now that the
     title no longer differs by colour alone. Light mode is handled in the
     html.light block: white would vanish on .tip's pale background there. */
  .tip-title{font-size:13px;font-weight:700;line-height:1.4;color:var(--text-primary);}
  .tip-body{font-size:12px;font-weight:400;line-height:1.55;margin-top:4px;opacity:.88;}

  /* ===== Tables ===== */
  .tablewrap{overflow-x:auto;border:1px solid var(--border-dark);border-radius:16px;margin:14px 0;}
  table.dt{width:100%;border-collapse:collapse;font-size:12px;text-align:left;}
  table.dt thead tr{background:rgba(13,18,53,0.75);}
  table.dt th{padding:11px 13px;font-size:9px;text-transform:uppercase;letter-spacing:.11em;font-weight:700;color:var(--text-secondary);border-bottom:1px solid var(--border-dark);white-space:nowrap;}
  table.dt td{padding:11px 13px;border-bottom:1px solid rgba(26,37,96,0.5);color:var(--text-secondary);vertical-align:top;}
  table.dt tbody tr:last-child td{border-bottom:none;}
  table.dt tbody tr:hover{background:rgba(13,18,53,0.35);}
  table.dt td.mono{font-family:var(--mono);color:var(--blue);font-weight:600;font-size:12px;}
  /* Key/value example tables (Example Header, Default Configuration, request
     header samples …): React renders the key cell as text-primary/semibold and
     the value cell as the mono blue. Matched by structure so every such table
     across every page picks it up. */
  table.dt tbody td:first-child:has(+ td.mono){color:var(--text-primary);font-weight:600;}
  table.dt td.mono.green{color:#34d399;}
  .req{font-size:9px;font-weight:800;padding:2px 6px;border-radius:6px;}
  .req.yes{background:rgba(37,99,235,0.18);color:var(--blue);border:1px solid rgba(37,99,235,0.3);}
  .req.no{background:rgba(148,163,184,0.12);color:var(--text-secondary);border:1px solid rgba(148,163,184,0.2);}

  /* ===== Code ===== */
  pre.code{background:#04050c;border:1px solid var(--border-dark);border-radius:14px;padding:16px;overflow:auto;min-width:0;max-width:100%;
    font-family:var(--mono);font-size:12px;line-height:1.65;color:var(--blue);margin:12px 0;}
  pre.code code{font-family:var(--mono);white-space:pre;}
  code{font-family:var(--mono);background:rgba(83,103,252,0.10);color:var(--blue);padding:1px 6px;border-radius:5px;font-size:.82em;}

  /* ===== Badges / pills / endpoints ===== */
  .badge{display:inline-block;padding:3px 9px;font-size:9px;font-weight:800;text-transform:uppercase;
    letter-spacing:.05em;border-radius:8px;border:1px solid;}
  .m-post{background:rgba(37,99,235,0.16);border-color:rgba(37,99,235,0.4);color:#60a5fa;}
  .m-get{background:rgba(5,150,105,0.16);border-color:rgba(16,185,129,0.4);color:#34d399;}
  .m-put{background:rgba(234,88,12,0.16);border-color:rgba(234,88,12,0.45);color:#fb923c;}
  .m-delete{background:rgba(220,38,38,0.16);border-color:rgba(220,38,38,0.45);color:#f87171;}
  .pathpill{font-family:var(--mono);font-size:12px;font-weight:600;background:#111318;border:1px solid var(--border-dark);
    color:#cbd5e1;padding:3px 10px;border-radius:7px;}
  .pill{display:inline-block;font-size:10px;font-weight:700;padding:2px 9px;border-radius:9999px;
    background:rgba(83,103,252,0.12);border:1px solid rgba(83,103,252,0.32);color:var(--accent);}
  .endpoint-line{display:flex;flex-wrap:wrap;align-items:center;gap:8px;margin:14px 0;}

  .endpoint{border-top:1px solid var(--border-dark);padding-top:36px;margin-top:36px;scroll-margin-top:112px;}
  .endpoint-title{font-size:20px;font-weight:700;margin:6px 0;}

  /* first element top spacing cleanup */
  .subsec>*:first-child{margin-top:0;}
  .callout>*:first-child{margin-top:0;}

  /* =====================================================
     Responsive — off-canvas sidebar (mobile / tablet)
     No horizontal scroll from 360px up.
     ===================================================== */
  /* 1023.98px, not 1024px: at exactly 1024 the desktop min-width:1024 rules must
     win outright, otherwise both blocks matched and the off-canvas sidebar
     clobbered the three-column layout on 1024px-wide viewports. */
  @media(max-width:1023.98px){
    .menu-btn{display:inline-flex;}
    /* flex column here too, so the off-canvas drawer pins the note to its
       bottom exactly as the docked sidebar does. */
    .sidebar{display:flex;flex-direction:column;position:fixed;left:0;top:0;height:100%;width:min(288px,84vw);
      transform:translateX(-100%);transition:transform .25s ease;z-index:60;
      padding-top:72px;box-shadow:0 0 40px rgba(0,0,0,0.5);}
    #docsnav.open{transform:none;}
    .main{width:100%;}
    .crumb{padding:0 16px;}
    .content{padding:24px 16px;}
    .sec-hero{margin:0 0 32px;padding-bottom:18px;}
    .sec-hero h1{font-size:28px;}
    .subsec{margin:32px 0 0;}
    .subsec-title{font-size:22px;margin-bottom:16px;}
    .callout{padding:18px 16px;border-radius:16px;}
  }
  @media(max-width:420px){
    .sec-hero h1{font-size:24px;}
    .subsec-title{font-size:20px;}
    .content{padding:20px 12px;}
  }

  /* =====================================================
     Light theme — scoped to html.light
     Toggled by the shared script (adds/removes .light).
     ===================================================== */
  html.light{
    --accent:#5367fc;
    --groww:#5367fc;
    --blue:#5367fc;
    --bg-primary:#ffffff;
    --bg-secondary:#f8fafc;
    --bg-tertiary:#f1f5f9;
    --border-dark:#e2e8f0;
    --border-soft:rgba(83,103,252,0.28);
    --text-primary:#0f172a;
    --text-secondary:#475569;
    --text3:#64748b;
  }
  html.light body{
    color:var(--text-primary);
    background:radial-gradient(1200px 600px at 15% -10%,rgba(83,103,252,0.06),transparent 60%),#ffffff;
  }
  html.light .topbar{background:rgba(255,255,255,0.9);border-bottom:1px solid var(--border-dark);}
  html.light .link-btn{color:#475569;border-color:var(--border-dark);}
  html.light .link-btn:hover{color:#0f172a;border-color:var(--border-soft);}
  html.light .menu-btn{color:#475569;border-color:var(--border-dark);}
  html.light .menu-btn:hover{color:#0f172a;}
  html.light .searchbox,
  html.light .nav-search{background:#ffffff;border-color:var(--border-dark);color:var(--text3);}
  html.light .searchbox .kbd,
  html.light .nav-search .kbd{background:var(--bg-tertiary);border-color:var(--border-dark);color:var(--text3);}

  html.light .sidebar{background:#f8fafc;border-right:1px solid var(--border-dark);}
  html.light .nav-group>.nav-top .gt{color:#0f172a;}
  html.light .nav-sub{border-left-color:var(--border-dark);}
  html.light .nav-sub a{color:#475569;}
  html.light .nav-sub a:hover{color:#0f172a;background:#eef2ff;}
  html.light .nav-foot{border-top-color:var(--border-dark);}

  html.light .crumb{background:rgba(255,255,255,0.9);border-bottom:1px solid var(--border-dark);color:var(--text3);}
  html.light .crumb .cur{color:#0f172a;}

  html.light .sec-hero{border-bottom-color:var(--border-dark);}
  html.light .sec-hero h1{color:#0f172a;}
  html.light .sec-hero p{color:#64748b;}
  html.light .headline{color:#0f172a;border-bottom-color:var(--border-dark);}
  html.light .subsec-title,
  html.light .subhead,
  html.light .itembox strong,html.light .itembox .t,
  html.light .stepttl{color:#0f172a;}

  html.light .itembox{background:#ffffff;border:1px solid var(--border-dark);}
  html.light .note{background:#f8fafc;border-color:var(--border-dark);color:var(--text-secondary);}
  html.light .stepcard{background:#ffffff;border-color:var(--border-dark);}
  html.light .grid2 .check,html.light .grid3 .check{background:#ffffff;border-color:var(--border-dark);}

  /* Callouts -> light blue */
  html.light .callout{background:#dbeafe;border:1px solid #93c5fd;}
  html.light .callout.soft{background:#eff6ff;}
  /* Info / warning notes keep the brand-blue identity on light too. */
  html.light .tip{background:rgba(83,103,252,0.08);border-color:rgba(83,103,252,0.28);color:#3b3fc0;}
  html.light .tip strong{color:#3b3fc0;}
  /* The dark theme takes --text-primary (white) for these; on light that token
     is still white and would disappear against .tip's pale panel and the white
     .itembox, so both revert to the page's light-mode ink. */
  html.light .tip-title{color:#0f172a;}
  html.light .formula-card .formula-line{color:#0f172a;}
  /* Needs the combinator to outrank the line rule above (0,3,1), or the result
     loses its accent on light and reads as a fourth identical line. */
  html.light .formula-card .formula-line+.formula-result{color:#3b3fc0;}
  html.light .formula-card .mini-strong{color:#3b3fc0;}
  html.light .warn{background:rgba(83,103,252,0.08);border-color:rgba(83,103,252,0.28);color:#3b3fc0;}

  /* Tables */
  html.light .tablewrap{border-color:var(--border-dark);}
  html.light table.dt thead tr{background:#f1f5f9;}
  html.light table.dt th{color:#475569;border-bottom-color:var(--border-dark);}
  html.light table.dt td{color:#334155;border-bottom-color:#eef2f7;}
  html.light table.dt tbody tr:hover{background:#f8fafc;}
  html.light table.dt td.mono{color:var(--accent);}

  /* Code */
  html.light pre.code{background:#f8fafc;border-color:var(--border-dark);color:#0f172a;}
  html.light code{background:rgba(83,103,252,0.10);color:#3b3fc0;}
  html.light .pathpill{background:#f1f5f9;border-color:var(--border-dark);color:#334155;}

  /* Method badges — color-coded on light chips */
  html.light .m-post{background:#dbeafe;border-color:#93c5fd;color:#1d4ed8;}
  html.light .m-get{background:#dcfce7;border-color:#86efac;color:#15803d;}
  html.light .m-put{background:#ffedd5;border-color:#fdba74;color:#c2410c;}
  html.light .m-delete{background:#fee2e2;border-color:#fca5a5;color:#b91c1c;}
  html.light .pill{background:#eef2ff;border-color:#c7d2fe;color:#4338ca;}

/* ============ Mobile header ============
   Declared after the min-width:640px logo rule so it wins on tablets, and the
   narrow-phone block below wins over this one — source order matters here
   because all three have equal specificity. */
@media (max-width:768px){
  .topbar{ padding:0 14px; gap:10px; }
}
/* The home navbar drops to its smaller mark at exactly 640px, so the logo
   step-down is pinned to the same boundary and the two headers stay identical
   from 640px up. (This used to fire at 768px, which made the docs mark smaller
   than home's across the whole 640-768 band.) */
@media (max-width:639.98px){
  .brand img{ height:96px; }               /* = the home navbar's sub-640px size */
}
/* Narrow phones: the menu button + logo + two nav links + theme pill together
   overflowed 320px, so tighten every part of the row rather than dropping a
   control (the baseline keeps both links visible at this width). */
@media (max-width:420px){
  .topbar{ padding:0 12px; gap:8px; }
  .brand img{ height:64px; }               /* still stepped down: the full 96px
                                              plus the button, two links and the
                                              pill overflows a 360px row */
  .topbar-right{ gap:8px; }
  .nav-btn{ font-size:11px; letter-spacing:0; }
  .theme-pill{ padding:6px 8px; }
  .menu-btn{ width:34px; height:34px; }
}

/* ============================================================
   Ultrawide scaling — engages only above 1600px, so the layout
   at 1366px / 1440px is unchanged. Without this the 920px doc
   column sits stranded between very large empty gutters on
   1920/2560 monitors (the reported >1366px issue).
   ============================================================ */
@media (min-width:2200px){
  .content{ padding-left:32px; padding-right:32px; }
}

/* ===== Page-by-page docs navigation =====
   Each sidebar group switches to its own section (one visible at a
   time), matching the original app instead of one endless page. */
.nav-group>.nav-top{ cursor:pointer; transition:background .18s ease, color .18s ease; }
.nav-group>.nav-top:hover{ background:rgba(83,103,252,0.10); }
.nav-group>.nav-top.active{ background:rgba(83,103,252,0.16); }
.nav-group>.nav-top.active .gt{ color:#fff; }
.nav-group>.nav-top.active .chev svg{ transform:rotate(90deg); }
/* Only the active group's sub-links are relevant */
.nav-group>.nav-top:not(.active) + .nav-sub{ display:none; }
html.light .nav-group>.nav-top:hover{ background:rgba(83,103,252,0.08); }
html.light .nav-group>.nav-top.active{ background:rgba(83,103,252,0.12); }
html.light .nav-group>.nav-top.active .gt{ color:#0f172a; }

/* ===== Subsection paging (one subsection visible at a time,
   matching the original app's activeSubSecId behaviour) =====
   The active sub-item needs a SOLID fill: a 16% tint was tried first and read
   as "no highlight at all", which was the reported missing background on the
   left-hand nav. */
/* Bright azure fill with white bold text.
   #0d6efd is the lightest blue that still clears 4.5:1 against white at this
   11px bold size — a brighter step (#0a84ff, say) looks the part but drops to
   ~3.6:1 and the label starts to dissolve into the fill. The glow supplies the
   extra brightness instead, without costing legibility.

   Both themes are given the same fill on purpose. The light theme used to get
   a pale #eef0ff tint with blue ink, so the selected row looked like a
   different control depending on the theme. */
.nav-sub a.sub-active{ color:#fff; font-weight:700; background:#0d6efd;
  border-left:2px solid #6ea8fe; margin-left:-1px; border-radius:0 12px 12px 0;
  box-shadow:0 0 12px rgba(13,110,253,0.55); }
.nav-sub a.sub-active:hover{ color:#fff; background:#2b7cfe; }
html.light .nav-sub a.sub-active{ color:#fff; font-weight:700;
  background:#0d6efd; border-left-color:#6ea8fe;
  box-shadow:0 0 12px rgba(13,110,253,0.35); }
html.light .nav-sub a.sub-active:hover{ color:#fff; background:#2b7cfe; }

/* ===== "Next Step" button at the end of each subsection ===== */
.ns-btn{ width:100%; margin-top:24px; padding:20px; display:flex; align-items:flex-start; gap:12px; text-align:left;
  border-radius:16px; border:1px solid rgba(83,103,252,0.2); background:rgba(83,103,252,0.05);
  color:inherit; cursor:pointer; font-family:inherit; transition:background .18s ease, border-color .18s ease; }
.ns-btn:hover{ background:rgba(83,103,252,0.1); border-color:rgba(83,103,252,0.4); }
.ns-icon{ width:16px; height:16px; margin-top:2px; flex-shrink:0; color:#5367fc; }
.ns-text{ display:flex; flex-direction:column; gap:4px; }
/* React: text-sm font-semibold text-groww */
.ns-label{ font-size:14px; font-weight:600; color:#5367fc; }
.ns-desc{ font-size:12px; color:var(--text-secondary); line-height:1.6; }
.ns-desc strong{ color:#fff; font-weight:600; }
html.light .ns-btn{ background:rgba(83,103,252,0.06); border-color:rgba(83,103,252,0.18); }
html.light .ns-btn:hover{ background:rgba(83,103,252,0.1); border-color:rgba(83,103,252,0.35); }
html.light .ns-desc{ color:#64748b; }
html.light .ns-desc strong{ color:#0f172a; }


/* ===== Keyboard focus ring (shared design system) =========================
   Mirrors the existing .checkbox-input:focus-visible pattern so every page
   gives keyboard users the same affordance. :focus-visible only matches
   keyboard / programmatic focus, so pointer users see no visual change. */
:where(a,button,input,select,textarea,summary,[role="button"],[tabindex]):focus-visible{
  outline:2px solid var(--groww,#5367FC);
  outline-offset:2px;
}


/* ============================================================
   FOOTER — ported verbatim from css/home.css so the documentation
   footer is pixel-identical to the rest of the site (and to the
   baseline). Uses the same class names as the markup copied from
   home.html; --w-page is inlined here as 1280px.
   ============================================================ */
footer{ padding:96px 0 48px; border-top:1px solid var(--border-dark); background:#060b1a; position:relative; z-index:10; margin-top:32px; }
footer .fwrap{ max-width:1280px; margin:0 auto; padding:0 24px; display:flex; flex-direction:column; gap:64px; }
.fgrid{ display:grid; grid-template-columns:1fr; gap:32px; }
@media(min-width:1024px){ .fgrid{ grid-template-columns:repeat(12,1fr); gap:24px; } }
.fcol-4{ grid-column:span 1; } .fcol-2{ grid-column:span 1; }
@media(min-width:1024px){ .fcol-4{ grid-column:span 4; } .fcol-2{ grid-column:span 2; } }
footer h4{ font-size:14px; font-weight:600; color:#fff; text-transform:uppercase; letter-spacing:.08em; margin-bottom:16px; }
.socials{ display:flex; flex-wrap:wrap; gap:10px; }
.soc{ width:40px; height:40px; background:#0a0f24; border:1px solid var(--border-dark); border-radius:12px; display:flex; align-items:center; justify-content:center; color:var(--text-secondary); }
.soc svg{ width:20px; height:20px; }
.dlrow{ display:flex; flex-wrap:wrap; gap:12px; margin-top:8px; }
.dl{ display:flex; align-items:center; gap:12px; padding:12px 16px; background:#0a0f24; border:1px solid var(--border-dark); border-radius:12px; width:155px; }
.dl svg{ width:16px; height:16px; color:#a3a3a3; }
.dl .t{ font-size:12px; font-weight:600; color:#fff; }
.fcontact{ display:flex; flex-direction:column; gap:12px; font-size:14px; }
.fcontact a{ display:flex; align-items:center; gap:10px; color:var(--text-secondary); font-weight:600; }
.fcontact a svg{ width:16px; height:16px; color:var(--groww); }
.query-btn{ display:inline-flex; align-items:center; gap:6px; font-size:12px; font-weight:700; color:var(--groww); border:1px solid rgba(83,103,252,0.3); background:rgba(83,103,252,0.05); padding:8px 14px; border-radius:12px; margin-top:4px; }
.query-btn svg{ width:14px; height:14px; }
footer ul.links{ list-style:none; display:flex; flex-direction:column; gap:10px; font-size:14px; color:var(--text-secondary); font-weight:600; }
.fdivider{ width:100%; height:1px; background:rgba(26,37,96,0.6); }
.reg p{ font-size:13px; color:#e5e5e5; line-height:1.7; font-weight:600; }
.reg .u{ color:#fff; font-weight:700; text-decoration:underline; }
.addr-grid{ display:grid; grid-template-columns:1fr; gap:20px; }
@media(min-width:768px){ .addr-grid{ grid-template-columns:repeat(3,1fr); } }
/* Card border follows the shared token (#1a2560 dark / #E2E8F0 light); the
   off-guideline cyan glow is gone. */
.addr{ padding:24px; background:#0a0f24; border:1px solid var(--border-dark); border-radius:16px; display:flex; flex-direction:column; gap:12px; font-size:14px; }
.addr .top{ display:flex; align-items:center; justify-content:space-between; font-size:12px; font-weight:600; color:#fff; text-transform:uppercase; letter-spacing:.08em; border-bottom:1px solid var(--border-dark); padding-bottom:8px; }
.addr .city{ font-size:10px; padding:2px 8px; border-radius:4px; background:rgba(255,255,255,0.1); color:#fff; text-transform:uppercase; letter-spacing:.15em; font-family:var(--font-primary); }
.addr p{ color:#e5e5e5; font-weight:600; line-height:1.6; }
.addr .tel{ color:#d4d4d4; font-weight:600; }
.addr .tel span{ color:#fff; }
.compliance p{ font-size:13px; color:#e5e5e5; line-height:1.7; font-weight:600; margin-bottom:16px; }
.compliance a{ color:var(--groww); font-weight:700; }
.compliance a.w{ color:#fff; text-decoration:underline; }
.copyright{ padding-top:32px; border-top:1px solid var(--border-dark); display:flex; flex-direction:column; gap:16px; justify-content:flex-start; flex-wrap:wrap; font-size:14px; color:#a3a3a3; font-weight:600; }
@media(min-width:640px){ .copyright{ flex-direction:row; align-items:center; } }
@media(max-width:480px){ .dl{ width:100%; } }

/* Footer — light theme */
html.light footer{ background:#f1f5f9; border-top-color:#e2e8f0; }
html.light footer h4,
html.light .addr .top,
html.light .addr .tel span,
html.light .reg .u{ color:#0f172a; }
html.light .soc{ background:#ffffff; border-color:#e2e8f0; color:#475569; }
html.light .dl{ background:#ffffff; border-color:#e2e8f0; }
html.light .dl .t{ color:#0f172a; }
html.light .dl svg{ color:#475569; }
html.light .fdivider{ background:#e2e8f0; }
html.light .reg p{ color:#475569; }
html.light .addr{ background:#ffffff; }
html.light .addr p{ color:#475569; }
html.light .addr .tel{ color:#475569; }
html.light .addr .city{ background:#e2e8f0; color:#0f172a; }
html.light .compliance p{ color:#475569; }
html.light .compliance a.w{ color:#0f172a; }
html.light .copyright{ color:#64748b; }

/* ===== Code block copy control (injected by js/script.js) ===== */
.codewrap{ position:relative; }
.codewrap pre.code{ padding-right:52px; }
.code-copy{ position:absolute; top:20px; right:12px; display:inline-flex; align-items:center; justify-content:center;
  width:30px; height:30px; border-radius:8px; cursor:pointer; padding:0;
  border:1px solid var(--border-dark); background:var(--bg-tertiary); color:var(--text-secondary);
  opacity:0; transition:opacity .18s ease, color .18s ease, border-color .18s ease; }
.codewrap:hover .code-copy,
.code-copy:focus-visible,
/* Hold the control visible while its copied/failed state is showing. Without
   this the confirmation was unseeable in the most ordinary case: click, then
   move the pointer off the block, and the button drops straight back to
   opacity:0 — so a copy that HAD worked looked like a dead button. */
.code-copy.copied{ opacity:1; }
.code-copy:hover{ color:#fff; border-color:var(--border-soft); }
.code-copy svg{ width:14px; height:14px; }
/* Touch devices get no hover, so keep the control permanently visible there. */
@media (hover:none){ .code-copy{ opacity:1; } }
html.light .code-copy{ background:#ffffff; border-color:var(--border-dark); color:#475569; }
html.light .code-copy:hover{ color:#0f172a; }

/* ============================================================
   Light theme — neutral shadows
   Coloured glows (brand blue / cyan / mint) are a dark-mode device only.
   On light they flatten to the shared neutral grey elevation.
   ============================================================ */
html.light .theme-pill:hover{ box-shadow:0 1px 3px rgba(0,0,0,.07), 0 1px 2px -1px rgba(0,0,0,.04); }
html.light .addr{ box-shadow:0 1px 3px rgba(0,0,0,.07), 0 1px 2px -1px rgba(0,0,0,.04); }
html.light .sidebar{ box-shadow:none; }
@media(max-width:1023.98px){
  html.light .sidebar{ box-shadow:0 1px 3px rgba(0,0,0,.07), 0 1px 2px -1px rgba(0,0,0,.04); }
}
/* ============================================================
   Per-table column treatments — matched to the React tables.
   Scoped to the subsection ids that already exist in the markup so no other
   table on the page is affected.
   ============================================================ */

/* 4.1 SEBI Circulars — "Regulatory References"
   React: regulator cell = text-primary/bold, circular number = 10px mono blue.
   The circular numbers are one long unbroken token, which used to push the
   table past the 896px column and force a horizontal scrollbar; letting them
   wrap keeps the table inside its container. */
#sebi_circulars table.dt tbody td:first-child{ color:var(--text-primary); font-weight:700; }
#sebi_circulars table.dt td.mono{ font-size:10px; white-space:normal; overflow-wrap:anywhere; word-break:break-word; }
#sebi_circulars table.dt{ table-layout:auto; width:100%; }

/* 4.2 Algo Classification — "Understanding Algo Types"
   React colours the OPS Limit cell with the brand blue (text-groww /
   text-blue-400, font-semibold); it was rendering as plain body text. */
#classification table.dt tbody td:first-child{ color:var(--text-primary); font-weight:700; }
#classification table.dt tbody td:nth-child(3){ color:var(--accent); font-weight:600; }

/* 4.3 Static IP — "OTR Violation Penalties" is the only two-column table in
   this subsection; its Penalty column takes the brand blue. */
#static_ip table.dt:has(thead th:nth-child(2):last-child) tbody td:first-child{ color:var(--text-primary); font-weight:600; }
#static_ip table.dt:has(thead th:nth-child(2):last-child) tbody td:nth-child(2){ color:var(--accent); font-weight:600; }

/* ============================================================
   "On this page" scroll-spy navigation (bgc-toc-*)
   Injected by js/script.js. Fixed right-hand rail on desktop, hidden below
   the tablet breakpoint. Both active-class spellings are honoured
   (.is-active and .bgc-toc-active) so it works whichever the script emits.
   ============================================================ */
.bgc-toc{
  display:none;
  position:sticky; top:var(--topbar-h); align-self:flex-start;
  width:256px; flex-shrink:0; height:calc(100vh - var(--topbar-h));
  overflow-y:auto; padding:24px;
  border-left:1px solid var(--border-dark); background:var(--bg-primary);
}
@media(min-width:1024px){ .bgc-toc{ display:block; } }
@media(min-width:1280px){ .bgc-toc{ width:288px; } }
/* Below the tablet breakpoint the rail is removed entirely — never collapsed
   to a zero-width column that still eats layout space. */
@media(max-width:1023.98px){ .bgc-toc{ display:none !important; } }

.bgc-toc-title,.bgc-toc-head{
  display:flex; align-items:center; gap:6px; margin-bottom:16px;
  font-size:10px; font-weight:700; text-transform:uppercase; letter-spacing:.08em;
  color:var(--text-secondary); user-select:none;
}
.bgc-toc-title svg,.bgc-toc-head svg{ width:14px; height:14px; flex-shrink:0; }

.bgc-toc-list{
  list-style:none; margin:8px 0 0; padding:0 0 0 16px;
  display:flex; flex-direction:column; gap:14px;
  border-left:1px solid var(--border-dark);
}
.bgc-toc-item{ margin:0; padding:0; list-style:none; }
/* Nested headings indent rather than starting a second rail. */
.bgc-toc-item.is-sub,.bgc-toc-item[data-level="3"]{ padding-left:12px; }

.bgc-toc-link{
  display:block; width:100%; text-align:left; padding:0; margin:0;
  border:0; background:transparent; cursor:pointer;
  font-family:inherit; font-size:12px; font-weight:600; line-height:1.45;
  color:var(--text3);
  transition:color .18s ease, transform .18s ease, border-color .18s ease;
}
.bgc-toc-link:hover{ color:#e5e7eb; transform:translateX(2px); }

/* Active item — brand blue rail + emphasis. The negative margin pulls the
   marker onto the list's own border so the rail stays a single line. */
.bgc-toc-link.is-active,
.bgc-toc-link.bgc-toc-active,
.bgc-toc-item.is-active>.bgc-toc-link,
.bgc-toc-item.bgc-toc-active>.bgc-toc-link{
  color:#fff; font-weight:800; transform:none;
  margin-left:-17px; padding-left:15px;
  border-left:2px solid #5367fc;
}

html.light .bgc-toc{ background:var(--bg-primary); border-left-color:var(--border-dark); }
html.light .bgc-toc-list{ border-left-color:var(--border-dark); }
html.light .bgc-toc-link{ color:#64748b; }
html.light .bgc-toc-link:hover{ color:#0f172a; }
html.light .bgc-toc-link.is-active,
html.light .bgc-toc-link.bgc-toc-active,
html.light .bgc-toc-item.is-active>.bgc-toc-link,
html.light .bgc-toc-item.bgc-toc-active>.bgc-toc-link{ color:#0f172a; border-left-color:#5367fc; }

@media (prefers-reduced-motion: reduce){
  .bgc-toc-link,.bgc-toc-link:hover{ transition:none; transform:none; }
}

  /* ---- Footer: second copyright line right-aligned -----------------
     margin-left:auto on the last line rather than reverting the container to
     justify-content:space-between. For two items the on-screen result is the
     same, but this keeps working once flex-wrap kicks in: if the pair no
     longer fits on one row the second wraps to its own row and stays right,
     instead of space-between collapsing it back to the left.
     Scoped to the row context — the container is flex-direction:column below
     640px, where margin-left:auto would push the line to the right edge on a
     phone. Both stay left when stacked. */
  @media(min-width:640px){
    .copyright p:last-child{ margin-left:auto; text-align:right; }
  }

/* Scrollbars are themed site-wide from js/script.js — see the note there on
   why they cannot live in a stylesheet. Nothing here may set scrollbar-width
   or scrollbar-color: Chrome 121+ discards the webkit rules on any element
   that inherits either one. */