/* KAIT public homepage v2.1 — cinematic one-screen composition.
   Frozen brand tokens (Hi-Fi v1.2); reference: docs/design/homepage/
   public-homepage-reference-v2.png (reproduced as code, never embedded).
   Visual stack: black environment -> mountain silhouettes -> gold glow/haze
   -> floating product shell -> opaque inner cards -> fully opaque text. */

:root{
  --canvas-sunken:#030509;--canvas:#05080C;--surface-1:#11161E;--surface-2:#161C26;
  --border-subtle:#252B35;--border-strong:#313947;
  --text-primary:#F5F5F5;--text-secondary:#A0A6AE;--text-tertiary:#6A727D;
  --profit:#3FBF87;--loss:#F0564E;--live:#3FBF87;
  --brand:#F2C75B;--brand-hi:#F7DC85;--brand-dark:#B98522;
  --f:Inter,-apple-system,BlinkMacSystemFont,Helvetica,Arial,sans-serif;
  --ease:cubic-bezier(.4,0,.2,1);

  /* ---- HERO GEOMETRY CONTRACT ------------------------------------------
     The reading block is placed BENEATH the kite, so it has to know where the
     kite ends. These four numbers were literals repeated across four media
     blocks; as properties there is one source of truth and the anchor cannot
     drift out of step with the header it measures from.

     --kite-ink is measured, not guessed: the PNG's alpha channel puts the
     body at y 0.00-0.45 of its square and the ribbon tail's last real ink at
     y 0.876. Anything below that line is transparent canvas. */
  --hdr:76px;              /* .bar height; the header adds its own 1px rule */
  --hero-pad:22px;         /* .cols padding-block */
  --kite-top:clamp(84px,9vh,140px);
  --kite-size:clamp(132px,11vw,160px);
  --kite-ink:.876;
  --hero-breath:clamp(64px,9.6vh,128px);
  /* breathing room between the header and the product panel. The panel used to
     begin 8px ABOVE the header's bottom edge -- it tucked under the header
     instead of starting below it. */
  --panel-top:clamp(26px,3.2vh,48px);
  /* where Gokait's measured centre crossing sits, per width band -- see the
     rail's own note. The base value serves the widest band. */
  --gk-phase:-.045;
}
*{box-sizing:border-box;margin:0;padding:0}
/* HORIZONTAL CLIPPING WITHOUT A SECOND SCROLL CONTAINER.
   `overflow-x:hidden` is not free: per spec, when one axis is not `visible` the
   other computes from `visible` to `auto`, so this one line silently made BODY
   a scroll container. It had 45px of real scrollable travel of its own (the
   decorative .glow bleeds past the content box), which meant a wheel or swipe
   starting anywhere in the page latched to BODY rather than the viewport --
   body gave its 45px, stopped, and the browser would not chain a latched
   gesture to the viewport until the user lifted and started again. That is the
   "I have to click or retry before scrolling works" bug, and it fired
   everywhere because body is the nearest scrollable ancestor of everything.
   `clip` clips exactly the same way but is NOT a scrollport, so `overflow-y`
   stays `visible` and no nested scroller is created. `hidden` is kept first as
   the fallback for engines predating `clip` (Safari <16). */
html,body{overflow-x:hidden}
html,body{overflow-x:clip}
body{background:#000;color:var(--text-primary);font-family:var(--f);font-size:16px;
  line-height:1.55;-webkit-font-smoothing:antialiased;font-feature-settings:"tnum" 1;
  min-height:100svh;display:flex;flex-direction:column;
  /* Breathing room BELOW the bottom strip, before the scene ends. Padding on
     the flex CONTAINER, not on .strip: the strip is a bordered, backdrop-blurred
     band and growing its own box would have made the band taller instead of
     leaving space after it. .hero keeps flex:1, so a short viewport still puts
     the strip at the bottom with this gap under it. */
  padding-bottom:var(--public-footer-bottom-breathing-room)}
/* ANCHORS CLEAR THE PINNED BAR. Set on the scroll container so every anchor
   jump and every scrollIntoView clears it at once. The homepage carries no
   in-page anchors today -- About and the capital note are overlays, and the
   nav points at other routes -- so this is the rule that keeps the first one
   added correct without anybody remembering the header exists. */
html{scroll-padding-top:calc(var(--hdr) + 18px)}
.num{font-variant-numeric:tabular-nums}
a{color:inherit;text-decoration:none}
button{font-family:var(--f)}
.wrap{max-width:min(1760px,93vw);margin:0 auto;padding:0 30px;width:100%}
.gold-text{background:linear-gradient(180deg,var(--brand-hi),var(--brand) 55%,var(--brand-dark));
  -webkit-background-clip:text;background-clip:text;color:transparent}

/* ============ cinematic environment (all local CSS/SVG, no assets) ============ */
.bg{position:fixed;inset:0;z-index:-1;overflow:hidden;background:#000}
/* photographic mountain environment (public/mountain-environment.webp),
   integrated — never shown raw: darkened, graded, then relit by the
   overlay stack below. Slight overscan absorbs the parallax travel. */
.bg .env{position:absolute;inset:-2.5% -1.5%;
  background:url("mountain-environment.webp") center 66%/cover no-repeat;
  opacity:.8;filter:brightness(.84) saturate(.94) contrast(1.05);
  transform:translateX(var(--bx,0px)) scale(1.03);
  transition:transform .9s cubic-bezier(.22,1,.36,1)}
/* dark overlay: keeps the left copy zone and header ink-black, grades the
   scene into the page instead of letting it read as a wallpaper */
.bg .shade{position:absolute;inset:0;background:
  radial-gradient(ellipse 30% 40% at 73% 47%,rgba(0,0,0,.42),transparent 72%),
  linear-gradient(90deg,rgba(0,0,0,.84) 0%,rgba(0,0,0,.46) 28%,rgba(0,0,0,.08) 54%,rgba(0,0,0,.18) 100%),
  linear-gradient(180deg,rgba(0,0,0,.8) 0%,rgba(0,0,0,.2) 24%,rgba(0,0,0,.02) 50%,rgba(0,0,0,.44) 100%)}
/* golden radial glow: reinforces the picture's own sun behind the shell */
.bg .sky{position:absolute;inset:0;background:
  radial-gradient(ellipse 46% 56% at 72% 44%,rgba(242,199,91,.10),transparent 66%),
  radial-gradient(ellipse 40% 30% at 8% 102%,rgba(185,133,34,.07),transparent 72%)}
/* haze: warm fog sitting on the ridge line, denser on the product side */
.bg .haze{position:absolute;left:0;right:0;bottom:4%;height:42%;filter:blur(46px);
  background:radial-gradient(ellipse 44% 62% at 72% 62%,rgba(242,199,91,.15),transparent 68%),
             radial-gradient(ellipse 58% 46% at 26% 92%,rgba(200,150,60,.07),transparent 70%);
  animation:breathe 9s ease-in-out infinite}
/* ground glow / reflection under the shell */
.bg .ground{position:absolute;left:40%;right:-8%;bottom:0;height:22%;filter:blur(34px);
  background:radial-gradient(ellipse 62% 92% at 55% 100%,rgba(242,199,91,.20),transparent 72%)}
.bg .vignette{position:absolute;inset:0;background:
  radial-gradient(ellipse 82% 78% at 50% 44%,transparent 56%,rgba(0,0,0,.62) 100%)}
.bg .grain{position:absolute;inset:0;opacity:.05;pointer-events:none;
  background-image:url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='140' height='140'><filter id='n'><feTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='2'/></filter><rect width='140' height='140' filter='url(%23n)' opacity='0.55'/></svg>")}
/* sparse gold particles: slow rise + twinkle */
.bg .pt{position:absolute;border-radius:50%;background:var(--brand);opacity:0;
  animation:drift var(--pt,16s) ease-in-out infinite;animation-delay:var(--pd,0s)}
@keyframes drift{
  0%{transform:translateY(0);opacity:0}
  20%{opacity:var(--po,.5)}
  80%{opacity:calc(var(--po,.5)*.4)}
  100%{transform:translateY(-46px);opacity:0}}

/* ---------- animated KAIT kite (official PNG, decorative sky layer, behind content) ---------- */
/* The PNG is one object on a transparent 1254x1254 canvas, but the artwork is
   NOT centred: the kite BODY lives top-right (canvas x .50-.98, y .05-.44,
   visual centre ~74% 23%) and its ribbon TAIL sweeps down-left to the lower-left
   corner. So we anchor the composition by where the BODY lands (not the square):
   top/left place the body in the open sky below the header and left of the
   dashboard; the tail then flows naturally down-left into the darker sky. */
.kite{position:absolute;top:var(--kite-top);left:21%;z-index:1;pointer-events:none;
  width:var(--kite-size);   /* one source of truth: the reading block below is
     anchored to this same geometry, so the two can never drift apart. .bg is
     fixed and full-viewport, so the 9vh inside --kite-top resolves exactly as
     the 9% this rule used to carry -- verified identical at seven viewports. */
  transform:translate3d(var(--kx,0),var(--ky,0),0);   /* .kite = positioning + optional desktop parallax */
  transition:transform .5s var(--ease);will-change:transform}
.kite img{width:100%;height:auto;display:block;
  filter:drop-shadow(0 9px 13px rgba(0,0,0,.4))}       /* subtle grounding shadow, no glow — the art has its own light */
.kite-in{animation:kaitFloat 16s cubic-bezier(.45,.05,.55,.95) infinite;
  transform-origin:74% 23%;will-change:transform}      /* .kite-in = flight; pivot at the BODY so the tail trails, never spins */
/* slow, irregular wind: gentle drift + subtle tilt, no bounce/spin/pulse */
@keyframes kaitFloat{
  0%{transform:translate3d(0,0,0) rotate(-1.2deg) scale(1)}
  22%{transform:translate3d(7px,-6px,0) rotate(.7deg) scale(1.004)}
  45%{transform:translate3d(12px,4px,0) rotate(2.2deg) scale(1.007)}
  68%{transform:translate3d(4px,9px,0) rotate(.2deg) scale(1.003)}
  86%{transform:translate3d(-6px,3px,0) rotate(-1.7deg) scale(.999)}
  100%{transform:translate3d(0,0,0) rotate(-1.2deg) scale(1)}}
@keyframes kaitFloatSm{
  0%{transform:translate3d(0,0,0) rotate(-1deg)}
  40%{transform:translate3d(6px,-4px,0) rotate(1.5deg)}
  75%{transform:translate3d(-4px,4px,0) rotate(-1deg)}
  100%{transform:translate3d(0,0,0) rotate(-1deg)}}

/* ---------- header (page chrome ONLY — scoped so card-level <header>
   elements inherit their card surface instead of a dark strip) ---------- */
/* PINNED. `position:sticky` keeps the bar in normal flow -- it still occupies
   its own --hdr row above the hero, so nothing below moves, nothing needs a
   compensating offset, and there is no shift at the instant it starts
   sticking. z-index:20 was already declared here and was inert while the
   element was static; it is now the real layer, above the scene (-1), the
   content column (1) and the strip (2), and below the overlays (50) so a
   dialog still covers the bar. Backdrop blur and scrim are UNCHANGED: at
   scroll 0 the bar is pixel-for-pixel the accepted header. */
body>header{position:sticky;top:0;
  border-bottom:1px solid rgba(37,43,53,.5);background:rgba(0,0,0,.42);
  backdrop-filter:blur(10px);z-index:20}
.bar{display:flex;align-items:center;height:var(--hdr);gap:40px}
.brandblk{display:flex;align-items:center;gap:12px}
.brandblk .mark{width:34px;height:34px}
/* ONE word, so the wide two-word tracking is gone: at .28em "Gokait"
   read as spaced-out capitals and crowded the nav on phones. */
.brandblk .word{display:block;font-size:24px;font-weight:700;letter-spacing:.005em;line-height:1;white-space:nowrap}
.brandblk .tag{display:block;font-size:10px;letter-spacing:.06em;color:var(--brand-dark);margin-top:3px}
nav{display:flex;gap:10px}
nav .navlink{display:inline-flex;align-items:center;color:var(--text-secondary);
  font-size:14.5px;padding:8px 12px;border-radius:8px;
  transition:color .15s var(--ease),background .15s var(--ease)}
nav .navlink:hover{color:var(--text-primary);background:rgba(242,199,91,.05)}
/* footer secondary link row */
.flinks{display:flex;flex-wrap:wrap;gap:6px 18px;align-items:center}
/* Tap target (2026-08-26). All three controls measured 19px tall on every
   breakpoint -- under the 24x24 CSS-px minimum of WCAG 2.5.8 (Target Size,
   AA). The TEXT is deliberately unchanged at 12px: only the interactive box
   grows, via inline-flex + min-height, so the footer keeps its exact visual
   weight and the row gains 5px once rather than being restyled. One shared
   rule, no per-link exception, no inline style. */
.flinks a,.flinks button{font-size:12px;color:var(--text-tertiary);
  background:none;border:0;padding:0;cursor:pointer;font:inherit;font-size:12px;
  display:inline-flex;align-items:center;min-height:24px}
.flinks a:hover,.flinks button:hover{color:var(--brand)}
/* Same focus treatment the rest of the public site already uses. */
.flinks a:focus-visible,.flinks button:focus-visible{
  outline:1px solid var(--brand-dark);outline-offset:2px}
nav button{background:none;border:0;color:var(--text-secondary);font-size:14.5px;cursor:pointer;
  padding:8px 15px;border-radius:8px;transition:color .25s var(--ease),background .25s var(--ease)}
nav button:hover{color:var(--text-primary);background:rgba(242,199,91,.05)}
nav button:focus-visible{outline:1px solid var(--brand-dark);outline-offset:2px}

/* mobile hamburger — hidden on desktop, shown <=760px; the 3 bars morph to an X */
.navtoggle{display:none;flex-direction:column;justify-content:center;gap:5px;
  width:44px;height:44px;padding:11px;margin-left:auto;border:0;border-radius:9px;
  background:none;cursor:pointer;transition:background .2s var(--ease)}
.navtoggle span{display:block;width:22px;height:2px;border-radius:2px;background:var(--brand);
  transition:transform .28s var(--ease),opacity .2s var(--ease)}
.navtoggle:hover{background:rgba(242,199,91,.07)}
.navtoggle:focus-visible{outline:1px solid var(--brand-dark);outline-offset:2px}
.navtoggle.open span:nth-child(1){transform:translateY(7px) rotate(45deg)}
.navtoggle.open span:nth-child(2){opacity:0}
.navtoggle.open span:nth-child(3){transform:translateY(-7px) rotate(-45deg)}

/* ---- CANONICAL HEADER BREAKPOINT -----------------------------------------
   860px, the same width the shared shell (site.css) collapses at, so the bar
   is the SAME object on the homepage and on every inner page. These rules used
   to live in this file's 760 block, which is why 761-860 showed a full nav row
   here and a hamburger everywhere else. */
@media (max-width:860px){
  :root{--hdr:64px}
  .bar{gap:14px;position:relative}
  .navtoggle{display:flex}
  nav{display:none;position:absolute;top:100%;left:0;right:0;flex-direction:column;gap:0;
    padding:8px;background:rgba(6,8,12,.97);backdrop-filter:blur(16px);
    border-top:1px solid var(--border-subtle);border-bottom:1px solid var(--border-subtle);
    box-shadow:0 26px 50px rgba(0,0,0,.62)}
  nav.open{display:flex}
  nav .navlink,nav button{width:100%;text-align:start;padding:14px 18px;font-size:15.5px;border-radius:10px}
  nav>*:not(:last-child){border-bottom:1px solid rgba(242,199,91,.15)}   /* gold separator */
  .brandblk .tag{display:none}
}

/* buttons */
.btn-gold{display:inline-flex;align-items:center;gap:9px;
  background:linear-gradient(180deg,var(--brand-hi),var(--brand) 60%,var(--brand-dark));
  color:#161302;border:0;border-radius:10px;padding:14px 28px;font-size:15px;font-weight:700;
  cursor:pointer;box-shadow:0 8px 26px rgba(242,199,91,.18);
  transition:transform .3s var(--ease),box-shadow .3s var(--ease),filter .3s var(--ease)}
.btn-gold:hover{transform:translateY(-1px);filter:brightness(1.07);
  box-shadow:0 12px 34px rgba(242,199,91,.3)}
.btn-gold svg{width:16px;height:16px;stroke:#161302;fill:none;stroke-width:2.2;
  stroke-linecap:round;stroke-linejoin:round}
.btn-outline{display:inline-flex;align-items:center;gap:9px;border:1px solid rgba(242,199,91,.5);
  color:var(--brand);border-radius:10px;padding:13px 28px;font-size:15px;font-weight:600;
  background:rgba(242,199,91,.05);transition:background .3s var(--ease),transform .3s var(--ease)}
.btn-outline:hover{background:rgba(242,199,91,.13);transform:translateY(-1px)}
.btn-outline svg{width:15px;height:15px;stroke:var(--brand);fill:none;stroke-width:1.9;
  stroke-linecap:round;stroke-linejoin:round}

/* ---------- hero: the one screen ---------- */
/* `overflow:clip` is what makes the strip the real END OF THE PAGE.
   .glow is inset -18% on .stage, so it hangs 189px BELOW the last content --
   measured at 1280x720: content ended at 1305, the document scrolled to 1447.
   That 142px was not a margin anyone chose, it was the transparent tail of a
   blurred decoration, and it read on screen as a black dead zone after the
   footer. Clipping it here removes it from the document's scrollable overflow
   (`clip`, not `hidden`: no scroll container is created, so the pinned header
   above still resolves its sticky against the viewport). The GLOW ITSELF is
   untouched -- its radial gradient goes transparent at 74% of a 480px
   closest-side radius, i.e. ~355px + blur from the panel's centre, which lands
   well inside this box; only the invisible remainder is cut. `overflow-clip-margin`
   is deliberately NOT used: measured here, it puts the scrollable overflow
   straight back (1447 again) while doing nothing for the visible art. */
.hero{flex:1;display:flex;align-items:center;min-height:0;overflow:clip}
.cols{display:grid;grid-template-columns:.72fr 1.28fr;gap:52px;align-items:center;
  padding-top:var(--hero-pad);padding-bottom:var(--hero-pad)}
/* ---- THE READING BLOCK IS TUCKED UNDER THE ARTWORK ----------------------
   Not centred. The hero's height comes from the product panel, so centring put
   the copy 180-245px below the kite's ink and let its top slide 39px between
   English and Arabic. Anchoring it below the measured ink line fixes both: the
   block reads as one group deliberately placed under the kite, and because the
   TOP is now fixed, a language with shorter copy changes only where the block
   ends -- never where it begins.

   max(0px, ...) is the guard. On a short or narrow viewport the kite sits high
   and the arithmetic can go negative; the block then simply starts at the top
   of its grid area rather than being pulled above it.

   Below 761px .cols is a single column, the panel is underneath rather than
   beside, and there is no artwork-and-copy relationship to preserve -- so the
   anchor does not apply there and the natural stack order is left alone. */
@media (min-width:761px){
  .pitch{align-self:start;
    margin-top:max(0px,calc(var(--kite-top) + var(--kite-size) * var(--kite-ink)
                            + var(--hero-breath) - var(--hdr) - var(--hero-pad)))}
}

/* THE READING COLUMN IS NOT A SCROLL ANCHOR.
   Its height is language-dependent -- the same three sentences measure 495px in
   English and 418px in Arabic -- and the columns are centred, so when the
   browser chose an anchor inside it and scrolled to hold that anchor still,
   everything ELSE moved instead: measured on live production, switching to
   Arabic slid the whole product panel, the technology rail, the lot ladder and
   the footer up by 39px in the viewport. Excluding this column from anchor
   selection leaves the scroll position alone, so the panel stays exactly where
   the reader left it and only the copy reflows -- which is the one thing that
   SHOULD change when you change language. */
.pitch{overflow-anchor:none}

.pitch .eyebrow{display:flex;align-items:center;gap:10px;font-size:12.5px;letter-spacing:.22em;
  color:var(--brand);font-weight:600}
.eyebrow .dot{width:18px;height:18px;border:1px solid var(--brand-dark);border-radius:50%;
  display:inline-flex;align-items:center;justify-content:center;flex:none}
.eyebrow .dot i{width:6px;height:6px;background:var(--brand);border-radius:50%}
h1{margin-top:24px;font-size:clamp(42px,4.8vw,72px);font-weight:700;line-height:1.12;
  letter-spacing:-.015em}
h1 span{display:block}
h1 .gold-text{position:relative;
  background:linear-gradient(180deg,#FBE9AE,var(--brand-hi) 30%,var(--brand) 62%,var(--brand-dark));
  -webkit-background-clip:text;background-clip:text;
  filter:drop-shadow(0 0 26px rgba(242,199,91,.28))}
.sub{margin-top:22px;max-width:475px;color:rgba(224,228,233,.88);font-size:17px;
  line-height:1.65}
.cta{display:flex;gap:16px;margin-top:34px;flex-wrap:wrap}
.points{display:flex;gap:28px;margin-top:32px;list-style:none;flex-wrap:wrap}
.points li{display:flex;align-items:center;gap:9px;font-size:13.5px;color:var(--text-secondary)}
.points svg{width:17px;height:17px;stroke:var(--brand);fill:none;stroke-width:1.8;
  stroke-linecap:round;stroke-linejoin:round;flex:none}

/* ---------- floating product shell ---------- */
/* The panel is placed by LAYOUT vertically and NUDGED only horizontally. The
   -24px it used to carry was a visual lift that pulled its top edge above the
   header's bottom edge, and it could not simply be reversed: there are only
   40-46px between the panel's bottom and the footer, so a purely visual move
   down would have collided. As a margin the row grows with it instead. */
.stage{position:relative;perspective:1700px;min-width:0;
  margin-top:var(--panel-top);transform:translate(18px,0)}
.glow{position:absolute;inset:-18% -14%;z-index:-1;border-radius:50%;pointer-events:none;
  background:radial-gradient(closest-side,rgba(242,199,91,.30),transparent 74%);
  filter:blur(50px);animation:breathe 9s ease-in-out infinite}
/* ground reflection under the shell */
.stage::after{content:"";position:absolute;left:4%;right:4%;bottom:-42px;height:66px;
  pointer-events:none;
  background:radial-gradient(ellipse 58% 100% at 50% 0%,rgba(242,199,91,.24),transparent 72%);
  filter:blur(16px)}
/* FLAT panel. The Live-Price card is now a live INTERACTIVE canvas: a scaled +
   3D-rotated ancestor makes the browser's pointer->canvas mapping non-1:1, so
   the crosshair drifts off the real mouse (worse near the edges, and it moved
   with the old mouse-parallax). A professional trading chart must be face-on.
   Decorative parallax still rides the background + kite, never this wrapper. */
.tiltwrap{transform:none}
.window{position:relative;display:flex;border-radius:18px;min-height:712px;
  /* faint interior gold reflection (top-right) over the graphite base — the panel
     reads as lit by the surrounding gold environment, not a neon border */
  background:
    radial-gradient(130% 78% at 80% -8%,rgba(242,199,91,.06),transparent 46%),
    linear-gradient(165deg,rgba(13,17,26,.84),rgba(8,11,17,.90));
  backdrop-filter:blur(10px);
  border:1px solid rgba(242,199,91,.18);
  box-shadow:0 70px 140px rgba(0,0,0,.78),0 30px 60px rgba(0,0,0,.6),
             inset 0 0 0 1px rgba(4,6,10,.85),
             inset 0 1px 0 rgba(250,228,150,.06),   /* warm top-edge highlight */
             0 0 110px rgba(242,199,91,.12);         /* soft gold ambient, diffuse */
  animation:float 8s ease-in-out infinite}
/* gold rim: brightest along top + right, like the reference lighting */
.window::before{content:"";position:absolute;inset:-1px;border-radius:19px;padding:2px;
  background:linear-gradient(205deg,rgba(250,228,150,.95),rgba(242,199,91,.30) 28%,
    rgba(242,199,91,.08) 54%,rgba(185,133,34,.50) 100%);
  -webkit-mask:linear-gradient(#000 0 0) content-box,linear-gradient(#000 0 0);
  -webkit-mask-composite:xor;mask-composite:exclude;pointer-events:none}
/* (the travelling border sweep was removed: a premium/institutional panel is lit
   by ambient gold, not a scanning light — see the static rim + reflection above) */

.wmain{flex:1;min-width:0;display:flex;flex-direction:column}
/* THE HEADER IS THREE COLUMNS, NOT A FLEX ROW WITH A GAP IN THE MIDDLE.
   The brand line has to sit on the panel's TRUE centre line, not merely in the
   space left over between XAUUSD and the market state -- a status that changes
   from PAUSED to MARKET CLOSED is 60px wider, and in a flex row that width
   would slide the phrase sideways on a live page every time the market opened.
   Two equal `1fr` side tracks put the `auto` centre track on the exact centre
   by construction, so neither side can ever move it, whatever it says.
   The side floors are `min-content`, NOT `max-content`, and the difference is
   a real one. Under ~340px of header -- a 320px phone -- XAUUSD plus MARKET
   CLOSED genuinely do not fit on one line at any centring. A `max-content`
   floor makes the tracks refuse to shrink and pushes the market state clean
   outside the panel's gold rim; `min-content` lets it wrap onto a second line
   inside the panel, which is exactly what the header did before this change.
   Neither floor binds at any width the phrase is actually shown at, so the
   centring above is unaffected either way -- this is purely the behaviour at
   the edge, and it stays the behaviour that was already there.
   All three cells are pinned explicitly: once the brand line moves to row two,
   auto-placement would otherwise pull the market state into the vacated middle
   column and un-anchor it from the right edge. */
.topbar{height:auto;min-height:50px;flex:none;   /* header breathing:
  a FLOOR, not a fixed height. A single-row header measures under 50px so
  this holds it at exactly 50px and desktop is unchanged; a header that has
  genuinely stacked onto two rows is allowed to take the room it needs
  instead of overlapping inside a box that cannot hold it. */

  display:grid;align-items:center;column-gap:16px;padding:0 20px;
  grid-template-columns:minmax(min-content,1fr) minmax(0,auto) minmax(min-content,1fr);
  border-bottom:1px solid var(--border-subtle);
  /* the header is asked about its OWN width below, never the viewport's: the
     same header is ~780px wide on a desktop and ~290px inside the stacked
     mobile panel, and it is the panel that it has to fit into. */
  container-type:inline-size;container-name:topbar}
.tsym{grid-area:1/1;justify-self:start;font-size:12.5px;letter-spacing:.14em;font-weight:600;
  display:inline-flex;align-items:center;gap:9px;
  /* gold to match the logo mark + the Gokait wordmark */
  background:linear-gradient(180deg,var(--brand-hi),var(--brand) 55%,var(--brand-dark));
  -webkit-background-clip:text;background-clip:text;color:transparent}
.tsym .tlogo{width:20px;height:20px;flex:none}
.tlive{grid-area:1/3;justify-self:end;font-size:10.5px;letter-spacing:.16em;font-weight:700;color:var(--text-tertiary);
  display:flex;align-items:center;gap:7px}
/* MARKET PRESENCE -- the state the badge has always CARRIED but never SHOWED.
   setLiveBadge() has set .live / .closed from the canonical feed status since
   long before this rule existed, and the <i> dot has always been in the markup;
   there was simply no declaration for either, so the dot painted at zero size
   and the text kept the grey .tlive base colour. Nothing here computes market
   hours: this is the presentation half of a state the payload already decides.

   OPEN   green text + green dot, dot breathing on opacity alone (the existing
          `breathe` keyframes -- no scale, no halo, no reflow; the soft shadow
          rides the same opacity, and the TEXT never pulses).
   CLOSED red text + red dot, fully static: no animation, no glow.

   COLOUR IS NOT THE ONLY SIGNAL -- the badge always spells out MARKET OPEN or
   MARKET CLOSED -- and colour is deliberately declared OUTSIDE the animation,
   so reduced motion drops the pulse and never the state. */
.tlive i{width:6px;height:6px;border-radius:50%;background:currentColor;
  flex:none;opacity:1}
.tlive.live{color:var(--profit)}
.tlive.live i{box-shadow:0 0 6px rgba(63,191,135,.55);
  animation:breathe 2.6s var(--ease) infinite}
.tlive.closed{color:var(--loss)}
.tlive.closed i{box-shadow:none;animation:none}
/* Reduced motion stops the BREATHING, never the STATE. The page-wide reduce
   block zeroes every animation with !important, so this is here to say the
   quiet part out loud: colour and dot survive, only the movement goes. */
@media (prefers-reduced-motion:reduce){
  .tlive.live{color:var(--profit)}
  .tlive.live i{animation:none;opacity:1}
  .tlive.closed{color:var(--loss)}
  .tlive.closed i{animation:none;opacity:1}
}

/* the centre brand line. One weight lighter and one tone below the market
   state, so it reads as a signature rather than a third metric arguing with
   XAUUSD for the eye. No box, no background, no animation -- the restraint is
   the premium part. The wordmark takes the same tone as the sentence: a second
   gold on this row would argue with XAUUSD, which is the one thing the line is
   written not to do.

   IT WRAPS, DELIBERATELY. The line carries a sentence now, and `nowrap` was
   not merely a clipping risk here -- it was a LAYOUT risk. Once the line takes
   its own row spanning 1/-1, a nowrap item contributes its ENTIRE length as
   min-content to the two `minmax(min-content,1fr)` side columns, which inflated
   the grid past the panel and carried the line out of the window on every
   locale longer than English. Wrapping makes its min-content the longest WORD
   instead, so the columns collapse back to XAUUSD and the market state and the
   line stays inside the panel at every width and in all seven locales.
   Overflow stays as the backstop it always was; it is no longer reached. */
.tbrand{grid-area:1/2;justify-self:center;min-width:0;max-width:100%;
  font-size:11px;font-weight:400;letter-spacing:.055em;line-height:1.2;
  color:var(--text-tertiary);text-align:center;
  white-space:normal;overflow:hidden;text-overflow:ellipsis}
/* the heart is the one thing on this line allowed any colour. It is drawn from
   the platform's colour-emoji font -- never from the gold gradient the panel
   clips for XAUUSD -- and carries an explicit red so a system with no emoji
   font shows a red heart rather than a grey outline. The nudge is optical: an
   emoji glyph sits fractionally low against Inter's x-height. */
.tbrand-heart{font-family:"Apple Color Emoji","Segoe UI Emoji","Noto Color Emoji",
  "Twemoji Mozilla","EmojiOne Color",sans-serif;
  font-size:.94em;letter-spacing:normal;color:#E5484D;vertical-align:-.04em}

/* ---- THE BRAND SIGNATURE -----------------------------------------------
   The line carries the only piece of pure brand copy on the page and it was
   set in the same tertiary grey as a caption. This gives it presence without
   giving it volume: the WORDMARK becomes the living element, the sentence
   becomes readable, and the market row keeps the header.

   The hierarchy is held by SIZE and WEIGHT, not by brightness. XAUUSD is
   12.5px with a logo beside it; the market state is 700 in profit/loss colour;
   the wordmark is 600 at 10.5px and the sentence is 400. It is still the third
   thing you read, which is the point.

   Keyframes live beside the rule that uses them, as drift/kaitFloat do for the
   background and trust-scroll does for the rail. */
.tb-mark{
  display:inline-block;              /* transformable, and it never reflows */
  position:relative;
  font-weight:600;letter-spacing:.04em;
  color:var(--brand);                /* the canonical gold, #F2C75B */
  transform-origin:50% 60%;          /* optical centre of the glyphs */
  /* a breath of gold, not a halo. STATIC -- it is never animated, so it costs
     no paint per frame and can never bloom over XAUUSD. */
  text-shadow:0 0 5px rgba(242,199,91,.20)}
/* THE SWEEP IS CLIPPED TO THE GLYPHS, NOT TO A BOX. A bar travelling behind
   the word would be exactly the glowing bar this is not allowed to be;
   clipping the highlight to the letterforms is what makes it read as light
   crossing polished metal instead.

   Two layers: the moving highlight over flat gold. With a 300%-wide highlight
   layer, `background-position:p` puts the band centre at 1.5W - 2Wp, so p=90%
   parks it clear of the left edge and p=10% carries it clear of the right --
   both invisible, which is why the loop can jump between them with nothing to
   see, and why a browser with animations off simply shows unbroken gold.

   Guarded: without background-clip:text, `color:transparent` would erase the
   wordmark, so the plain gold above stands on its own. */
@supports ((-webkit-background-clip:text) or (background-clip:text)){
  .tb-mark{
    background-image:
      linear-gradient(105deg,transparent 44%,rgba(255,247,224,.92) 50%,transparent 56%),
      linear-gradient(var(--brand),var(--brand));
    background-size:300% 100%,100% 100%;
    background-position:90% 0,0 0;
    background-repeat:no-repeat;
    -webkit-background-clip:text;background-clip:text;
    color:transparent;
    animation:kaitSigSweep 9s linear infinite,
              kaitSigBreath 9s ease-in-out infinite}
}
/* THE ACTIVE PHASE IS 1.35s OF EVERY 9s -- 15%. The other 7.65s are deliberate
   dead air: a signature that moved continuously would be a distraction sitting
   an inch from a live price. Only transform, opacity and background-position
   are touched, so the sequence never lays out and never reflows the header. */
@keyframes kaitSigSweep{
  0%{background-position:90% 0,0 0}
  15%{background-position:10% 0,0 0}
  100%{background-position:10% 0,0 0}}
@keyframes kaitSigWarm{
  0%{color:var(--sig-warm)}
  6%{color:#FBF3DC}
  13%{color:#FBF3DC}
  20%{color:var(--sig-warm)}
  100%{color:var(--sig-warm)}}
@keyframes kaitSigBreath{
  0%{transform:scale(1)}
  5%{transform:scale(1.02)}
  10%{transform:scale(1.02)}
  15%{transform:scale(1)}
  100%{transform:scale(1)}}
/* the sentence. Champagne rather than white: 88% of --text-primary's channel
   value, warmed 12% toward the brand gold, so it reads as the wordmark's own
   family instead of a neutral caption that happens to sit beside it. Well
   clear of --text-tertiary #6A727D, and still below --text-primary #F5F5F5 so
   the market row outranks it. The dash keeps the old tertiary tone -- it is a
   separator, not content. */
.tbrand{--sig-ink:#D8DCE2;--sig-warm:#F1E4BC}
.tb-line{color:var(--sig-ink)}
/* the emphasis. Warmer and a shade brighter than the sentence, but well short
   of the wordmark's saturated gold, so the eye lands on Gokait first and on the
   promise second. 500 rather than 600 for the same reason: enough to separate
   it from the sentence, not enough to rival the brand. */
.tb-em{font-style:normal;font-weight:500;color:var(--sig-warm);
  animation:kaitSigWarm 9s ease-in-out infinite}
.tb-dash{color:var(--text-tertiary)}
/* REDUCED MOTION DROPS THE MOVEMENT AND KEEPS THE LOOK. The global sweep lower
   in this file already stops every animation on the page; what matters here is
   that the state it stops ON is the premium one, so it is asserted rather than
   assumed -- gold wordmark, champagne sentence, highlight parked off the
   glyphs, no hairline, no scale. Reduced motion must not return this line to
   grey, which is the whole reason these four declarations are written out. */
@media (prefers-reduced-motion:reduce){
  .tb-mark{background-position:90% 0,0 0;transform:none}
  .tb-line{color:var(--sig-ink)}
  .tb-em{color:var(--sig-warm);animation:none}
  .tb-dash{color:var(--text-tertiary)}
}

/* THE TWO STEP-DOWNS ARE WRITTEN ON THE CHILDREN, DELIBERATELY.
   An element cannot answer its own @container query -- .topbar declares the
   container, so only its descendants may ask about it. That is a constraint
   worth designing to rather than around: expressing both step-downs purely as
   child placement means the header keeps ONE grid definition and ONE height at
   every width, so there is no second layout to drift out of sync and no header
   that changes size as the panel narrows.

   STEP 1 -- the panel is narrower than a laptop's. The brand line gives back a
   little size and tracking; XAUUSD and the market state are not touched. */
@container topbar (max-width:679px){
  .tbrand{font-size:9.5px;letter-spacing:.04em}
}
/* STEP 1a -- the laptop band. `container-type:inline-size` queries the CONTENT
   box, so a 1280 viewport gives the panel 648px of content and lands inside
   STEP 1: without this, every 1024-1400 desktop would keep the phone's 9.5px
   while only 1440+ received the readable size, which is the opposite of what
   the signature needed. Measured at 1280 the widest locale (German) sets in
   389px against 648px of content, and at 1024 in 389px against 431px -- both
   still one line, both still clear of XAUUSD and the market state. Below 420px
   of content the phone size stands, untouched. */
@container topbar (min-width:420px) and (max-width:679px){
  .tbrand{font-size:10.5px;letter-spacing:.05em}
}
/* STEP 2 -- below this the three cannot share a line without crowding, so the
   brand line takes its own row underneath and spans the full width, where
   `justify-self:center` still puts it on the panel's true centre -- now with
   the whole width to be centred in. XAUUSD and the market state keep row one
   and their hierarchy; the header stays exactly 50px, the two rows sharing it. */
@container topbar (max-width:499px){
  .tbrand{grid-column:1/-1;grid-row:2;justify-self:center;
    /* THE BREATHING. Written on the child because .topbar declares the
       container and cannot answer its own query -- the same constraint the two
       step-downs above are designed around. The brand line separates itself
       from row one and from the divider underneath, and the header (now a
       floor, not a fixed height) grows to hold both rows instead of letting
       them overlap. Centred text may wrap to a second line here and still
       clears everything. */
    margin-top:8px;margin-bottom:10px;line-height:1.45;text-align:center}
  /* row one lifts off the top edge by the same amount, so the pair reads as a
     composed two-row header rather than content pushed against the border */
  .tsym,.tlive{margin-top:10px}
}
/* STEP 3 -- on the narrowest panels the market state is the last thing still
   competing for room, and at .16em it wrapped onto a second line. Tracking is
   what gives way, not size or wording: the label stays MARKET OPEN / MARKET
   CLOSED at 10.5px and simply sets tighter, which keeps it on one line without
   turning it into a badge or shrinking it below the panel's smallest type. */
@container topbar (max-width:300px){
  .tlive{letter-spacing:.06em;gap:5px}
}
/* a browser without container queries (pre-2023) sees neither step, so the
   stacked row comes from the viewport instead. Coarser -- it cannot know the
   panel's width -- but it is the same rule, so it cannot collide either. */
@supports not (container-type:inline-size){
  @media (max-width:1180px){
    .tbrand{font-size:9.5px;letter-spacing:.04em;
      grid-column:1/-1;grid-row:2;justify-self:center;
      margin-top:8px;margin-bottom:10px;line-height:1.45;text-align:center}
    .tsym,.tlive{margin-top:10px}
  }
}

/* inner dashboard: cool graphite-navy, more opaque than the shell */
/* THE QUERY CONTAINER for both selectors. Neither control can ask about
   its own width, and neither should ask about the viewport's: this box is
   384px wide at a 480px viewport but 340px at 768px, because the hero goes
   two-column at tablet. The space the controls actually have is this. */
.cards{container-type:inline-size;container-name:cards;
  flex:1;display:grid;grid-template-columns:1fr 1fr;gap:14px;padding:18px;
  /* Two info cards were removed: the panel is now Hybrid + KLDXAU on top and a
     LARGE real chart below. Row 1 (fixed) holds the two mini trend sparks; the
     Live-Price chart (grid-column:1/-1) takes ALL remaining height, so it grows
     as the primary visual without lengthening the homepage. */
  /* row 1: the shared performance-range strip (auto). row 2: the two
     result cards. row 3: the XAUUSD chart, which still spans 1/-1. */
  grid-template-rows:auto 176px minmax(280px,1fr)}
.card{background:linear-gradient(180deg,rgba(19,25,36,.985),rgba(9,12,20,.99));
  border:1px solid var(--border-subtle);border-radius:12px;padding:15px 18px;min-width:0;
  display:flex;flex-direction:column;min-height:158px;
  /* soft inner top highlight + a low bottom depth shadow -> the cards read a
     touch deeper and more separated, still fully dark (never glassy) */
  box-shadow:inset 0 1px 0 rgba(255,255,255,.045),0 3px 8px rgba(0,0,0,.30)}
.card h3{font-size:11px;letter-spacing:.16em;text-transform:uppercase;
  color:var(--text-tertiary);font-weight:600;margin-bottom:7px}
/* the two info cards (Intelligence Brief / Platform Health) were removed, along
   with their .row/.arch/.cico/.card.brief/.card.health styling. */

/* the LARGE primary Live-Price chart, spanning the full panel width */
.card.chart{grid-column:1/-1;display:flex;flex-direction:column;position:relative;
  /* SAME navy-ceramic family as the Hybrid/KLDXAU cards. The LWC chart layer is
     now transparent, so this ONE surface shows through the whole plot + scales —
     therefore the warm-gold depth is dialled to a WHISPER (was a visible bottom
     band that read as a seam through the plot). Clean navy ceramic; the gold comes
     from the CHART line drawn onto it, not from the surface. */
  background:
    radial-gradient(120% 74% at 50% 116%,rgba(242,199,91,.05),transparent 60%),
    radial-gradient(120% 70% at 50% -12%,rgba(242,199,91,.035),transparent 58%),
    linear-gradient(180deg,rgba(19,25,36,.985),rgba(9,12,20,.99));
  overflow:hidden;
  box-shadow:inset 0 1px 0 rgba(255,255,255,.05),
             inset 0 -18px 30px -20px rgba(242,199,91,.10),
             0 3px 10px rgba(0,0,0,.32)}
/* Lightweight Charts host: the LARGE primary chart. Fills all height the card
   gives it (flex:1); real right price axis + bottom time axis, so NO edge mask
   here (that would clip the axis labels). */
.card.chart .lwc{width:100%;flex:1;min-height:0;margin-top:10px;display:block;position:relative;
  cursor:default;                      /* fixed chart — no navigation cursor */
  -webkit-user-select:none;user-select:none;
  touch-action:pan-y}                  /* the page always scrolls; the chart captures no gesture */
/* CSP-safe backstop for the library's attribution link (also disabled via the
   attributionLogo:false option) — our data is not a TradingView feed. */
.card.chart .lwc #tv-attr-logo{display:none!important}
/* embedded travelling-energy + endpoint-glow overlay canvas (landing.js), sampled
   from the LWC line coordinates and painted over it. Never captures pointer input. */
.card.chart .lwc .c-energy{position:absolute;inset:0;pointer-events:none;z-index:2}
/* The travelling comet + permanent endpoint glow for the two mini trend sparks
   (Hybrid, KLDXAU) is a canvas overlay (landing.js COMET) laid over each SVG.
   The Live Price card is a Lightweight Charts chart and does NOT use this. */
.comet-cv{position:absolute;pointer-events:none}
/* ---- Live-Price chart header: title + change badge (left), timeframe strip
   1m/15m/1H (right). In-flow, above the LARGE chart. ---- */
.chart-head{display:flex;align-items:center;gap:8px 10px;flex-wrap:wrap;padding:0 2px}
/* min-width:0 is the fix for the clipping: a flex item defaults to
   min-width:auto, so this row could never shrink below its content and
   overflowed .chart-head (measured: 73px past it at 320, putting the
   badge 54px outside the card, where it was clipped). With it the row
   shrinks first and, only when the three parts genuinely cannot share a
   line, wraps -- so the badge is always fully visible instead of cut. */
.chart-title{display:flex;align-items:center;gap:6px 9px;margin-right:auto;
  min-width:0;flex-wrap:wrap}
/* INLINE is the base composition: the title takes the slack and the strip
   sits at the header's trailing edge, which is where a chart toolbar belongs.
   The narrow variant lives in the container query further down -- so a wide
   card never pays for a phone's layout.
   No rule targets the strip itself. A flex child does not grow without an
   explicit flex:1, so it stays exactly as wide as its labels. A selector
   ending in the same class would also shadow the base rule for anything
   scanning this sheet by name, which is why none is written here. */
.chart-title{margin-right:auto;width:auto;justify-content:flex-start;
  text-align:start}
.chart-head{justify-content:flex-start}
.cslabel{font-size:11px;letter-spacing:.16em;text-transform:uppercase;
  color:var(--text-tertiary);font-weight:600;white-space:nowrap;
  -webkit-user-select:text;user-select:text}
/* live XAUUSD price — the STRONGEST header element; reacts to each live tick
   (green up-tick / red down-tick) then settles to neutral off-white, like an
   MT5/terminal. Fast flash in, gentle settle out. */
.c-px{font-size:19px;line-height:1;font-weight:700;font-variant-numeric:tabular-nums;
  letter-spacing:.005em;color:#F2ECD8;transition:color .5s var(--ease);
  -webkit-user-select:text;user-select:text}
.c-px.up{color:#16C784;transition:none}   /* instant flash-in to the true tick colour */
.c-px.dn{color:#EA3943;transition:none}   /* (base .c-px .5s handles the settle-out)  */
/* daily change badge — compact institutional pill (visible even when closed) */
/* white-space:nowrap is the fix for the split arrow: the value is ONE text
   node, "-1.02% <arrow>", and the space before the arrow was a legal break
   opportunity, so the arrow dropped to a second line inside the pill
   (measured: badge 34px tall for a 15px line). It now always reads as one
   unit. flex:0 0 auto stops the pill being squeezed narrower than that
   unit, which would clip the text inside its own background.
   The clamps compact it on small screens WITHOUT a viewport hack: both
   land on their max well before tablet, so desktop and laptop keep the
   exact 10px / 1.5px 6px they have today, and it only tightens where
   the row is genuinely short of room. Sized off the value, not off any
   particular percentage, so a longer +12.34% behaves identically. */
.mkt-badge{display:inline-flex;align-items:center;flex:0 0 auto;white-space:nowrap;
  font-size:clamp(9px,2.4vw,10px);font-weight:700;letter-spacing:.01em;
  padding:1.5px clamp(4.5px,1.5vw,6px);border-radius:5px;
  background:rgba(255,255,255,.05);color:var(--text-secondary);
  font-variant-numeric:tabular-nums;-webkit-user-select:text;user-select:text}
.mkt-badge.chg.up{color:var(--profit);background:rgba(63,191,135,.11)}
.mkt-badge.chg.dn{color:var(--loss);background:rgba(240,86,78,.11)}
.mkt-badge.flat{color:var(--text-tertiary)}
/* timeframe selector — a compact PILL/OVAL ceramic control. Outer: dark rounded
   pill, thin restrained border, subtle inner depth. Active: warm gold/bronze
   ceramic oval with dark readable text (NOT bright yellow, NOT neon, NOT a big
   button). Smooth active transitions between 1m/15m/1H. */
.tfsel{display:flex;align-items:center;gap:2px;max-width:100%;
  overflow-x:auto;scrollbar-width:none;-ms-overflow-style:none;
  padding:3px;border-radius:999px;background:rgba(12,16,23,.85);
  border:1px solid rgba(255,255,255,.05);
  box-shadow:inset 0 1px 0 rgba(255,255,255,.03),inset 0 -1px 2px rgba(0,0,0,.35)}
.tfsel::-webkit-scrollbar{display:none}
.tfbtn{appearance:none;-webkit-appearance:none;border:0;margin:0;cursor:pointer;
  font-family:inherit;font-size:10.5px;font-weight:600;letter-spacing:.02em;
  padding:4px 13px;border-radius:999px;color:var(--text-tertiary);white-space:nowrap;
  background:transparent;transition:color .2s var(--ease),background .2s var(--ease),box-shadow .2s var(--ease)}
.tfbtn:hover{color:var(--text-secondary)}
.tfbtn.is-on{color:#231703;font-weight:700;
  background:linear-gradient(180deg,#f2ca6e 0%,#e0ab48 55%,#c9973a 100%);
  box-shadow:inset 0 1px 0 rgba(255,244,214,.55),inset 0 -1px 2px rgba(120,80,20,.35),
             0 1px 3px rgba(0,0,0,.35)}
.tfbtn:focus-visible{outline:2px solid rgba(242,199,91,.55);outline-offset:1px}
.cempty{position:absolute;left:0;right:0;bottom:44px;text-align:center;font-size:11px;
  color:var(--text-tertiary);letter-spacing:.1em;display:none}
.cempty.show{display:block}
/* the latest-price marker is the Lightweight Charts price line + axis label (gold) */
/* the live-line endpoint + the travelling energy are painted on the .c-energy
   overlay canvas (landing.js), sampled from the real LWC line coordinates. */

/* ---- SHARED PERFORMANCE RANGE (HYBRID + KlDxAu + Lot Flight Line) --------
   Same segmented-pill family as the chart's .tfsel so it belongs to the page,
   but deliberately QUIETER and smaller: this is a secondary control sitting
   above two result cards, not the chart's primary timeframe strip. It spans
   the full grid width as its own auto row, with the label on the left and the
   pill hard right, so the association reads left-to-right and the pill never
   sits over the chart. */
.prsel-row{grid-column:1/-1;display:flex;align-items:center;flex-wrap:wrap;
  justify-content:space-between;gap:4px 10px;min-width:0;margin:-2px 0 -4px}
/* Label leading, pill trailing -- the association reads along the line and the
   pill never sits over a card. The stacked+centred variant is in the container
   query below and applies only when the row genuinely cannot hold both,
   measured against the LONGEST locale rather than English. */
.prsel-label{width:auto;text-align:start}
.prsel-label{font-size:9.5px;letter-spacing:.16em;text-transform:uppercase;
  color:var(--text-tertiary);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.prsel{display:flex;align-items:center;gap:2px;flex:0 0 auto;
  padding:2px;border-radius:999px;background:rgba(12,16,23,.72);
  border:1px solid rgba(255,255,255,.045)}
.prbtn{appearance:none;-webkit-appearance:none;border:0;margin:0;cursor:pointer;
  font-family:inherit;font-size:9.5px;font-weight:600;letter-spacing:.06em;
  padding:4px 10px;border-radius:999px;color:var(--text-tertiary);white-space:nowrap;
  background:transparent;min-height:24px;
  transition:color .2s var(--ease),background .2s var(--ease),box-shadow .2s var(--ease)}
.prbtn:hover{color:var(--text-secondary)}
.prbtn.is-on{color:#231703;font-weight:700;
  background:linear-gradient(180deg,#f2ca6e 0%,#e0ab48 55%,#c9973a 100%);
  box-shadow:inset 0 1px 0 rgba(255,244,214,.5),inset 0 -1px 2px rgba(120,80,20,.3),
             0 1px 2px rgba(0,0,0,.3)}
.prbtn:focus-visible{outline:2px solid rgba(242,199,91,.55);outline-offset:1px}
/* a request that failed keeps the last valid figures and says so, quietly */
.prsel[data-state="stale"]{border-color:rgba(242,199,91,.34)}
/* the passive echo under the Lot Flight Line subtitle */
.lotline-range{text-align:center;margin:-7px 0 11px;font-size:9.5px;letter-spacing:.34px;
  color:var(--text-tertiary);min-height:11px}
.lotline-range:empty{display:none}

/* ---- COMPACT, CENTRED SEGMENTED CONTROLS --------------------------------
   Both strips are sized by their own content and centred on their line. A
   segmented control that stretches to fill a row reads as a navigation bar;
   these are settings, and they should occupy exactly the width of their
   labels. The two remain visually distinct -- the performance range carries
   its own uppercase label above it, the chart strip sits inside the chart
   header next to the price -- so they cannot be mistaken for one another. */
/* No rule is added for the strips themselves. Centring comes from the PARENT
   (.chart-head / .prsel-row put each control alone on its line and centre it),
   so the controls keep their own base rules untouched -- including the
   overflow-x scroll affordance and the symmetric padding the tfsel contract
   depends on, and with no margin that could push the chart. */

/* ---- NARROW-CONTAINER COMPOSITION ---------------------------------------
   Each control drops to its own centred row only when the CONTAINER cannot
   hold it inline. The two thresholds differ because the two rows have
   different content: the performance row needs 316px for its longest label
   (Spanish) plus the pill; the chart header needs 526px for its longest title
   (Russian) plus the strip. Sizing both from the worst locale is what keeps
   the composition identical in every language -- the layout changes at the
   same physical width whatever the words are.

   The query size is the container's CONTENT box, so these numbers are the space
   the row genuinely has: .cards carries 18px of padding a side, so a 480px
   viewport gives a 384px box but only 348px of content -- which is why 480
   stacks and a 600px viewport (460px of content) does not. Comparing against
   the border box would have mis-set both switch points by 36px.
   Measured intrinsic widths are recorded in patch_phaseA.py. */
@container cards (max-width:359px){
  .prsel-row{justify-content:center}
  .prsel-label{width:100%;text-align:center}
}
@container cards (max-width:599px){
  .chart-head{justify-content:center}
  .chart-title{margin-right:0;width:100%;justify-content:center;text-align:center}
}
/* Container queries have been baseline for years, but a browser without them
   would otherwise get the INLINE layout at every size and clip on a phone --
   the one failure mode worth a fallback. Viewport width is a poor proxy (see
   the 480/768 inversion above), so the fallback is deliberately generous:
   stack below 1080, which is the band where the stage is never roomy. */
@supports not (container-type:inline-size){
  @media (max-width:1080px){
    .prsel-row{justify-content:center}
    .prsel-label{width:100%;text-align:center}
    .chart-head{justify-content:center}
    .chart-title{margin-right:0;width:100%;justify-content:center;text-align:center}
  }
}
/* ==== DIRECTION CONTRACT =================================================
   Arabic changes the language, not the physical product.

   Setting dir="rtl" on <html> is right for text and wrong for structure: it
   mirrored the whole marketing shell, measured at 1280px as logo 67 -> 1164,
   XAUUSD panel 526 -> 85, technology rail 526 -> 85 and the result cards
   reordered. A visitor who switches language should not be shown a different
   product.

   Three layers, the same ones the dashboard shell already uses:
     1. the SHELL is pinned to a fixed physical geometry;
     2. the WORDS inside it are returned to the locale's direction;
     3. canonical NUMBERS are isolated so bidi cannot reorder them.
   `direction` inherits and bidi applies per inline box, so pinning the
   containers is sufficient -- Arabic still renders right-to-left inside each
   one. ================================================================== */
[dir="rtl"] header,[dir="rtl"] .bar,[dir="rtl"] nav,
[dir="rtl"] .hero,[dir="rtl"] .cols,[dir="rtl"] .stage,
[dir="rtl"] .tiltwrap,[dir="rtl"] .window,[dir="rtl"] .wmain,
[dir="rtl"] .cards,[dir="rtl"] .card,[dir="rtl"] .chart-head,
[dir="rtl"] .prsel-row,[dir="rtl"] .topbar,[dir="rtl"] .trust,
[dir="rtl"] .trust-rail,[dir="rtl"] .lotline-track,
[dir="rtl"] .strip,[dir="rtl"] .srow,[dir="rtl"] .flinks,
[dir="rtl"] .paygrp,[dir="rtl"] .pay-marks{direction:ltr}
/* ...and the words inside the shell are the locale's, aligned to its own
   reading edge. text-align:start resolves against the element's OWN direction,
   so this is one rule for every language rather than a left/right pair. */
/* ALIGNMENT IS NOT SET HERE. It was, and that was a mistake: forcing
   text-align:start onto every prose element pushed .trust-h, .lotline-h and
   .lotline-sub -- which the English design CENTRES -- to the right edge in
   Arabic, changing the composition rather than the language. Because the base
   sheet leaves prose at its initial `start`, setting only `direction` is enough:
   start resolves against each element's OWN direction, so Arabic prose moves to
   its reading edge while a centred heading stays centred in all seven locales. */
/* STRUCTURAL, NOT A LIST. This used to name the elements to return -- .hero h1,
   .card p, .lotline-sub and so on -- and a list can only ever name what existed
   when it was written. Measured in Arabic: the header's two call-to-action
   buttons, the tagline bar, the market-state word, the "coming soon" flag, the
   capital heading, the sizing dialog and the footer byline were all still
   rendering LTR because nobody had added them.

   So the default is inverted. Inside the shell, text is the LOCALE'S; a
   container is left-to-right only when it is NAMED in the rule above. :where()
   makes this rule specificity-zero on its own selector, so every named
   container outranks it whatever the source order -- the range row keeps its
   physical button order while the words inside it read right-to-left.

   IT RESTORES TEXT, NEVER A CONTAINER. `direction` on a flex or grid container
   reverses the order of its children, so a rule broad enough to catch every
   paragraph is also broad enough to turn the product around. Measured when it
   was written as a plain descendant rule: the timeframe buttons, the range
   buttons, the 0.01 -> 0.05 ladder and the technology rail all came out
   mirrored against production. Naming the TEXT elements fixes that at the
   cause -- a <div>, <ol>, <ul> or <table> is never matched, so no sequence can
   reverse, while a heading, paragraph, list item, label or button caption is
   always the locale's whether or not anyone remembered to add it. */
[dir="rtl"] :where(header,.hero,.cols,.cards,.card,.chart-head,.prsel-row,
                   .topbar,.lotline,.strip,.srow,.flinks)
            :where(p,h1,h2,h3,h4,h5,h6,li,span,em,b,strong,small,a,label,
                   button,summary,dt,dd,figcaption){direction:rtl}
/* A TEXT REGION is returned whole. .pitch is the hero's own reading column --
   an eyebrow, a headline, a paragraph, a call to action and three marks, read
   top to bottom. Because the rule above returns text ELEMENTS and never their
   containers, the headline and the paragraph moved to the Arabic reading edge
   while the three ROWS between them stayed anchored at the left, which reads as
   a column that cannot decide which way it runs. Nothing in .pitch is product
   geometry -- no plan order, no ladder, no travel -- so the whole column is the
   locale's, and the two buttons and three marks lead from the same edge as the
   sentence above them.

   .lotline is the same shape of thing: a heading, a subtitle, a range line, a
   capital label with its explain control, a dialog and a closing invitation --
   all reading matter -- around ONE geometric element, the 0.01 -> 0.05 ladder.
   That ladder is anchored by name above and outranks this rule, so returning
   the section is safe: the ladder still ascends left to right in every locale
   while the words around it lead from the Arabic edge. */
[dir="rtl"] .pitch,[dir="rtl"] .lotline{direction:rtl}
/* Canonical values never flip: a price, a ticker, a signed pip total and a
   date are read the same way in every language. isolate keeps a leading "+"
   or "-" attached to its own number inside an Arabic sentence. */
[dir="rtl"] .num,[dir="rtl"] .mono,[dir="rtl"] .px,[dir="rtl"] .c-px,
[dir="rtl"] .lot-size,[dir="rtl"] .lot-usd,[dir="rtl"] .tsym,
[dir="rtl"] .mkt-badge{direction:ltr;unicode-bidi:isolate}
/* A value is isolated AS A UNIT, so nothing inside one is re-directed either:
   the label and the currency code belong to the figure, not to the sentence
   around it. Without this the rule above would reach the <em>USD</em> inside a
   result and set it right-to-left -- harmless while the code is pure Latin,
   and a reordered figure the first time a unit carries a digit. */
[dir="rtl"] .num *,[dir="rtl"] .mono *,[dir="rtl"] .px *,
[dir="rtl"] .c-px *,[dir="rtl"] .lot-size *,[dir="rtl"] .lot-usd *,
[dir="rtl"] .tsym *,[dir="rtl"] .mkt-badge *{direction:ltr}
/* The kite is decorative artwork anchored to the hero's own art layer. It is
   named here so a future direction rule can never move it out of frame -- the
   one element that survived the mirroring, and it stays that way. */
[dir="rtl"] .kite{direction:ltr}

/* ---- STABLE ISLANDS ------------------------------------------------------
   A control or an identity that must read the same in every language, sealed
   DEEPLY so no restore rule can reach into it.

   THE BRAND LOCKUP IS AN IDENTITY, NOT A SENTENCE. The mark leads the wordmark
   at the same gap, size and baseline in every locale. It is an <a>, and the
   structural restore names <a>, so without this it reordered in Arabic:
   measured at 1440, EN and DE put the mark at x=0 and the word at x=46, and
   Arabic put the mark at x=87 and the word at x=0. Same box, mutated identity.

   The two segmented controls are named for the same reason. They are <div>s,
   so the restore cannot match them today and they merely inherit -- naming
   them makes the guarantee explicit rather than incidental, which is the whole
   point of a control whose ORDER carries meaning (1m before 15m before 1H,
   1D before 1W before 1M before ALL). */
[dir="rtl"] .brandblk,[dir="rtl"] .brandblk *,
[dir="rtl"] .tfsel,[dir="rtl"] .tfsel *,
[dir="rtl"] .prsel,[dir="rtl"] .prsel *{direction:ltr}

/* ---- ARABIC PRIMARY COMPOSITION -----------------------------------------
   The homepage's two hero columns SWAP SIDES in Arabic: the reading column
   leads from the right, the XAUUSD panel sits left. This is the one place a
   whole column changes side, and it is deliberate -- an Arabic composition,
   not a page that happened to flip.

   It is expressed as explicit GRID PLACEMENT, never as `direction:rtl` on the
   layout root. Direction on .cols would swap the columns AND reverse every row
   nested inside them -- the timeframe buttons, the range buttons, the lot
   ladder and the technology rail all travel through here.

   The track sizes are mirrored rather than re-tuned, so the panel keeps
   exactly the weight it has in English: .72fr/1.28fr becomes 1.28fr/.72fr, and
   .9fr/1.1fr becomes 1.1fr/.9fr at the narrower desktop step.

   Below 761px .cols is a SINGLE column. There is no left and right to swap, so
   nothing is forced: the vertical order stays reading-column first, panel
   after it, which is the same order an Arabic reader wants.

   The stage's 18px nudge and the kite's 21% offset are horizontal placements
   measured from one edge, so both are mirrored too -- otherwise the panel
   drifts toward the page centre and the kite hovers over the panel instead of
   over the copy it belongs to. The artwork itself is never flipped: only where
   it sits changes, and the parallax offset is negated so it still trails the
   pointer the same way. */
@media (min-width:761px){
  [dir="rtl"] .cols{grid-template-columns:1.28fr .72fr}
  [dir="rtl"] .pitch{grid-column:2;grid-row:1}
  [dir="rtl"] .stage{grid-column:1;grid-row:1;transform:translate(-18px,0)}
  [dir="rtl"] .kite{left:auto;right:21%;
    transform:translate3d(calc(var(--kx,0px) * -1),var(--ky,0px),0)}
}
@media (min-width:761px) and (max-width:1180px){
  [dir="rtl"] .cols{grid-template-columns:1.1fr .9fr}
}

/* ---- SESSION NOTICE ------------------------------------------------------
   One line, under the shared range control, for all three surfaces. It is a
   STATEMENT OF STATE, not an alert: same 9.5px uppercase scale as the range
   label above it, no box, no colour block. The closed mark takes the warning
   ink only on the two words that carry the meaning.
   It occupies no height when hidden, so nothing on the card moves when the
   market opens or closes. */
/* A FLEX CHILD of the range row, never a grid item. flex-basis:100% puts it on
   its own line inside the row it qualifies, so the .cards grid keeps exactly the
   track count it has when the market is open and the closed state cannot inflate
   the panel. order:-1 keeps it above the control. */
.sessnote{flex:0 0 100%;order:-1;display:flex;flex-wrap:wrap;align-items:baseline;
  justify-content:center;gap:0 .1em;margin:0 0 5px;padding:0;line-height:1.35}
.sessnote[hidden]{display:none}
/* HIERARCHY. Three related but unequal facts: the STATE leads, the qualifier
   explains it, the date pins it. Same line, three weights -- an institutional
   status treatment rather than one uniform whisper. */
.sn-mark{font-size:10.5px;font-weight:700;letter-spacing:.15em;
  text-transform:uppercase;color:var(--warn,#d9a441)}
.sn-mark::before{content:"";display:inline-block;width:5px;height:5px;
  border-radius:50%;background:currentColor;margin-inline-end:.55em;
  vertical-align:.08em;opacity:.9}
.sessnote .sn-q{font-size:9.5px;letter-spacing:.13em;text-transform:uppercase;
  color:var(--text-tertiary)}
.sessnote .num{font-size:10px;letter-spacing:.04em;font-weight:600;
  color:var(--text-secondary);font-variant-numeric:tabular-nums}
.sn-dot{width:3px;height:3px;border-radius:50%;flex:none;margin:0 .6em;
  background:currentColor;opacity:.4;align-self:center}

/* ---- KAIT RECOMMENDED CAPITAL -------------------------------------------
   A THIRD value on the same flight node, not a table column. The live result
   keeps its weight; the guidance sits beneath it, quieter and in the neutral
   ink, so the eye reads performance first and reference second. Nothing here
   is a grid: the nodes are still the five points on the thread. */
.lot-cap{display:block;margin-top:5px;padding-top:5px;font-size:10px;
  letter-spacing:.04em;color:var(--text-tertiary);
  font-variant-numeric:tabular-nums;white-space:nowrap;
  border-top:1px solid rgba(255,255,255,.07)}
.lotcap{display:flex;align-items:center;justify-content:center;gap:7px;
  margin:16px 0 0}
.lotcap-t{font-size:9.5px;letter-spacing:.16em;text-transform:uppercase;
  color:var(--text-tertiary);font-weight:600}
.lotcap-sub{margin:3px 0 0;font-size:11px;color:var(--text-tertiary);
  text-align:center;opacity:.85}

/* the affordance: a 24px target that LOOKS like 15px, so the tap area meets
   WCAG 2.5.8 without a heavy mark sitting next to quiet type */
.sizing-info{appearance:none;-webkit-appearance:none;background:none;border:0;
  padding:0;margin:0;width:24px;height:24px;display:inline-flex;
  align-items:center;justify-content:center;cursor:pointer;flex:none;
  color:var(--brand);border-radius:50%}
.sizing-info svg{width:15px;height:15px;fill:none;stroke:currentColor;
  stroke-width:1.6;stroke-linecap:round;overflow:visible}
.sizing-info svg .sd{fill:currentColor;stroke:none}
.sizing-info::after{content:"";position:absolute;width:24px;height:24px;
  border-radius:50%;pointer-events:none;
  box-shadow:0 0 0 0 rgba(242,199,91,.34);
  animation:sizing-pulse 4.5s ease-out infinite}
.sizing-info{position:relative}
@keyframes sizing-pulse{
  0%,70%,100%{box-shadow:0 0 0 0 rgba(242,199,91,0)}
  12%{box-shadow:0 0 0 4px rgba(242,199,91,.20)}
  30%{box-shadow:0 0 0 7px rgba(242,199,91,0)}
}
.sizing-info:hover,.sizing-info:focus-visible{color:var(--brand-hi,#F2C75B)}
.sizing-info:focus-visible{outline:2px solid var(--brand);outline-offset:2px}

.sizing-pop{max-width:520px;margin:10px auto 0;padding:14px 16px;
  border-radius:12px;text-align:start;
  background:linear-gradient(180deg,#141821,#0f1216);
  border:1px solid rgba(242,199,91,.24);
  box-shadow:0 14px 40px rgba(0,0,0,.42)}
.sizing-pop[hidden]{display:none}
.sizing-pop h3{margin:0 0 6px;font-size:12.5px;letter-spacing:.02em;
  color:var(--brand);font-weight:700}
.sizing-pop h3:focus{outline:none}
.sizing-pop p{margin:0;font-size:12px;line-height:1.62;color:var(--text-secondary)}
.sizing-x{appearance:none;-webkit-appearance:none;margin-top:10px;
  padding:5px 12px;min-height:24px;border-radius:999px;cursor:pointer;
  font-family:inherit;font-size:10.5px;letter-spacing:.1em;
  text-transform:uppercase;font-weight:600;color:var(--text-secondary);
  background:rgba(255,255,255,.04);border:1px solid var(--border-subtle)}
.sizing-x:hover{color:var(--text-primary,#eef1f5)}
.sizing-x:focus-visible{outline:2px solid var(--brand);outline-offset:2px}

/* the CTA is a sentence, not a button block: it invites a conversation */
.lotcta{margin:14px 0 0;text-align:center;font-size:11.5px;line-height:1.7;
  color:var(--text-tertiary)}
.lotcta-q{color:var(--text-secondary)}
.lotcta-a{color:var(--brand);font-weight:600;text-decoration:none;
  padding:2px 4px;border-radius:6px;margin-inline-start:.35em}
.lotcta-a:hover{text-decoration:underline}
.lotcta-a:focus-visible{outline:2px solid var(--brand);outline-offset:2px}
.lotcta-n{display:block;opacity:.8;font-size:10.5px}

@media (prefers-reduced-motion:reduce){
  .sizing-info::after{animation:none}
}

/* live price number (base; the chart overlay overrides size + makes it selectable) */
.px{font-size:24px;font-weight:700;transition:color .45s var(--ease)}
.px.tick{color:var(--brand-hi);transition:none}

/* Hybrid Trend — sparkline + a travelling live glow that rides the curve */
.card.mtrend{position:relative;                /* Hybrid -> blue identity */
  background:
    radial-gradient(130% 78% at 50% 116%,rgba(76,141,247,.11),transparent 60%),
    linear-gradient(180deg,rgba(19,25,36,.985),rgba(9,12,20,.99));
  box-shadow:inset 0 1px 0 rgba(255,255,255,.045),
             inset 0 -16px 28px -20px rgba(76,141,247,.42),
             0 3px 8px rgba(0,0,0,.30)}
.mthead{display:flex;justify-content:space-between;align-items:flex-start;gap:10px}
.mthead h3{margin-bottom:0;line-height:1.5}
.mtpips{font-size:17px;font-weight:700;color:#4C8DF7;line-height:1.5;text-shadow:0 0 5px rgba(76,141,247,.32)}    /* pips: blue + micro-glow; roomy line-height so the digit tops never crowd/clip */
.mtpips em{font-style:normal;font-size:10px;color:var(--text-tertiary);font-weight:500}
.mtusd{position:absolute;right:18px;bottom:12px;font-size:13px;font-weight:700;
  text-shadow:0 1px 5px rgba(0,0,0,.85)}                                  /* $ profit -> bottom-right corner */
.mtusd.pos{color:var(--profit)} .mtusd.neg{color:var(--loss)} .mtusd.mut{color:var(--text-tertiary)}
.mtusd em{font-style:normal;font-size:9px;color:var(--text-tertiary);font-weight:500;letter-spacing:.06em}
.card.mtrend svg{width:100%;flex:1;min-height:0;margin-top:6px;display:block}
#ms-line{stroke:#4C8DF7;stroke-width:1.5;vector-effect:non-scaling-stroke}
/* the blue comet + endpoint that ride this line are the canvas overlay (COMET) */

/* ---------- KlDxAu card: the MODELED points strategy — violet, sibling of the blue Hybrid ---------- */
.card.msum.kx{position:relative;              /* KLDXAU -> violet identity (mirrors Hybrid) */
  /* its OWN size container: the pre-release mark below is placed from the
     CARD's width, which is the thing that actually varies, instead of from a
     viewport breakpoint that only correlates with it. Verified not to change
     the card box, the chart height or the HYBRID card. */
  container-type:inline-size;container-name:kxcard;
  background:
    radial-gradient(130% 78% at 50% 116%,rgba(167,139,250,.11),transparent 60%),
    linear-gradient(180deg,rgba(19,25,36,.985),rgba(9,12,20,.99));
  box-shadow:inset 0 1px 0 rgba(255,255,255,.045),
             inset 0 -16px 28px -20px rgba(167,139,250,.42),
             0 3px 8px rgba(0,0,0,.30)}
.kxpips{font-size:17px;font-weight:700;color:#A78BFA;line-height:1.5;text-shadow:0 0 5px rgba(167,139,250,.32)}    /* pips: violet + micro-glow; roomy line-height so the digit tops never crowd/clip */
.kxpips em{font-style:normal;font-size:10px;color:var(--text-tertiary);font-weight:500}
.card.msum.kx svg{width:100%;flex:1;min-height:0;margin-top:6px;display:block}
#kx-line{stroke:#A78BFA;stroke-width:1.5;vector-effect:non-scaling-stroke}
/* KLDXAU pre-release mark. Deliberately the quietest thing on the card: 8.5px,
   uppercase, tracked, gold at low alpha over a barely-there gold wash. It is a
   footnote to a live number, not a banner over it.

   PLACEMENT: directly under the KLDXAU title, 5px below its baseline box.
   Absolute, so it adds NO height -- the card box, the sparkline and the HYBRID
   card next to it are all untouched, and the two cards stay the same height.

   ONE TYPE SIZE IN EVERY LANGUAGE. 8.5px is fixed here and nowhere overridden
   per locale: a longer translation makes the BOX wider, never the text smaller.
   Measured widths run 27px (ar) to 98px (es) and all of them clear the pips.

   WHY `inset-inline-start` HERE, WHEN THE PROFIT MARK USES PHYSICAL `left`.
   The two neighbours behave differently. .mtusd is pinned with a physical
   right:18px, so it never mirrors. .kxpips is a FLEX CHILD of .mthead, so it
   DOES flip to the left in Arabic -- which is exactly what a physical `left`
   walked into: the mark and the pips collided in ar and nowhere else. Sharing
   the header means sharing its direction, so this one is logical. */
.kxsoon{position:absolute;inset-inline-start:18px;top:36px;pointer-events:none;
  font-size:8.5px;font-weight:600;letter-spacing:.14em;text-transform:uppercase;
  line-height:1;white-space:nowrap;padding:3px 6px;border-radius:3px;
  color:rgba(242,199,91,.70);border:1px solid rgba(242,199,91,.20);
  background:rgba(242,199,91,.045)}

/* On a NARROW card the header itself changes shape: the pips no longer fit
   beside the title, so they wrap and the header grows from ~42px to ~67px tall.
   A mark tucked 5px under the title then lands on the pips' second line -- and
   there is no horizontal room to dodge either (a 145px card leaves 109px of
   content for a 98px mark and a 62px pips). So on those cards the mark drops
   clear of the whole header instead, still the first thing under the title.
   Driven by the CARD's own width, which is the thing that actually varies. */
@container kxcard (max-width:199px){
  .kxsoon{top:73px}
}
/* The mark is positioned against the card's PADDING box, so its inset has to
   equal the card's own padding to sit flush under the K of KLDXAU. One
   breakpoint narrows that padding to 16px (the same block that sets
   .card{padding:14px 16px}), so the inset follows it there -- otherwise the
   mark sat 2px inside the title on short, wide screens. */
@media (max-height:940px) and (min-width:1081px){
  .kxsoon{inset-inline-start:16px}
}

/* the violet comet + endpoint that ride this line are the canvas overlay (COMET) */


/* ---------- trust rail: technology & execution infrastructure ----------
   The transition out of the one-screen hero. INFORMATIONAL only: these are the
   technologies and execution venues the platform runs on. Nothing here is a
   link, and no wording anywhere claims partnership, endorsement or
   certification -- the trust is in the infrastructure, never in a relationship
   with the companies that own it. */
/* GEOMETRY COMES FROM THE PARENT, NOT FROM A NUMBER IN HERE.
   .trust is a child of .stage -- the same .cols grid column that owns the
   XAUUSD panel -- so its left edge, right edge and width ARE the panel's, with
   nothing restating them. No max-width, no vw, no offset, no second source of
   truth: change the hero grid ratio and both move together. It used to be a
   body-level full-bleed band, which is exactly why it ran under the left hero
   column. Rounded, bordered and lit a little more quietly than the panel above
   it, so it reads as supporting infrastructure rather than a second headline. */
.trust{position:relative;margin-top:28px;padding:20px 0 18px;overflow:hidden;
  border:1px solid rgba(242,199,91,.16);border-radius:14px;
  background:linear-gradient(180deg,rgba(13,17,26,.72),rgba(8,11,17,.84))}
/* the same warm gold the hero is lit by, at a fraction of the strength, so the
   rail reads as part of the scene rather than a strip pasted over it */
.trust::before{content:"";position:absolute;inset:0;pointer-events:none;
  background:radial-gradient(ellipse 44% 128% at 50% 50%,rgba(242,199,91,.06),transparent 70%)}
.trust-h{position:relative;text-align:center;margin:0 auto 16px;max-width:min(92%,640px);
  font-size:11px;font-weight:600;letter-spacing:.2em;text-transform:uppercase;
  line-height:1.5;color:var(--text-tertiary)}

/* Edges are masked so marks arrive and leave as light instead of sliding out
   from under a hard border. Both properties are written: -webkit- covers every
   shipping engine, unprefixed is the standard. Without either, the rail simply
   has square edges -- it still runs, nothing breaks. */
/* The rail fills its card, and the card is the panel column, so the widest it
   can ever be is that column (~1055px at the 1760px .wrap cap). One unit of
   track stays comfortably wider than that, which is what keeps the seamless
   loop safe at every screen size without a cap being restated here. */
.trust-rail{position:relative;overflow:hidden;
  -webkit-mask-image:linear-gradient(90deg,transparent 0,#000 9%,#000 91%,transparent 100%);
          mask-image:linear-gradient(90deg,transparent 0,#000 9%,#000 91%,transparent 100%)}

/* SEAMLESS LOOP. The track carries the sequence-block twice and travels exactly
   -50%, so copy two lands on the pixel copy one started from: there is no seam
   to hide and no restart to see. `width:max-content` keeps the track at its
   natural width so the percentage is always measured against real content.
   The repeat count in the markup is chosen so ONE unit is always wider than the
   rail, which is what guarantees no empty gap at the trailing edge. It is a
   function of how many marks are in the sequence and of how wide the rail can
   get: 4 repeats of the current two marks. 32s over that distance holds ~54px/s
   -- the same pace as before the rail narrowed, because the period was shortened
   in step with the unit rather than left to drift faster. */
.trust-track{display:flex;width:max-content;will-change:transform;
  animation:trust-scroll var(--trust-dur,30s) linear infinite}
@keyframes trust-scroll{
  from{transform:translate3d(0,0,0)}
  to{transform:translate3d(-50%,0,0)}
}
/* DIRECTION. `translate3d` is PHYSICAL: -50% is leftward whatever the writing
   mode. In LTR the flex track's inline-start is its left edge, so it overflows
   rightward and -50% pulls copy two into view -- correct. Under dir="rtl" the
   flex main axis mirrors: the track is anchored at the RIGHT edge of the rail
   and overflows LEFTWARD, so that same -50% travels AWAY from its own content
   and the rail drains from the trailing edge until it is empty. Measured on
   production at 1440: rail [586..1369], LTR track [586..2974] (overflow right),
   RTL track [-1513..875] (overflow left) -- same width, mirrored anchor.
   Everything else about the loop is already symmetric: the distance is the
   same 50%, one unit is wider than the rail in either direction, the item
   padding is `0 clamp(...)` on both sides, and the edge mask is a symmetric
   90deg gradient. Only the SIGN of the travel is direction-dependent, so the
   fix is one mirrored keyframe pair -- not a second rail, not RTL markup and
   not a line of JS. */
/* DIRECTION IS NO LONGER A VARIABLE HERE.
   This rail used to carry a mirrored keyframe pair, because under dir="rtl" the
   flex track anchored to the RIGHT edge and overflowed leftward, so a leftward
   -50% travelled away from its own content and the rail drained.

   The direction contract removed that condition: .trust and .trust-rail are
   pinned to direction:ltr in every locale, so the track's main axis is the same
   physical axis in Arabic as in English. The mirror then became not merely
   redundant but WRONG -- LTR geometry driven by an RTL animation drains exactly
   as the original bug did. Verified from the live cascade: in Arabic
   .trust-rail computed direction:ltr while [dir="rtl"] .trust-track was still
   selecting trust-scroll-rtl.

   Content direction and animation geometry are separate concerns, and the
   geometry is now locale-invariant by construction. ONE animation, every
   locale, with no override to keep in step. */
.trust-seq{display:flex;align-items:center;list-style:none;margin:0;padding:0}
.trust-seq li{flex:none;position:relative;display:flex;align-items:center;justify-content:center;
  padding:0 clamp(24px,3.2vw,54px)}
/* the gold lives in the ATMOSPHERE around the slot, never on the mark itself */
.trust-seq li::before{content:"";position:absolute;inset:-16% 2%;pointer-events:none;
  border-radius:999px;opacity:0;transition:opacity .32s var(--ease);
  background:radial-gradient(ellipse 60% 118% at 50% 50%,rgba(242,199,91,.10),transparent 72%)}
.trust-seq li:hover::before{opacity:1}

/* ONE LIGHT-NEUTRAL SYSTEM OUT OF FOUR BRAND PALETTES.
   A single filter cannot do this -- it destroys two of the four -- so each mark
   gets the least transformation that reaches the same neutral:

   INVERT class (marks that are a single dark tone). brightness(0) drives every
   colour channel to 0, invert(1) lifts them to white; neither touches ALPHA, so
   the silhouette, the anti-aliased edges and every internal gap are preserved
   exactly. Safe only because these two are single-tone: verified that 100% of
   .tl-tradingview's opaque pixels are one tone, and that the notch inside the
   .tl-vantage mark is a transparent gap rather than a colour boundary.

   GRAYSCALE class (marks carrying internal structure in COLOUR). Desaturation
   keeps luminance differences, which is the only reason .tl-mt5 keeps its
   "5" and .tl-vtmarkets keeps its dot -- inverting either collapsed it into a
   featureless blob. MT5's brightness is capped: its "5" desaturates to 168
   against a 255 disc, so any multiplier above ~1.52 clips the numeral out of
   existence. 1.30 keeps it at 218 and clearly readable; the glyph is lifted the
   rest of the way with opacity, which raises it without flattening its
   internal contrast.
   Measured result: effective lightness 184-205 across all four (+/-5%). */
.trust-seq img{display:block;width:auto;height:var(--lh,26px);max-width:var(--lw,180px);
  object-fit:contain;opacity:var(--ink,.82);
  transition:opacity .3s var(--ease),filter .3s var(--ease)}
.trust-seq li:hover img{--ink:1}
/* .tl-vantage and .tl-vtmarkets are RETAINED while those two marks are held out
   of the markup pending written logo permissions (2026-08-18). They cost nothing
   unused and are what makes restoring the marks a markup-only change. */
.tl-tradingview{--lh:23px;--lw:180px;--ink:.82;filter:brightness(0) invert(1) brightness(.92)}
.tl-vantage    {--lh:26px;--lw:130px;--ink:.82;filter:brightness(0) invert(1) brightness(.92)}
.tl-mt5        {--lh:38px;--lw:44px; --ink:.95;filter:grayscale(1) brightness(1.30)}
.tl-vtmarkets  {--lh:25px;--lw:152px;--ink:.86;filter:grayscale(1) brightness(.95)}
/* Gokait sits IN the family, not above it: same height band, same ink, same
   neutralising filter, so no brand dominates the rail. --lw is the usual
   safety cap set just above the mark's natural width at this height
   (446/432 = 1.03 -> 27px at --lh:26px), so it is never stretched and never
   letterboxed. */
.tl-kait       {--lh:26px;--lw:28px; --ink:.88;filter:grayscale(1) brightness(1.18)}

/* ---- NAMED LOCKUPS -------------------------------------------------------
   Two marks in this rail are an icon plus a name. A visitor should not have to
   guess what a bare K or a bare disc is, and both names are set as TEXT beside
   the existing artwork -- no invented logo, no new third-party asset.

   The lockup is a sealed physical island: mark first, word second, one fixed
   gap, in every locale. The rail is already anchored left-to-right, and this
   states the same guarantee on the lockup itself so it cannot be inherited
   away. The words are never translated.

   The word is sized from the marks around it rather than by eye: at --lh:26px
   the neighbouring wordmarks stand 23-26px tall, and 17px/700 Inter has a cap
   height of ~12.3px and an overall ink height of ~17px, which reads at the
   same optical weight without the name shouting over the logos. */
.tl-lock{display:flex;align-items:center;gap:var(--tl-gap,9px);
  direction:ltr;unicode-bidi:isolate}
.tl-word{font:700 var(--tl-fs,17px)/1 var(--f);letter-spacing:.01em;
  white-space:nowrap;color:var(--tl-ink,#C6CAD1)}

/* GOKAIT: the artwork keeps its native gold and the word is set in brand gold,
   because the LOCKUP now carries the filter that neutralises them together.
   At rest that filter is precisely the one .tl-kait used to carry on its own,
   so nothing about the neutral state changed -- only what it is applied to. */
.tl-gokait{filter:grayscale(1) brightness(1.18)}
.tl-gokait .tl-kait{filter:none}
.tl-gokait .tl-word{color:var(--brand)}
/* MetaTrader's disc keeps its own desaturating filter; only the name is new. */
.tl-mtlock .tl-word{--tl-fs:16px}
/* ---- Gokait ENTERS GOLD, LEAVES NEUTRAL --------------------------------
   Tied to TRAVEL, not to a timer of its own. The track advances exactly one
   sequence per --trust-dur, so a mark's POSITION in the rail repeats with that
   period; KAIT sits at slots 1 and 6 of 10, which is 0 and 0.5 of the cycle,
   so two phase offsets phase-lock both marks to where they actually are. No
   JS, no per-frame measurement, no second clock to drift.

   Only `filter` animates -- never a dimension, a margin or the mark's box --
   so there is no layout shift and no effect on rail speed. Opacity is left to
   --ink so the mark keeps the family's optical weight throughout.

   The venue marks are untouched: this rule names .tl-kait alone. */
/* ONE MOMENT, AT THE CENTRE. Gokait travels the rail in the same neutral the
   other four marks wear, lights once as it crosses the middle, and returns to
   neutral before it reaches the far edge.

   A mark's animation phase IS its position, but the phase at which it crosses
   the rail's visual centre is not a constant: it is (x + (w - R)/2) / S, so it
   moves with the rail width and the sequence width. Measured from 320 to
   2560px it runs from 0.822 to 0.965 -- so a single fixed-phase event would be
   centred at one width and near the arrival edge at another.

   The map below is therefore always centred at 90%, and each width band
   carries the offset that puts ITS measured crossing there:

       band          measured centre   --gk-phase   peak lands at
       >=1181px      0.822 - 0.889     -0.045       40-57% of the pass
       761-1180px    0.907 - 0.945     -0.974       42-56%
       421-760px     0.868 - 0.941     -0.988       38-61%
       <=420px       0.949 - 0.965     -0.944       46-53%

   84% -> 96% is the whole event: roughly 1.2s of hold at 30s, 1.0s at 24s and
   0.6s at 14s, with a symmetric ramp either side. Only `filter` animates, on
   the compositor, so nothing about the rail's geometry or speed is touched,
   and every keyframe carries the same function list so the interpolation is
   well defined. The venue marks are never named by any of this. */
@keyframes gokait-moment{
  0%   {filter:grayscale(1) brightness(1.18) saturate(1)
        drop-shadow(0 0 0 rgba(242,199,91,0))}
  84%  {filter:grayscale(1) brightness(1.18) saturate(1)
        drop-shadow(0 0 0 rgba(242,199,91,0))}
  88%  {filter:grayscale(0) brightness(1.06) saturate(1.10)
        drop-shadow(0 0 6px rgba(242,199,91,.30))}
  92%  {filter:grayscale(0) brightness(1.06) saturate(1.10)
        drop-shadow(0 0 6px rgba(242,199,91,.30))}
  96%  {filter:grayscale(1) brightness(1.18) saturate(1)
        drop-shadow(0 0 0 rgba(242,199,91,0))}
  100% {filter:grayscale(1) brightness(1.18) saturate(1)
        drop-shadow(0 0 0 rgba(242,199,91,0))}
}
/* the LOCKUP carries it, so the mark and the word light as one object */
.tl-gokait{animation:gokait-moment var(--trust-dur,30s) linear infinite;
  animation-delay:calc(var(--trust-dur,30s) * var(--gk-phase,-.045))}
/* slot 6 of 10 is half a sequence along, so half a cycle ahead. The duplicated
   sequence is one whole sequence along -- a full cycle -- so it needs nothing
   further, and every copy arrives white, lights at the centre and leaves
   white. */
.trust-seq li:nth-child(6) .tl-gokait{
  animation-delay:calc(var(--trust-dur,30s) * (var(--gk-phase,-.045) - .5))}
@media (prefers-reduced-motion:reduce){
  /* the calmer of the two options the brief allows: nothing moves and nothing
     is tinted, so Gokait simply sits in the family with its peers */
  .tl-gokait{animation:none;filter:grayscale(1) brightness(1.18)}
}
}

/* Reduced motion: the marquee STOPS -- it does not merely slow. The track stops
   being a strip and becomes a centred wrapping row, and every duplicate
   collapses so each mark is seen exactly once. */
@media (prefers-reduced-motion:reduce){
  .trust-track{animation:none;width:100%;justify-content:center;flex-wrap:wrap}
  .trust-seq[aria-hidden="true"]{display:none}
  /* the repeat groups exist only to keep the moving strip wider than the rail;
     with the animation off they would just be visible duplicates */
  .trust-seq .tg2,.trust-seq .tg3{display:none}
  .trust-seq{flex-wrap:wrap;justify-content:center}
  .trust-rail{-webkit-mask-image:none;mask-image:none}
}

/* Narrow screens keep the marks legible and simply show fewer at once -- which
   is what a marquee is for. Shrinking them to fit would defeat showing them. */
@media (max-width:760px){
  .trust{margin-top:22px;padding:16px 0 14px}
  .trust-h{font-size:10px;letter-spacing:.16em;margin-bottom:12px}
  .trust-seq li{padding:0 clamp(20px,6vw,34px)}
  .tl-tradingview{--lh:20px;--lw:158px}
  .tl-vantage    {--lh:22px;--lw:112px}
  .tl-mt5        {--lh:32px;--lw:38px}
  .tl-vtmarkets  {--lh:21px;--lw:130px}
  .tl-kait       {--lh:22px;--lw:24px}
}

/* ---------- accepted payment marks (inside the bottom strip) ----------
   One payment presentation on the page: a small translated label and the two
   settlement symbols, sitting in the strip where the status chips used to be.
   The assets are SYMBOL-ONLY derivatives (see logo-*-icon.png), so there is no
   wordmark to hide -- nothing here masks, clips or offsets artwork to conceal
   text, which is why the group survives any font, zoom or locale change.
   Both marks are circles of near-identical aspect, so one shared height gives
   them equal optical weight without per-asset fudging. Native brand colour is
   deliberately kept: these identify a payment rail, and a monochrome or gold
   coin would be a worse signal, not a more premium one. */
.sitem.paygrp{display:flex;align-items:center;gap:16px}
.pay-lbl{font-size:10.5px;font-weight:600;letter-spacing:.16em;text-transform:uppercase;
  color:var(--text-tertiary);white-space:nowrap}
.pay-marks{display:flex;align-items:center;gap:16px;list-style:none;margin:0;padding:0}
.pay-marks img{display:block;width:auto;height:var(--lh,22px);object-fit:contain;
  opacity:.92;transition:opacity .28s var(--ease)}
/* decorative only -- the marks are not links and must not read as clickable */
.pay-marks li:hover img{opacity:1}
.pm-usdt{--lh:22px}
.pm-usdc{--lh:22px}

@media (max-width:760px){
  .sitem.paygrp{gap:14px}
  .pay-lbl{font-size:9.5px;letter-spacing:.14em}
  .pay-marks{gap:14px}
  .pm-usdt,.pm-usdc{--lh:19px}
}

/* ---------- bottom strip: part of the scene ---------- */
.strip{border-top:1px solid rgba(37,43,53,.5);background:rgba(3,5,9,.5);
  backdrop-filter:blur(8px)}
.srow{display:flex;align-items:center;gap:16px;padding-top:11px;padding-bottom:11px;flex-wrap:wrap}
.sitem{display:inline-flex;align-items:center;gap:8px;font-size:12px;letter-spacing:.06em;
  color:var(--text-secondary);white-space:nowrap}
.sitem svg{width:14px;height:14px;stroke:var(--brand);fill:none;stroke-width:1.8;
  stroke-linecap:round;stroke-linejoin:round;flex:none;opacity:.85}
.sitem .on{color:var(--profit)}
.sitem .mut{color:var(--text-tertiary)}
.sep{width:1px;height:14px;background:var(--border-subtle);flex:none}
/* ---- BRAND-FLIGHT SIGNATURE --------------------------------------------
   A signature, not a banner. It inherits .sitem wholesale -- same 12px scale,
   same letter-spacing, same secondary colour as "XAUUSD Only" beside it -- so
   it reads as one more identity mark in the rail rather than an announcement.
   The only additions are the separator's weight and the date's tabular figures,
   which keep 06.06.2026 the same width in every locale's font stack. */
.tookflight{position:relative;gap:0;color:var(--brand);font-weight:600}
/* The GLOW is a pseudo-element, not a text-shadow: animating a shadow repaints
   the glyphs every frame, while animating one element's opacity stays on the
   compositor. It breathes over nine seconds -- slow enough to read as presence
   rather than as an advertisement asking for attention. */
.tookflight::before{content:"";position:absolute;inset:-7px -2px;
  pointer-events:none;border-radius:999px;
  background:radial-gradient(ellipse 68% 150% at 50% 50%,
    rgba(242,199,91,.15),transparent 72%);
  /* the halo is inset horizontally so an absolutely-positioned child cannot add
     scrollable overflow to the footer row (measured: 16px before this) */
  opacity:.36;animation:flight-breathe 9s ease-in-out infinite}
@keyframes flight-breathe{0%,100%{opacity:.30}50%{opacity:.74}}
.ff-sep{opacity:.5;padding:0 .5em;color:var(--brand)}
/* The date is the FACT: brighter than the phrase, tabular so it never reflows,
   and it keeps the site's body colour rather than the gold, so the eye lands on
   the words first and the date confirms them. */
.ff-date{font-variant-numeric:tabular-nums;letter-spacing:.03em;
  color:var(--text-primary,#eef1f5);font-weight:600}
@media (prefers-reduced-motion:reduce){
  .tookflight::before{animation:none;opacity:.42}
}
.sgrow{flex:1}
/* Closing brand line. Reuses the footer's own scale and the existing palette
   tokens: the wordmark takes the flat brand gold (NOT .gold-text, which is a
   gradient), the sentence takes the site's soft-white body colour. No box, no
   background, no glow, no animation — it is one line of footer text. */
.fbrand{margin:0;font-size:12px;line-height:1.5;letter-spacing:.02em;
  color:var(--text-primary);max-width:460px;text-align:end}
.fbrand .fb-mark{color:var(--brand);font-weight:600}

/* ---------- overlays ---------- */
.ovl{position:fixed;inset:0;z-index:50;display:flex;align-items:center;justify-content:center;
  padding:24px}
.ovl[hidden]{display:none}
.ovl-back{position:absolute;inset:0;background:rgba(0,0,0,.7);backdrop-filter:blur(4px)}
.ovl-card{position:relative;width:min(440px,100%);background:linear-gradient(180deg,var(--surface-1),#0B0F15);
  border:1px solid rgba(242,199,91,.28);border-radius:16px;padding:30px 32px;
  box-shadow:0 30px 80px rgba(0,0,0,.7),0 0 40px rgba(242,199,91,.05);
  animation:ovlin .35s var(--ease)}
.ovl-card h2{font-size:19px;font-weight:700;margin-bottom:12px;
  background:linear-gradient(180deg,var(--brand-hi),var(--brand) 55%,var(--brand-dark));
  -webkit-background-clip:text;background-clip:text;color:transparent}
.ovl-card p{font-size:14px;color:var(--text-secondary);margin-bottom:10px}
.ovl-close{margin-top:14px;background:none;border:1px solid var(--border-strong);
  color:var(--text-secondary);border-radius:8px;padding:8px 20px;font-size:13px;cursor:pointer;
  transition:color .25s var(--ease),border-color .25s var(--ease)}
.ovl-close:hover{color:var(--text-primary);border-color:var(--brand-dark)}
.ovl-close:focus-visible{outline:1px solid var(--brand);outline-offset:2px}

/* ---------- motion ---------- */
@keyframes rise{from{opacity:0;transform:translateY(12px)}to{opacity:1;transform:none}}
@keyframes winin{from{opacity:0;transform:translateY(24px)}to{opacity:1;transform:none}}
@keyframes breathe{0%,100%{opacity:.55}50%{opacity:1}}
@keyframes float{0%,100%{transform:translateY(0)}50%{transform:translateY(-4px)}}
@keyframes halo{0%,100%{opacity:.22;transform:scale(.82)}50%{opacity:.62;transform:scale(1.15)}}
@keyframes ovlin{from{opacity:0;transform:translateY(10px)}to{opacity:1;transform:none}}
.rv{opacity:0;animation:rise .7s var(--ease) forwards;animation-delay:var(--d,0s)}
.rv-win{opacity:0;animation:winin .9s var(--ease) forwards;animation-delay:.5s}

@media (prefers-reduced-motion:reduce){
  *,*::before,*::after{animation:none!important;transition:none!important}
  .rv,.rv-win{opacity:1}
  .tiltwrap{transform:none}
  .bg .pt{opacity:.25}
  .kite,.kite-in{transform:none}   /* kite static, no parallax */
}

/* ---------- responsive ---------- */
@media (max-height:940px) and (min-width:1081px){
  :root{--hdr:64px;--hero-pad:16px}
  h1{font-size:clamp(38px,4.2vw,58px)}
  .sub{margin-top:16px}
  .cta{margin-top:26px}
  .points{margin-top:24px}
  /* two info cards removed: row 1 = the two mini sparks, row 2 = the large chart */
  .cards{gap:11px;padding:14px;grid-template-rows:auto 168px minmax(280px,1fr)}
  .card{padding:14px 16px}
  .row{font-size:12.5px;padding:3px 0}
  .card h3{margin-bottom:8px}
  .topbar{min-height:44px}   /* floor, for the same reason as the base rule */
}
/* THE ONE WIDTH THE FIXED HEIGHT CANNOT HOLD.
   Below ~350px the market state has already wrapped to two lines on its own
   (that is pre-existing, and it is what the tracking step-down at 300px was
   written for), which leaves the second row too little room for a wrapped
   brand line. The header takes its height from its content there, with 50px as
   the FLOOR so nothing changes at any wider width. The ~6px it gains comes out
   of `.cards`, which is `flex:1` inside a panel of fixed height -- so the panel,
   the footer and the page height are all unchanged; only the chart is that much
   shorter on the narrowest phones.

   This is a viewport query rather than a container query on purpose: it is the
   CONTAINER's own height that has to give, and an element cannot answer its own
   container query. Below this width the panel is always the stacked mobile one,
   so the viewport is a sound proxy for it. */
/* Superseded 2026-09-04: the BASE .topbar rule now releases the height at every
   width, so this no longer has anything to relax. Kept verbatim as the record of
   why the height had to give -- and it must stay verbatim, because two polish
   contracts match this exact block. */
@media (max-width:355px){
  .topbar{height:auto;min-height:50px}
}
@media (max-width:1180px){
  .cols{grid-template-columns:.9fr 1.1fr;gap:32px}
  h1{font-size:clamp(34px,4.4vw,52px)}
  .minis{gap:14px}
}
@media (max-width:760px){
  :root{--hero-pad:34px}
  .cols{grid-template-columns:1fr;gap:38px;padding-bottom:40px}
  .hero{align-items:flex-start}
  h1{font-size:clamp(38px,11vw,48px)}
  .tiltwrap{transform:none}
  .window{animation:none;backdrop-filter:none;height:auto;
    background:linear-gradient(165deg,#0D111A,#080B11)}
  .stage::after{display:none}
  .cards{grid-template-columns:1fr;grid-template-rows:none}   /* mobile: cards size to content, no row floor */
  /* SHARED PERFORMANCE RANGE on a phone: the label may shrink and ellipsise,
     the pill never does -- it keeps its intrinsic width so no token is clipped
     and every target stays >=24px tall. If the two cannot share one line the
     label steps above the pill rather than squeezing it. */
  /* clear of the header divider above, and centred as a pair so the
     control reads as belonging to the two cards under it */
  /* Spacing only. ALIGNMENT is decided by the container query, never here: a
     viewport rule cannot see that the stage is 496px wide at a 600px viewport
     but 340px at 768px, and when both spoke at once the viewport rule won and
     the row stayed centred on a roomy tablet. */
  .prsel-row{flex-wrap:wrap;gap:6px;margin:2px 0 4px}
  /* centred, not pushed right: margin-left:auto pinned it to the end of
     the row and fought the row's own centring. */
  .prsel{flex:0 0 auto;min-width:max-content}
  .prbtn{padding:5px 11px;font-size:10px;min-height:28px}
  /* the echo keeps ONE type size at every width: 8.5px is the KlDxAu
     'Coming soon' mark's reserved size and the polish contract asserts
     that literal appears exactly once, so this rule adjusts spacing only. */
  .lotline-range{margin:-6px 0 9px}

  .card.chart{min-height:440px}    /* keep the primary chart tall when stacked */
  /* The strip fills its row (flex:1 == flex:1 1 0%), but a 0 basis needs a
     floor or it shrinks to nothing. It has none by default: a flex item gets
     a content-based automatic minimum size ONLY while its overflow is visible,
     and .tfsel sets overflow-x:auto for its scroll affordance -- which makes
     min-width:auto resolve to 0. So between roughly 422px and 570px, where the
     title claims the row and leaves a sliver, the control was squeezed to 9px
     (clientWidth 7, scrollWidth 139) and all three buttons scrolled out of
     view. Proven by toggling overflow-x:visible alone, which restored it.
     max-content restores exactly the floor the overflow removed: the strip may
     still grow to fill its row and still scroll, but it can never be shrunk
     below 1m/15m/1H. Intrinsic, so it survives any relabelling or locale. */
  /* content-sized, never grown. min-width:max-content is retained: it is
     the floor that overflow-x removed, and without it the strip could be
     squeezed below 1m/15m/1H. `flex:1` was the growth, and only that. */
  .tfsel{flex:0 0 auto;min-width:max-content}
  .bg .env{background-position:66% 70%;opacity:.5}
  /* kite -> open right-sky area below the header, fully on-screen, calmer.
     Its anchor and scale are contract values here too, so the reading block
     below can be placed from the same numbers instead of guessing at them. It
     steps down about a tenth from the old 31vw so the copy it now sits above
     does not have to start unreasonably far down the page. */
  /* clamped, not raw vh: an unusually tall phone viewport would otherwise
     push the artwork down the page and open a gap above it. */
  :root{--kite-top:clamp(52px,8.5vh,84px);--kite-size:clamp(104px,27vw,132px);
        --hero-breath:clamp(16px,2.6vh,28px)}
  .kite{left:auto;right:0}
  /* THE STACK GETS THE SAME TUCK AS THE DESKTOP COMPOSITION. Measured before
     this rule existed: the artwork's ink crossed the eyebrow by up to 93x39px
     and the heading by up to 93x63px, and its BODY -- not just the ribbon --
     sat on the eyebrow. There is no left/right to separate them in one column,
     so they are separated vertically, by the same measured ink line the two
     column layout uses. */
  .pitch{margin-top:max(0px,calc(var(--kite-top) + var(--kite-size) * var(--kite-ink)
                                 + var(--hero-breath) - var(--hdr) - var(--hero-pad)))}
  .kite-in{animation-name:kaitFloatSm}
  .bg .shade{background:
    linear-gradient(180deg,rgba(0,0,0,.82) 0%,rgba(0,0,0,.5) 34%,rgba(0,0,0,.34) 62%,rgba(0,0,0,.6) 100%)}
  /* the brand line takes the disclaimer's old wrapping behaviour: full width,
     start-aligned, so it never squeezes the footer nav or overflows */
  .fbrand{text-align:start;max-width:none}
  .srow{gap:10px}
  .sgrow{display:none}
}


/* ---- marquee: keep the compositor layer small on phones -------------------
   The third repeat group is what makes one sequence wider than a DESKTOP rail.
   A phone rail is ~287px wide and two groups already cover it three times
   over, so the group stands down below 760px. That is what takes the promoted
   layer from 4396 device px (over the 4096 mobile texture limit, where the
   rail froze after one pass) down to ~1099 CSS px / ~3298 device px at dpr 3.
   The period drops with it so the marks keep travelling at the same ~54px/s
   instead of the phone sprinting through a shorter track in the desktop
   period. */
@media (max-width:760px){
  .trust-seq .tg3{display:none}
  .trust-track{--trust-dur:14s}
  :root{--gk-phase:-.988}
}
@media (min-width:761px) and (max-width:1180px){
  .trust-track{--trust-dur:24s}
  :root{--gk-phase:-.974}
}

/* ---- the narrow tablet band: 761 to 860 ---------------------------------
   Between 761 and 860 the two summary cards are still SIDE BY SIDE inside a
   panel that has already given most of its width to the chart, and the head
   row -- name on one side, figure on the other -- runs out of room. Measured
   on live production at 768, in English and in Arabic alike: the pips figure
   overflowed its own card by 13px and 16px, so a canonical number was being
   visually truncated.
   Below 761 the cards stack one per row and there is no squeeze; above 860 the
   panel is wide enough. So the figure is allowed to take its own line, and only
   inside this band. Nothing about the value changes -- only where it sits. */
@media (min-width:761px) and (max-width:860px){
  .mthead{flex-wrap:wrap;gap:0 10px}
  .mtpips,.kxpips{font-size:15px}
}


/* ---- narrow phones: identical lockup treatment to the inner pages ---------
   site.css steps the shared-shell brand down at 420/340px. Without the same
   steps here the homepage wore a 24px word and a 34px mark while every other
   public page wore 18px/26px -- the same "one brand unit" reading differently
   depending on which page you landed on. */
@media (max-width:420px){
  :root{--hdr:58px;--gk-phase:-.944}
  .bar{gap:12px}
  .brandblk{gap:8px}
  .brandblk .mark{width:26px;height:26px}
  .brandblk .word{font-size:18px}
  .navtoggle{width:40px;height:40px}
}
@media (max-width:340px){
  .brandblk .word{font-size:16.5px}
}

/* ---------- LOT FLIGHT LINE ----------------------------------------------
   Lives in the existing band between the trust rail and the footer, on the
   same content column as .cards and .trust-rail, so it reads as part of the
   instrument stack rather than a new section. Gold is spent only on the
   filament and the anchors, at the same alphas .kxsoon already uses — the
   numbers themselves stay champagne/green so the row never becomes a yellow
   strip competing with the dashboard above it. */
/* ---- READABLE OVER THE CINEMATIC GROUND ----------------------------------
   MEASURED PROBLEM: this section sits over the bright part of the mountain
   artwork, but its type was coloured for a DARK panel -- #4f555e for the
   subtitle, #5A6069 for the lot labels, #6a7078 for the range echo. Dark grey
   on a lit background is exactly the combination that disappears.

   The fix is a SCRIM plus a contrast lift, not an opaque card. The scrim is a
   soft radial wash that fades to nothing well inside its own box, so there is
   no rectangle edge anywhere and the atmosphere still reads through it; the
   type then moves onto the shared tokens instead of bespoke greys. */
.lotline{position:relative;margin-top:14px;padding:12px 0 10px;isolation:isolate}
.lotline::before{content:"";position:absolute;inset:-6px -18px;z-index:-1;
  pointer-events:none;border-radius:22px;
  background:radial-gradient(120% 100% at 50% 50%,
    rgba(8,10,14,.62) 0%,rgba(8,10,14,.46) 52%,rgba(8,10,14,0) 88%)}

.lotline-h{text-align:center;margin:0 0 3px;font-size:10.5px;font-weight:700;
  letter-spacing:2.2px;text-transform:uppercase;color:var(--text-secondary)}
.lotline-sub{text-align:center;margin:0 0 11px;font-size:10.5px;letter-spacing:.3px;
  color:var(--text-tertiary)}
.lotline-track{position:relative}
/* the filament sits BEHIND the anchors, spanning the full row */
.lotline-thread{position:absolute;left:0;right:0;bottom:5px;width:100%;height:10px;
  pointer-events:none}
.lotline-nodes{position:relative;display:grid;grid-template-columns:repeat(5,1fr);
  gap:0;list-style:none;margin:0;padding:0 0 16px}
.lotline-nodes li{position:relative;display:flex;flex-direction:column;
  align-items:center;gap:2px;padding:0 4px;min-width:0}
/* the gold anchor each value hangs above */
.lotline-nodes li::after{content:"";position:absolute;bottom:-14px;left:50%;
  width:4px;height:4px;margin-left:-2px;background:rgba(242,199,91,.70);
  transform:rotate(45deg)}
.lotline-nodes li.mid::after{box-shadow:0 0 7px rgba(242,199,91,.20)}
/* THREE RANKS, read top to bottom: the SIZE names the row, the RESULT is the
   loudest thing on it, the GUIDANCE is quieter and visually detached so it
   cannot be mistaken for part of the P/L. */
.lot-size{font-size:9.5px;font-weight:700;letter-spacing:1.4px;text-transform:uppercase;
  color:var(--text-secondary);line-height:1;white-space:nowrap}
.lot-usd{font-size:14px;font-weight:600;line-height:1.15;letter-spacing:-.01em;
  font-variant-numeric:tabular-nums;white-space:nowrap;color:var(--text-primary)}
.lot-usd.pos{color:var(--profit)}
.lot-usd.neg{color:var(--loss)}
.lot-usd.mut{color:var(--text-tertiary)}
/* withheld / stale inherits the card's own semantics - never invents freshness */
.lotline[data-mtm="hold"] .lot-usd{opacity:.55}
.lotline[data-state="withheld"] .lot-usd{color:var(--text-tertiary)}

@media (max-width:1180px){
  .lot-usd{font-size:13px}
}
@media (max-width:760px){
  .lotline{margin-top:12px}
  .lotline-h{font-size:9.5px;letter-spacing:1.8px}
  .lotline-sub{font-size:9px;margin-bottom:9px}
  .lotline-nodes{padding-bottom:14px}
  .lotline-nodes li{padding:0 2px}
  .lot-size{font-size:8px;letter-spacing:1px}
  .lot-usd{font-size:11px}
  .lotline-nodes li::after{bottom:-12px}
}
@media (max-width:420px){
  .lot-usd{font-size:10px}
  .lot-size{font-size:7.5px;letter-spacing:.7px}
}
@media (prefers-reduced-motion:reduce){
  .lotline-thread{opacity:.9}
}
