/* Home-page journey (journey.js): one fixed WebGL2 world behind the page. Every rule that changes the
   page is scoped under html.journey-on, which app.js sets only while a journey exists, so without it the
   site is unchanged. Immersive sections become windows onto the world with their text on glass; paper
   stays opaque. Only the journey's own elements (the stage and its labels) are styled unscoped: they
   exist only while a journey does, and must never fall into the page flow, even for a frame. */

/* ---- the stage: always behind every piece of content ---- */
.journey { position: fixed; top: 0; left: 0; width: 100%; height: 100vh; height: 100lvh; z-index: -1; pointer-events: none; overflow: hidden; contain: strict;
  background:
    radial-gradient(120% 80% at 50% 118%, rgba(28, 64, 60, .38), transparent 62%),
    radial-gradient(70% 55% at 12% 8%, rgba(22, 46, 50, .32), transparent 70%),
    linear-gradient(180deg, #071114 0%, #050b0d 55%, #04090b 100%); }
.journey[hidden] { display: none; }
/* A very faint grain and vignette so the dark gradients never band. */
.journey::after { content: ''; position: absolute; inset: 0; pointer-events: none; opacity: .5;
  background:
    radial-gradient(130% 100% at 50% 45%, transparent 58%, rgba(0, 0, 0, .38) 100%),
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='160' height='160'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.9' numOctaves='2' stitchTiles='stitch'/%3E%3CfeColorMatrix values='0 0 0 0 .6 0 0 0 0 .7 0 0 0 0 .68 0 0 0 .05 0'/%3E%3C/filter%3E%3Crect width='160' height='160' filter='url(%23n)'/%3E%3C/svg%3E"); }
.journey-canvas { position: absolute; inset: 0; width: 100%; height: 100%; display: block; }
.journey-labels { position: absolute; inset: 0; overflow: hidden; z-index: 1; }

/* ---- labels that follow the world (aria-hidden; moved with transforms only) ---- */
.journey-label { position: absolute; top: 0; left: 0; width: 0; height: 0; visibility: hidden; opacity: 0; will-change: transform, opacity; }
.journey-label-pill { position: absolute; bottom: 12px; left: 0; transform: translateX(-50%); display: flex; align-items: center; gap: 7px; padding: 3px 11px 4px; border-radius: 999px; white-space: nowrap;
  font-size: 12px; line-height: 1.5; color: #dfe8e4; background: rgba(5, 11, 13, .78); border: 1px solid rgba(210, 234, 229, .16); box-shadow: 0 6px 18px -8px rgba(0, 0, 0, .8); }
.journey-label-pill::after { content: ''; position: absolute; left: 50%; top: 100%; width: 1px; height: 9px; background: linear-gradient(rgba(210, 234, 229, .45), transparent); }
.journey-label-state { font-size: 11px; color: #a9b8ba; }
.journey-label[data-state="open"] .journey-label-state { color: var(--lime); }
/* A session pill is one sentence ("The Asia market is open now"); an open market reads in lime. */
.journey-label[data-kind="session"][data-state="open"] .journey-label-name { color: var(--lime); }
.journey-label[data-state="open"] .journey-label-pill { border-color: rgba(181, 228, 135, .36); }
.journey-label.is-focus .journey-label-pill { border-color: var(--lime); color: #fff; }
/* The offices beacon and the office labels lead to the offices section (journey.js matches the click by position). */
html.journey-pointer, html.journey-pointer body { cursor: pointer; }
.journey-label.is-hover .journey-label-pill { border-color: var(--lime); color: #fff; background: rgba(181, 228, 135, .14); }
.journey-label[data-kind="home"] .journey-label-pill, .journey-label[data-kind="office"] .journey-label-pill { color: #eef6e4; border-color: rgba(181, 228, 135, .42); }
.journey-label[data-kind="home"] .journey-label-pill::before, .journey-label[data-kind="office"] .journey-label-pill::before { content: ''; width: 6px; height: 6px; border-radius: 50%; background: var(--lime); }
.journey-label-count { min-width: 18px; padding: 0 5px; border-radius: 9px; font-size: 11px; line-height: 18px; text-align: center; color: var(--ink); background: var(--lime); }
.journey-label[data-kind="ingot"] .journey-label-pill { bottom: auto; top: 6px; flex-direction: column; gap: 0; padding: 4px 12px 5px; border-radius: 12px; color: #b4c0c0; text-align: center; }
.journey-label[data-kind="ingot"] .journey-label-pill::after { display: none; }
.journey-label[data-kind="ingot"] .journey-label-spec { font-size: 11px; opacity: .9; }
.journey-label[data-kind="ingot"].is-fit .journey-label-pill { color: #f3dfc6; border-color: rgba(240, 190, 140, .34); }
/* Selection is white, as in the forge itself: lime would read as "fits" on an account that does not. */
.journey-label[data-kind="ingot"].is-selected .journey-label-pill { color: #fff; border-color: rgba(241, 243, 238, .55); }
.journey-label[data-kind="event"] .journey-label-pill { font-size: 11.5px; color: #e8d2cb; border-color: rgba(224, 122, 106, .35); }
/* Arabic-script pills keep the site's 12 px floor, the smaller state and event text included. */
html[dir=rtl] .journey-label-pill { font-size: 12.5px; }
html[dir=rtl] :is(.journey-label-state, .journey-label[data-kind="event"] .journey-label-pill) { font-size: 12px; }

/* ---- the page over the world ---- */
html.journey-on {
  --journey-glass: rgba(6, 12, 14, .74);
  --journey-glass-strong: rgba(6, 12, 14, .86);
  --journey-hairline: rgba(210, 234, 229, .13);
  --journey-blur: blur(16px) saturate(1.12);
  background: #050b0d;
}
/* Slower devices skip the backdrop blur (it re-blurs every panel on every frame of a moving canvas);
   their glass is a little more opaque instead. Phones get the same below (max-width: 700px). */
html.journey-on:is(.journey-tier-low, .journey-tier-mid) { --journey-blur: none; --journey-glass: rgba(6, 12, 14, .9); }
html.journey-on:is(.journey-tier-low, .journey-tier-mid) .globe-section .globe-panel { -webkit-backdrop-filter: none; backdrop-filter: none; background: rgba(9, 15, 18, .9); }
/* The canvas is transparent: the night sky is the stage's own background, so the body lets it through. */
html.journey-on body { background: transparent; }
html.journey-on #content, html.journey-on .site-footer { position: relative; z-index: 1; }
html.journey-on .site-footer { background: #060c0e; border-top: 1px solid var(--journey-hairline); }
html.journey-on .market-strip { position: relative; z-index: 1; background: #081013; }
html.journey-on .final-cta { position: relative; z-index: 1; }

/* Windows: empty stretches before a section's content where the world shows through. Only the ones
   with a subject of their own (the canyon, the relief, the sunrise) are tall; the rest stay short so
   the page is not much longer than the classic one. */
html.journey-on .journey-window { --journey-window: 52vh; position: relative; display: flex; align-items: flex-end; height: var(--journey-window); pointer-events: none; }
html.journey-on [data-site-section="approach"] > .journey-window { --journey-window: 38vh; }
html.journey-on [data-site-section="sessions"] > .journey-window { --journey-window: 0px; }
html.journey-on [data-site-section="platform"] > .journey-window { --journey-window: 76px; } /* just its caption: the canyon shows beside the copy */
html.journey-on [data-site-section="simulator"] > .journey-window { --journey-window: 24vh; }
html.journey-on [data-site-section="steps"] > .journey-window { --journey-window: 56vh; }
html.journey-on [data-site-section="faq"] > .journey-window { --journey-window: 0px; }
html.journey-on [data-site-section="offices"] > .journey-window { --journey-window: 46vh; }
html.journey-on [data-site-section="cta"] > .journey-window { --journey-window: 50vh; }

/* Honest captions at the foot of a window: what the world shows, in the page's own type. A caption
   (and the Listen button beside it) waits, hidden, until the world it describes is really drawn. */
html.journey-on .journey-caption { pointer-events: auto; width: min(calc(100% - 112px), var(--max)); margin-inline: auto; margin-block-end: 22px; display: flex; flex-wrap: wrap; align-items: center; gap: 10px 14px; transition: opacity .3s ease; }
/* Waiting: faded out but still read by screen readers, and shown again if keyboard focus reaches it. */
html.journey-on .journey-window.is-waiting .journey-caption { opacity: 0; pointer-events: none; }
html.journey-on .journey-window.is-waiting .journey-caption:focus-within { opacity: 1; pointer-events: auto; }
/* Unavailable: the scene it describes can never draw (it failed), so the caption and Listen are gone. */
html.journey-on .journey-window.is-unavailable .journey-caption { display: none; }
/* The relief's framing is the same in every language and its south-west corner is open plain, so its
   caption sits at the physical left in right-to-left layouts too (inline-start would cover Kalar). */
html.journey-on[dir=rtl] .journey-caption[data-caption="relief"] { justify-content: flex-end; }
/* The platform station's canyon is framed the same way too, with its price peak and shock labels above the
   middle of the page: its caption row (and Listen) keeps the physical left as in English, clear of them. */
html.journey-on[dir=rtl] [data-site-section="platform"] > .journey-window .journey-caption { justify-content: flex-end; }
html.journey-on .journey-caption-text { margin: 0; display: inline-flex; align-items: center; gap: 10px; padding: 7px 14px; border-radius: 999px; font-size: 12px; line-height: 1.6; color: #c9d6d2;
  background: var(--journey-glass); border: 1px solid var(--journey-hairline); -webkit-backdrop-filter: var(--journey-blur); backdrop-filter: var(--journey-blur); }
html.journey-on .journey-caption-mark { display: none; }
html.journey-on .journey-caption-text::before { content: ''; flex: none; width: 7px; height: 7px; border-radius: 2px; transform: rotate(45deg); border: 1px solid #9eaeb0; }
html.journey-on .journey-caption:is([data-caption="relief"], [data-caption="sunrise"]) .journey-caption-text::before { border-radius: 50%; transform: none; border-color: var(--lime); }
/* Listen: dark glass with a lime edge, so its label keeps AA contrast over the brightest candles. */
html.journey-on .journey-listen { display: inline-flex; align-items: center; gap: 8px; min-height: 36px; padding-block: 6px; padding-inline: 13px 16px; border-radius: 999px; cursor: pointer; font: inherit; font-size: 12.5px; color: var(--text);
  background: rgba(6, 12, 14, .78); border: 1px solid rgba(181, 228, 135, .5); -webkit-backdrop-filter: var(--journey-blur); backdrop-filter: var(--journey-blur); transition: background-color .25s ease, border-color .25s ease; }
html.journey-on .journey-listen:hover { background: rgba(18, 32, 27, .88); border-color: rgba(181, 228, 135, .72); }
html.journey-on .journey-listen:focus-visible { outline: 2px solid var(--lime); outline-offset: 3px; }
html.journey-on .journey-listen .icon { width: 17px; height: 17px; fill: none; stroke: currentColor; stroke-width: 1.7; stroke-linecap: round; stroke-linejoin: round; }
html.journey-on .journey-listen[data-playing="true"] { background: var(--lime); color: var(--ink); border-color: transparent; }
html.journey-on .journey-listen[data-playing="true"] .icon { fill: currentColor; stroke: none; }
html.journey-on .journey-listen-note { font-size: 12px; color: #e3c3ba; }
html.journey-on .journey-listen-note:empty { display: none; }

/* Glass panels wherever text sits over the world (the sessions board brings its own). */
html.journey-on :is(
  #approach .section-head, #approach .approach-item,
  #steps .section-head, #steps .start-item,
  #offices .section-head, #offices .office,
  #simulator .section-head,
  #faq .faq-layout,
  .platform-copy,
  .forge-head
) {
  background: var(--journey-glass); border: 1px solid var(--journey-hairline); border-radius: 20px;
  -webkit-backdrop-filter: var(--journey-blur); backdrop-filter: var(--journey-blur);
  box-shadow: 0 30px 70px -42px rgba(0, 0, 0, .75);
}
html.journey-on :is(#approach, #steps, #offices, #simulator) .section-head { padding: 30px 34px; margin-bottom: 18px; }
html.journey-on :is(#approach .approach-item, #steps .start-item, #offices .office) { padding: 26px 28px 28px; border-top-color: var(--journey-hairline); }
html.journey-on :is(.approach-grid, .start-grid, .offices-grid) { gap: 16px; }
html.journey-on #faq .faq-layout { padding: 34px 38px; }
html.journey-on .platform-copy { padding: 34px 36px; }
html.journey-on .platform-section { background: none; }
/* The canyon is the platform chapter's picture: the interface mock-up (a second chart with its own
   line) would compete with it and blur the line between an illustration and synthetic prices. */
html.journey-on:not(.journey-failed) .platform-art { display: none; }
html.journey-on:not(.journey-failed) .platform-layout { grid-template-columns: minmax(0, 620px); justify-content: end; min-height: 0; }
html.journey-on .sim-teaser { display: grid; justify-items: start; gap: 0; }
/* Same for the simulator teaser: the canyon's low pass is its picture, so the small preview chart goes. */
html.journey-on:not(.journey-failed) .sim-preview { display: none; }
html.journey-on #simulator .section-head { margin-bottom: 18px; width: 100%; box-sizing: border-box; }
html.journey-on .forge-head { padding: 28px 32px; }
html.journey-on .forge :is(.forge-metal-note, .forge-specs-note) { width: fit-content; max-width: 100%; margin-inline: auto; padding: 8px 16px; border-radius: 14px; background: var(--journey-glass); border: 1px solid var(--journey-hairline); -webkit-backdrop-filter: var(--journey-blur); backdrop-filter: var(--journey-blur); }
html.journey-on .forge .forge-specs-note { margin-inline: 0; }
/* The vault's front-row names hang just under the window: the note keeps clear of them. */
html.journey-on .forge .forge-metal-note { margin-top: 44px; }
html.journey-on .forge :is(.forge-results, .forge-summary-row) { position: relative; }
html.journey-on .forge .forge-summary-row { padding: 14px 20px; border-radius: 16px; background: var(--journey-glass); border: 1px solid var(--journey-hairline); -webkit-backdrop-filter: var(--journey-blur); backdrop-filter: var(--journey-blur); }
html.journey-on .forge .forge-list-wrap { padding: 22px; border-radius: 20px; background: var(--journey-glass-strong); border: 1px solid var(--journey-hairline); }
html.journey-on .forge .forge-detail.is-empty { background: var(--journey-glass-strong); }

/* ---- hero: the Earth replaces the old sculpture; the darkening stays only behind the text ---- */
html.journey-on .hero { background: none; }
html.journey-on .hero #hero-scene, html.journey-on .hero .hero-art-label { display: none; }
/* The classic page's still drawing (shown when its sculpture does not run) has no place over the Earth;
   this outranks style.css's .hero:not(.scene-wanted) .hero-still rule. */
html.journey-on .hero:is(.scene-wanted, :not(.scene-wanted)) .hero-still { display: none; }
/* The bottom row (small type) moves over the lit Earth once the page scrolls: a deeper floor of shade
   and lighter type keep it at AA. */
html.journey-on .hero::after { background: linear-gradient(90deg, transparent 38%, rgba(5, 11, 13, .42) 55%, rgba(5, 11, 13, .82) 78%), linear-gradient(0deg, rgba(5, 11, 13, .9) 0, rgba(5, 11, 13, .6) 12%, transparent 26%); }
html.journey-on .hero-bottom { z-index: 2; }
html.journey-on :is(.hero-scroll, .motion-control, .hero-signals span) { color: #b6c4c0; }

/* The live line: Baghdad time and the sessions, computed on the device. */
html.journey-on .journey-live { margin-top: 30px; display: grid; gap: 6px; max-width: 540px; }
/* It fills the room the hero kept for it (style.css .hero-live-slot: 30 px of margin and three rows, four at
   701-760 px, at every width above phones), so the centred hero text stays put when the line takes fewer rows;
   its rows stay at the top. */
html.journey-on .hero .hero-content > .journey-live { min-height: 98px; align-content: start; }
html.journey-on .journey-live-line { margin: 0; display: flex; flex-wrap: wrap; align-items: baseline; gap: 4px 14px; font-size: 13px; line-height: 1.7; color: #dbe5e1; }
/* A wrapped status (or caption, on phones) never leaves one word alone on its last row. */
html.journey-on :is(.journey-live-status, .journey-live-caption) { text-wrap: pretty; }
html.journey-on .journey-live-now { display: inline-flex; align-items: baseline; gap: 7px; color: #b9c8c4; }
/* The larger time keeps the row's own height (line-height 1), so every row of the line is the same size and
   three rows still fit the hero's slot. */
html.journey-on .journey-live-now strong { font-size: 15px; font-weight: 500; line-height: 1; color: var(--lime); letter-spacing: .01em; }
html.journey-on .journey-live-dot { align-self: center; flex: none; width: 7px; height: 7px; border-radius: 50%; background: var(--lime); box-shadow: 0 0 0 3px rgba(181, 228, 135, .14); }
html.journey-on .journey-live[data-paused="true"] .journey-live-dot { background: #9eaeb0; box-shadow: none; }
html.journey-on .journey-live-caption { margin: 0; font-size: 11.5px; line-height: 1.7; color: #a6b8b4; }
html.journey-on[dir=rtl] .journey-live-line { font-size: 13px; }
html.journey-on[dir=rtl] .journey-live-caption { font-size: 12px; }

/* ---- the 3D stage stopped for good: nothing may still frame an empty world ---- */
html.journey-on.journey-failed :is(.journey-window, .forge-window, .journey-live) { display: none; }
html.journey-on.journey-failed .hero { background: radial-gradient(ellipse at 23% 65%, #153e3d80, transparent 55%), linear-gradient(120deg, #0c181e, #0b1519 50%, #0a1114); }
/* ...and the hero gets its still drawing back (this outranks the hiding rule above), as it does while a
   lost WebGL context may still come back (journey.js gives up after a few seconds). */
html.journey-on:is(.journey-failed, .journey-lost) .hero:is(.scene-wanted, :not(.scene-wanted)) .hero-still { display: block; }

/* ---- small screens ---- */
@media (max-width: 1000px) {
  html.journey-on .hero::after { background: linear-gradient(90deg, transparent 30%, rgba(5, 11, 13, .5) 50%, rgba(5, 11, 13, .85) 74%), linear-gradient(0deg, rgba(5, 11, 13, .9) 0, rgba(5, 11, 13, .6) 12%, transparent 26%); }
}
/* The fourth row the slot keeps at these widths (the 700 px block below takes the slot away again). */
@media (max-width: 760px) { html.journey-on .hero .hero-content > .journey-live { min-height: 118px; } }
@media (max-width: 700px) {
  html.journey-on { --journey-blur: none; --journey-glass: rgba(6, 12, 14, .9); }
  html.journey-on .globe-section .globe-panel { -webkit-backdrop-filter: none; backdrop-filter: none; background: rgba(9, 15, 18, .9); }
  html.journey-on [data-site-section="approach"] > .journey-window { --journey-window: 32vh; }
  html.journey-on [data-site-section="sessions"] > .journey-window { --journey-window: 34vh; }
  html.journey-on [data-site-section="platform"] > .journey-window { --journey-window: 24vh; }
  html.journey-on [data-site-section="simulator"] > .journey-window { --journey-window: 24vh; }
  html.journey-on [data-site-section="steps"] > .journey-window { --journey-window: 44vh; }
  html.journey-on [data-site-section="faq"] > .journey-window { --journey-window: 0px; }
  html.journey-on [data-site-section="offices"] > .journey-window { --journey-window: 38vh; }
  html.journey-on [data-site-section="cta"] > .journey-window { --journey-window: 44vh; }
  html.journey-on .journey-caption { width: calc(100% - 40px); margin-block-end: 14px; gap: 8px; }
  /* Phones put the canyon's labels above the caption row, so it keeps the reading side here. */
  html.journey-on[dir=rtl] [data-site-section="platform"] > .journey-window .journey-caption { justify-content: normal; }
  html.journey-on .journey-caption-text { font-size: 11px; padding: 6px 12px; }
  html.journey-on[dir=rtl] .journey-caption-text { font-size: 12px; }
  html.journey-on :is(#approach, #steps, #offices, #simulator) .section-head { padding: 22px 20px; }
  html.journey-on :is(#approach .approach-item, #steps .start-item, #offices .office) { padding: 20px 18px 22px; }
  html.journey-on :is(#faq .faq-layout, .platform-copy) { padding: 24px 20px; }
  html.journey-on .forge-head { padding: 22px 20px; }
  html.journey-on .forge .forge-list-wrap { padding: 16px; }
  /* The tall framing stacks the vault in three rows: give it the height to show every bar's name, and
     keep the note under the window far enough below the front row for that row's labels. */
  html.journey-on .forge-window { height: clamp(320px, 88vw, 460px); }
  html.journey-on .forge .forge-metal-note { margin-top: 52px; }
  /* Text runs the full width up top and the Earth rises below it: darken only behind the text. */
  html.journey-on .hero::after { background: linear-gradient(180deg, rgba(5, 11, 13, .55) 0%, rgba(5, 11, 13, .3) 44%, transparent 60%), linear-gradient(0deg, rgba(5, 11, 13, .9) 0, rgba(5, 11, 13, .6) 9%, transparent 19%); }
  /* Here the Earth rises right under the text, so the risk line and the live line get their own glass
     (the risk warning must stay readable over any frame). */
  html.journey-on .journey-live { margin-top: 12px; padding: 12px 14px; border-radius: 14px; background: var(--journey-glass); border: 1px solid var(--journey-hairline); -webkit-backdrop-filter: var(--journey-blur); backdrop-filter: var(--journey-blur); }
  html.journey-on .hero .hero-content > .journey-live { min-height: 0; } /* no slot here: the line arrives under the text */
  html.journey-on .hero .hero-content > .risk-short { margin-top: 18px; padding: 10px 14px; border-radius: 14px; color: #c3d0cc; background: var(--journey-glass); border: 1px solid var(--journey-hairline); }
  html.journey-on .journey-live-line { font-size: 12px; gap: 2px 12px; }
  .journey-label-pill { font-size: 11px; padding: 2px 9px 3px; }
}

@media (prefers-reduced-motion: reduce) {
  html.journey-on :is(.journey-listen, .journey-caption) { transition: none; }
}
