/* ═══════════════════════════════════════════════════════════════════════════════
   TRADEFINANCEAI — PLATFORM EXPERIENCE LAYER
   Public homepage (signed out) + Customer workspace (signed in)

   WHY THIS IS A NEW FILE AND NOT AN EDIT TO index.html's STYLESHEET
   ----------------------------------------------------------------
   `index.html`'s `<style>` block is a completed module (Rule 2). This layer is
   additive: every selector below is either brand new (`.tfa-*`, `#TFA_*`) or one
   of the FOUR documented layout overrides in the LAYOUT section — the same move
   `#TFS_STYLE` made when the product portal was added. Deleting this file and the
   three lines that reference it in `index.html` restores the previous interface
   exactly, which is the test this layer is designed to pass.

   WHY THE TOKENS ARE SCOPED TO #TFA_HOME
   --------------------------------------
   `index.html` declares `--c-*` on `:root`; `mdp/assets/css/tokens.css` declares
   `--mdp-*`. A third set on `:root` would be a third global namespace to collide
   with. `--tfa-*` is declared ON the container instead, so it cannot reach any
   existing rule even if a future phase loads all three documents together. The
   VALUES are deliberately the platform's existing palette (#08090D, #D4A832,
   #F2EFE8) so the homepage, the workspace and Match Deal Pro read as one product
   — brand consistency without editing either frozen token set.

   RESTRAINT IS A RULE HERE, NOT A PREFERENCE
   ------------------------------------------
   Gold is an accent: eyebrows, one clause of the headline, the single primary
   action per surface, thin rules, icon strokes, focus. Surfaces are graphite.
   Status colour appears only where a status exists. There are no glows, no
   oversized radii and no animation that carries meaning — every transition is
   ≤220ms and every one of them is switched off under `prefers-reduced-motion`.
   ═══════════════════════════════════════════════════════════════════════════════ */

/* ───────────────────────────────────────────────────────────────────────────────
   LAYOUT — THE ONLY FOUR RULES IN THIS FILE THAT ADDRESS AN EXISTING SELECTOR

   `#APP` was `height:100vh; overflow:hidden`, sized so the AI Assistant filled the
   first viewport exactly and the page below it scrolled as siblings. The new home
   lives INSIDE `#APP`, between `#TB` and `#CONTENT`, because that is the only
   position that keeps the reading order and the tab order identical to the visual
   order — a sibling before `#APP` would put the header after the hero in the tab
   sequence, which is an accessibility regression no styling can undo.

   So `#APP` has to grow, `#TB` has to stick, and `#CONTENT` has to keep a DEFINITE
   height. That last one matters more than it looks: `#MSGS` is `flex:1;
   overflow-y:auto` inside `#CONTENT`, and an internal scroller only scrolls
   internally when its parent is definitely sized. Give `#CONTENT` a min-height
   instead and a long conversation would push the composer off the bottom of the
   document. `calc()` off the two chrome heights preserves today's behaviour
   byte-for-byte.
   ─────────────────────────────────────────────────────────────────────────────── */
/* The two chrome heights, as variables, because BOTH of them already change at the
   existing breakpoints: `#TB` is 62px / 56px (≤768) / 52px (≤480), and `#FOOT` is
   hidden entirely at ≤480px and at short viewports. A single hard-coded calc would
   be wrong at three widths. These are the only two custom properties this layer
   declares outside `#TFA_HOME`, they are prefixed, and the mobile nav panel reads
   the same header height so the two can never drift apart. */
html { --tfa-nav-h: 62px; --tfa-foot-h: 48px; }
@media (max-width: 768px)  { html { --tfa-nav-h: 56px; } }
@media (max-width: 480px)  { html { --tfa-nav-h: 52px; --tfa-foot-h: 0px; } }
@media (max-height: 660px) { html { --tfa-foot-h: 0px; } }

#APP { height: auto; min-height: 100vh; overflow: visible; }
/* z-index 30, and this one is not cosmetic. `#APP` was 10 and `#TFS` — the product
   portal below it — is 20, which was correct while `#APP` was exactly one viewport
   tall and the two could never overlap. A STICKY header can overlap anything the
   page scrolls past, so at 10 the header would slide behind the product portal and
   vanish. `#APP` has to sit above its own siblings for the header to survive the
   scroll. Nothing else in `#APP` overlaps `#TFS` geometrically, and every overlay in
   the document is far above both (`#MD` 150, `.px-ov` 400, the tour 9400, the boot
   overlay 9999) so all four still cover the header exactly as before. */
#APP { z-index: 30; }
#TB  { position: sticky; top: 0; }
#CONTENT { flex: 0 0 auto; height: calc(100vh - var(--tfa-nav-h) - var(--tfa-foot-h)); }
/* `dvh` where it exists, so the assistant is exactly one usable viewport on a phone
   with a retracting browser bar. `vh` above stays as the fallback. */
@supports (height: 100dvh) {
  #CONTENT { height: calc(100dvh - var(--tfa-nav-h) - var(--tfa-foot-h)); }
}

/* ═══════════════════════════════════════════════════════════════════════════════
   TOKENS
   ═══════════════════════════════════════════════════════════════════════════════ */
#TFA_HOME {
  --tfa-max: 1340px;
  --tfa-gut: clamp(20px, 4vw, 44px);

  --tfa-bg: #08090D;
  --tfa-bg-2: #0A0C11;
  --tfa-surface: rgba(17, 20, 26, .74);
  --tfa-surface-2: rgba(23, 27, 34, .80);
  --tfa-surface-3: rgba(30, 35, 44, .70);
  --tfa-inset: rgba(255, 255, 255, .028);

  --tfa-bd: rgba(255, 255, 255, .075);
  --tfa-bd-2: rgba(255, 255, 255, .13);

  --tfa-gold: #D4A832;
  --tfa-gold-2: #F0CC5A;
  --tfa-gold-soft: rgba(212, 168, 50, .11);
  --tfa-gold-bd: rgba(212, 168, 50, .32);

  --tfa-text: #F2EFE8;
  --tfa-text-2: rgba(242, 239, 232, .66);
  --tfa-text-3: rgba(242, 239, 232, .44);

  --tfa-ok: #4ADE80;
  --tfa-warn: #FBBF24;
  --tfa-risk: #F87171;
  --tfa-info: #6C9BFF;
  --tfa-teal: #2DD4BF;

  --tfa-r-xs: 6px;
  --tfa-r-sm: 9px;
  --tfa-r: 13px;
  --tfa-r-lg: 17px;
  --tfa-r-pill: 999px;

  --tfa-mono: 'JetBrains Mono', ui-monospace, 'SF Mono', Menlo, monospace;
  --tfa-dur: 190ms;
  --tfa-ease: cubic-bezier(.16, 1, .3, 1);

  position: relative;
  z-index: 1;
  flex: 0 0 auto;
  /* A hard stop on horizontal overflow. `clip` rather than `hidden` so a sticky
     header outside this container is not turned into a scroll container. */
  max-width: 100%;
  overflow-x: clip;
  color: var(--tfa-text);
}
#TFA_HOME *, #TFA_HOME *::before, #TFA_HOME *::after { box-sizing: border-box; }

.tfa-wrap { max-width: var(--tfa-max); margin: 0 auto; padding: 0 var(--tfa-gut); width: 100%; }

/* ═══════════════════════════════════════════════════════════════════════════════
   PRIMITIVES
   ═══════════════════════════════════════════════════════════════════════════════ */
.tfa-eyebrow {
  margin: 0 0 16px; font-size: 10.5px; font-weight: 700; letter-spacing: .19em;
  text-transform: uppercase; color: var(--tfa-gold); font-family: var(--tfa-mono);
  display: flex; align-items: center; gap: 10px;
}
.tfa-eyebrow::before {
  content: ''; width: 22px; height: 1px; flex: 0 0 auto;
  background: linear-gradient(90deg, transparent, var(--tfa-gold));
}
.tfa-h1 {
  margin: 0 0 20px; font-weight: 800; letter-spacing: -.028em; line-height: 1.06;
  font-size: clamp(30px, 4.6vw, 60px); color: #FFF;
}
.tfa-h1 span { color: var(--tfa-gold-2); }
.tfa-h2 {
  margin: 0 0 12px; font-weight: 750; letter-spacing: -.022em; line-height: 1.14;
  font-size: clamp(23px, 2.9vw, 36px); color: #FFF;
}
.tfa-lede {
  margin: 0 0 30px; font-size: clamp(14px, 1.15vw, 16.5px); line-height: 1.66;
  color: var(--tfa-text-2); max-width: 56ch;
}
.tfa-sub { margin: 0; font-size: 14px; line-height: 1.62; color: var(--tfa-text-2); max-width: 62ch; }

/* Section label — the small uppercase caption that names an operational panel. */
.tfa-cap {
  font-family: var(--tfa-mono); font-size: 9.5px; font-weight: 700; letter-spacing: .17em;
  text-transform: uppercase; color: var(--tfa-text-3);
}

/* ── Buttons ─────────────────────────────────────────────────────────────────── */
.tfa-btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 9px;
  min-height: 44px; padding: 0 22px; border-radius: var(--tfa-r-sm);
  font: inherit; font-size: 13.5px; font-weight: 650; letter-spacing: -.005em;
  text-decoration: none; cursor: pointer; white-space: nowrap;
  border: 1px solid var(--tfa-gold); background: var(--tfa-gold); color: #17120A;
  transition: background var(--tfa-dur) var(--tfa-ease), border-color var(--tfa-dur) var(--tfa-ease),
              color var(--tfa-dur) var(--tfa-ease), transform var(--tfa-dur) var(--tfa-ease);
}
.tfa-btn:hover { background: var(--tfa-gold-2); border-color: var(--tfa-gold-2); }
.tfa-btn:active { transform: translateY(1px); }
.tfa-btn.ghost { background: transparent; border-color: var(--tfa-bd-2); color: var(--tfa-text); }
.tfa-btn.ghost:hover { border-color: var(--tfa-gold-bd); color: #FFF; background: var(--tfa-gold-soft); }
.tfa-btn.sm { min-height: 34px; padding: 0 13px; font-size: 12px; border-radius: var(--tfa-r-xs); }
.tfa-btn svg { flex: 0 0 auto; }

/* A quiet text action — "View all →". Kept a real link/button, never a decorated span. */
.tfa-link {
  display: inline-flex; align-items: center; gap: 6px; padding: 6px 2px;
  font: inherit; font-size: 12px; font-weight: 600; color: var(--tfa-gold);
  background: none; border: 0; cursor: pointer; text-decoration: none;
  transition: color var(--tfa-dur) var(--tfa-ease), gap var(--tfa-dur) var(--tfa-ease);
}
.tfa-link:hover { color: var(--tfa-gold-2); gap: 9px; }

/* ── Focus. One ring, everywhere, from a token — including inside the header. ── */
#TFA_HOME :focus-visible, .tfa-nav :focus-visible, .tfa-navtog:focus-visible {
  outline: 2px solid var(--tfa-gold-2, #F0CC5A); outline-offset: 2px; border-radius: 4px;
}
#TFA_HOME [aria-disabled='true'] { opacity: .45; cursor: not-allowed; pointer-events: none; }

/* ── Panels ──────────────────────────────────────────────────────────────────── */
.tfa-panel {
  background: var(--tfa-surface); border: 1px solid var(--tfa-bd);
  border-radius: var(--tfa-r-lg); backdrop-filter: blur(18px) saturate(130%);
}
.tfa-panel-hd {
  display: flex; align-items: center; justify-content: space-between; gap: 14px;
  padding: 15px 20px; border-bottom: 1px solid var(--tfa-bd); flex-wrap: wrap;
}
.tfa-panel-bd { padding: 18px 20px; }

/* ── Badges / pills ─────────────────────────────────────────────────────────── */
.tfa-pill {
  display: inline-flex; align-items: center; gap: 6px; padding: 3px 9px;
  border-radius: var(--tfa-r-pill); border: 1px solid var(--tfa-bd-2);
  font-family: var(--tfa-mono); font-size: 9.5px; font-weight: 700;
  letter-spacing: .12em; text-transform: uppercase; color: var(--tfa-text-2);
  white-space: nowrap;
}
.tfa-pill.gold { border-color: var(--tfa-gold-bd); color: var(--tfa-gold-2); background: var(--tfa-gold-soft); }
.tfa-pill.ok   { border-color: rgba(74,222,128,.34);  color: var(--tfa-ok);   background: rgba(74,222,128,.10); }
.tfa-pill.warn { border-color: rgba(251,191,36,.34);  color: var(--tfa-warn); background: rgba(251,191,36,.10); }
.tfa-pill.risk { border-color: rgba(248,113,113,.34); color: var(--tfa-risk); background: rgba(248,113,113,.10); }
.tfa-pill.info { border-color: rgba(108,155,255,.34); color: var(--tfa-info); background: rgba(108,155,255,.10); }
.tfa-dot { width: 5px; height: 5px; border-radius: 50%; background: currentColor; flex: 0 0 auto; }

/* ── Skeletons & states. Every async panel owns its own three states. ────────── */
.tfa-skel { border-radius: 6px; background: rgba(255,255,255,.055); animation: tfaShine 1.25s ease-in-out infinite; }
@keyframes tfaShine { 0%,100% { opacity: .45; } 50% { opacity: .85; } }
.tfa-state { padding: 20px; text-align: center; font-size: 12.5px; color: var(--tfa-text-3); line-height: 1.6; }
.tfa-state b { display: block; color: var(--tfa-text-2); font-size: 13px; font-weight: 600; margin-bottom: 5px; }

/* Figures. `tabular-nums` so a count changing from 9 to 10 does not shift the row. */
.tfa-num { font-variant-numeric: tabular-nums; font-weight: 750; letter-spacing: -.02em; color: #FFF; }

/* ═══════════════════════════════════════════════════════════════════════════════
   HEADER NAVIGATION — added as a NEW child of #TB

   `#TB` is `display:flex; justify-content:space-between` with two children. Adding
   a third between them produces brand · nav · controls with no change to `#TB`'s
   own rule, which is why there is no `#TB` override here beyond `position:sticky`.
   The existing Match Deal Pro dropdown, its single authoritative unread badge, the
   mode chip, New chat, Pricing and Sign in / Account are untouched.
   ═══════════════════════════════════════════════════════════════════════════════ */
.tfa-nav {
  display: flex; align-items: center; gap: 2px; min-width: 0;
  --tfa-gold: #D4A832; --tfa-gold-2: #F0CC5A;
}
.tfa-nav-item {
  position: relative; display: inline-flex; align-items: center; gap: 5px;
  min-height: 36px; padding: 0 11px; border: 0; border-radius: var(--tfa-r-xs, 6px);
  background: none; font: inherit; font-size: 12.5px; font-weight: 550;
  color: rgba(242, 239, 232, .62); text-decoration: none; cursor: pointer;
  white-space: nowrap; transition: color 190ms cubic-bezier(.16,1,.3,1);
}
.tfa-nav-item:hover { color: #F2EFE8; }
.tfa-nav-item[aria-current='page'], .tfa-nav-item[aria-expanded='true'] { color: #FFF; font-weight: 650; }
.tfa-nav-item[aria-current='page']::after {
  content: ''; position: absolute; left: 11px; right: 11px; bottom: -1px; height: 2px;
  border-radius: 2px 2px 0 0; background: linear-gradient(90deg, #D4A832, #F0CC5A);
}
.tfa-nav-item .cv { transition: transform 190ms cubic-bezier(.16,1,.3,1); }
.tfa-nav-item[aria-expanded='true'] .cv { transform: rotate(180deg); }

/* Company submenu — a real menu of real destinations (the published legal pages). */
.tfa-sub { position: relative; }
.tfa-submenu {
  position: absolute; top: calc(100% + 9px); left: 0; z-index: 60; min-width: 234px;
  padding: 7px; border-radius: 13px; border: 1px solid rgba(255, 255, 255, .1);
  background: rgba(12, 14, 19, .97); backdrop-filter: blur(26px) saturate(140%);
  box-shadow: 0 22px 58px rgba(0, 0, 0, .6);
  opacity: 0; visibility: hidden; transform: translateY(-5px);
  transition: opacity 190ms cubic-bezier(.16,1,.3,1), transform 190ms cubic-bezier(.16,1,.3,1), visibility 190ms;
}
.tfa-sub.open .tfa-submenu { opacity: 1; visibility: visible; transform: none; }
.tfa-submenu a {
  display: block; padding: 9px 11px; border-radius: 8px; font-size: 12.5px;
  color: rgba(242, 239, 232, .78); text-decoration: none;
  transition: background 190ms, color 190ms;
}
.tfa-submenu a:hover { background: rgba(255, 255, 255, .05); color: #FFF; }

/* Mobile disclosure. Hidden until the nav collapses, so it is never a dead control. */
.tfa-navtog {
  display: none; align-items: center; justify-content: center;
  width: 38px; height: 38px; border-radius: 9px; cursor: pointer;
  border: 1px solid rgba(255, 255, 255, .1); background: transparent; color: #F2EFE8;
}
.tfa-navtog:hover { border-color: rgba(212, 168, 50, .32); }

/* ═══════════════════════════════════════════════════════════════════════════════
   HERO
   ═══════════════════════════════════════════════════════════════════════════════ */
.tfa-hero { position: relative; padding: clamp(46px, 7vw, 92px) 0 clamp(40px, 5vw, 72px); }
/* The trade-network field. Two static radial washes and a 44px grid — no image
   request, no animation, and it degrades to flat black if the gradients fail. */
.tfa-hero::before {
  content: ''; position: absolute; inset: 0; pointer-events: none;
  background:
    radial-gradient(58% 74% at 76% 26%, rgba(212, 168, 50, .085), transparent 66%),
    radial-gradient(46% 60% at 12% 8%, rgba(45, 212, 191, .05), transparent 70%),
    linear-gradient(rgba(255, 255, 255, .016) 1px, transparent 1px) 0 0 / 100% 44px,
    linear-gradient(90deg, rgba(255, 255, 255, .016) 1px, transparent 1px) 0 0 / 44px 100%;
  mask-image: radial-gradient(120% 100% at 50% 0%, #000 42%, transparent 100%);
}
.tfa-hero-grid {
  position: relative; display: grid; gap: clamp(30px, 5vw, 62px);
  grid-template-columns: minmax(0, 1.04fr) minmax(0, .96fr); align-items: center;
}
.tfa-hero-copy { min-width: 0; }
.tfa-cta { display: flex; flex-wrap: wrap; gap: 12px; margin-bottom: 34px; }

/* Standards strip. These are the rulebooks the platform actually applies — the same
   four already named in `#FOOT` plus the SWIFT category the assistant reads. They
   are facts about the product, not platform statistics: there is deliberately no
   countries-covered, companies, documents-analysed or trade-value figure anywhere on
   this page, because no endpoint on this platform can produce one and inventing them
   would put fabricated numbers in front of customers. */
.tfa-standards {
  display: flex; flex-wrap: wrap; gap: 0; margin: 0; padding: 0; list-style: none;
  border: 1px solid var(--tfa-bd); border-radius: var(--tfa-r); overflow: hidden;
  background: var(--tfa-inset);
}
.tfa-standards li {
  flex: 1 1 auto; min-width: 116px; padding: 13px 16px;
  border-inline-start: 1px solid var(--tfa-bd);
}
.tfa-standards li:first-child { border-inline-start: 0; }
.tfa-standards b {
  display: block; font-family: var(--tfa-mono); font-size: 12.5px; font-weight: 700;
  color: var(--tfa-gold-2); letter-spacing: .01em;
}
.tfa-standards i { display: block; margin-top: 3px; font-style: normal; font-size: 10.5px; color: var(--tfa-text-3); }

/* ── Globe. Wireframe, drawn from ellipses — no map asset, no external request, and
      nothing in it asserts a fact about the business. ─────────────────────────── */
.tfa-hero-vis { position: relative; min-width: 0; display: flex; justify-content: center; }
.tfa-globe { width: 100%; max-width: 520px; height: auto; display: block; }
.tfa-globe .gl-arc { animation: tfaArc 5.5s linear infinite; }
.tfa-globe .gl-arc:nth-of-type(2) { animation-delay: 1.1s; }
.tfa-globe .gl-arc:nth-of-type(3) { animation-delay: 2.2s; }
.tfa-globe .gl-arc:nth-of-type(4) { animation-delay: 3.3s; }
.tfa-globe .gl-arc:nth-of-type(5) { animation-delay: 4.4s; }
@keyframes tfaArc { 0% { stroke-dashoffset: 260; } 70%, 100% { stroke-dashoffset: 0; } }
.tfa-globe .gl-hub { animation: tfaHub 3.4s ease-in-out infinite; }
.tfa-globe .gl-hub:nth-of-type(even) { animation-delay: 1.7s; }
@keyframes tfaHub { 0%, 100% { opacity: .5; r: 2.6; } 50% { opacity: 1; r: 3.6; } }

/* The assistant card that overlays the globe. A real control: it focuses the
   composer that is already on this page. */
.tfa-vis-card {
  position: absolute; inset-inline-end: 0; bottom: 0; width: min(268px, 82%);
  padding: 15px 17px; border-radius: var(--tfa-r);
  border: 1px solid var(--tfa-gold-bd); background: rgba(12, 14, 19, .93);
  backdrop-filter: blur(20px); box-shadow: 0 20px 52px rgba(0, 0, 0, .58);
}
.tfa-vis-card h2, .tfa-vis-card h3 { margin: 0 0 5px; font-size: 13.5px; font-weight: 650; color: #FFF; }
.tfa-vis-card p { margin: 0 0 11px; font-size: 11.5px; line-height: 1.55; color: var(--tfa-text-2); }

/* ═══════════════════════════════════════════════════════════════════════════════
   CAPABILITIES (public only)

   Every card's "Learn more" scrolls to that product's card in the EXISTING product
   portal (`#TFS_<id>`), and every "Open" points at the same route the portal card
   already points at. This grid is navigation over existing functionality, not a
   second copy of it, and there is no card here for a capability the build does not
   serve.
   ═══════════════════════════════════════════════════════════════════════════════ */
.tfa-caps { padding: clamp(44px, 6vw, 86px) 0; border-top: 1px solid var(--tfa-bd); }
.tfa-caps-hd { max-width: 660px; margin-bottom: clamp(28px, 4vw, 46px); }
.tfa-caps-grid { display: grid; gap: 16px; grid-template-columns: repeat(3, minmax(0, 1fr)); }
.tfa-cap-card {
  display: flex; flex-direction: column; gap: 12px; padding: 22px;
  background: var(--tfa-surface); border: 1px solid var(--tfa-bd);
  border-radius: var(--tfa-r-lg);
  transition: border-color var(--tfa-dur) var(--tfa-ease), background var(--tfa-dur) var(--tfa-ease);
}
.tfa-cap-card:hover { border-color: var(--tfa-gold-bd); background: var(--tfa-surface-2); }
.tfa-cap-ic {
  width: 42px; height: 42px; flex: 0 0 auto; border-radius: 50%;
  display: flex; align-items: center; justify-content: center;
  border: 1px solid var(--tfa-gold-bd); color: var(--tfa-gold-2); background: var(--tfa-gold-soft);
}
.tfa-cap-card h3 { margin: 0; font-size: 15.5px; font-weight: 650; color: #FFF; letter-spacing: -.012em; }
.tfa-cap-card p { margin: 0; flex: 1 1 auto; font-size: 12.5px; line-height: 1.62; color: var(--tfa-text-2); }
.tfa-cap-acts { display: flex; align-items: center; gap: 14px; flex-wrap: wrap; }

/* ═══════════════════════════════════════════════════════════════════════════════
   WORKSPACE (signed in)

   Answers, in order down the page: what needs my attention, what is happening with
   my deals, what can I do next, what the AI has found. Every figure below is a field
   the server sent. Nothing is derived here, nothing is cached across companies, and
   a figure the platform cannot produce is absent rather than estimated.
   ═══════════════════════════════════════════════════════════════════════════════ */
.tfa-work { padding: 0 0 clamp(34px, 5vw, 62px); }
.tfa-work-grid {
  display: grid; gap: 20px; align-items: start;
  grid-template-columns: minmax(0, 1fr) 336px;
}
.tfa-col { display: flex; flex-direction: column; gap: 20px; min-width: 0; }

/* ── Action launcher ────────────────────────────────────────────────────────── */
.tfa-launch-grid { display: grid; gap: 12px; grid-template-columns: repeat(auto-fit, minmax(178px, 1fr)); }
.tfa-tile {
  display: flex; flex-direction: column; gap: 5px; min-height: 78px;
  padding: 15px 16px; border-radius: var(--tfa-r); text-align: start; cursor: pointer;
  border: 1px solid var(--tfa-bd); background: var(--tfa-inset); color: inherit;
  text-decoration: none; font: inherit;
  transition: border-color var(--tfa-dur) var(--tfa-ease), background var(--tfa-dur) var(--tfa-ease);
}
.tfa-tile:hover { border-color: var(--tfa-gold-bd); background: var(--tfa-gold-soft); }
.tfa-tile b { font-size: 13px; font-weight: 650; color: #FFF; }
.tfa-tile i { font-style: normal; font-size: 11px; color: var(--tfa-text-3); line-height: 1.5; }

/* ── Match Deal Pro journey rail ────────────────────────────────────────────── */
.tfa-journey { display: grid; gap: 10px; grid-template-columns: repeat(6, minmax(0, 1fr)); }
.tfa-step {
  position: relative; display: flex; flex-direction: column; gap: 6px;
  padding: 14px 13px; border-radius: var(--tfa-r); text-decoration: none; color: inherit;
  border: 1px solid var(--tfa-bd); background: var(--tfa-inset); min-width: 0;
  transition: border-color var(--tfa-dur) var(--tfa-ease), background var(--tfa-dur) var(--tfa-ease);
}
.tfa-step:hover { border-color: var(--tfa-gold-bd); background: var(--tfa-gold-soft); }
.tfa-step .k { font-family: var(--tfa-mono); font-size: 8.5px; font-weight: 700; letter-spacing: .15em; text-transform: uppercase; color: var(--tfa-gold); }
.tfa-step .v { font-size: 25px; line-height: 1; }
.tfa-step .l { font-size: 10.5px; line-height: 1.4; color: var(--tfa-text-3); }
/* The chevron between steps. Decorative, so it is a pseudo-element and never a
   character a screen reader has to read out. */
.tfa-step + .tfa-step::before {
  content: ''; position: absolute; inset-inline-start: -7px; top: 50%;
  width: 5px; height: 5px; margin-top: -3px;
  border-top: 1px solid var(--tfa-bd-2); border-inline-end: 1px solid var(--tfa-bd-2);
  transform: rotate(45deg);
}
[dir='rtl'] .tfa-step + .tfa-step::before { transform: rotate(-135deg); }

/* ── Two-up sub-panels ─────────────────────────────────────────────────────── */
.tfa-duo { display: grid; gap: 20px; grid-template-columns: repeat(2, minmax(0, 1fr)); }

/* ── Feed rows (recent activity + AI Trade Pulse) ──────────────────────────── */
.tfa-feed { display: flex; flex-direction: column; }
.tfa-row {
  display: flex; align-items: flex-start; gap: 12px; padding: 13px 0;
  border-top: 1px solid var(--tfa-bd);
}
.tfa-feed .tfa-row:first-child { border-top: 0; padding-top: 0; }
.tfa-row-ic { width: 26px; height: 26px; flex: 0 0 auto; border-radius: 8px; display: flex; align-items: center; justify-content: center; background: rgba(255,255,255,.05); color: var(--tfa-text-2); }
.tfa-row-bd { flex: 1 1 auto; min-width: 0; }
.tfa-row-bd b { display: block; font-size: 12.5px; font-weight: 600; color: var(--tfa-text); line-height: 1.45; }
.tfa-row-bd p { margin: 3px 0 0; font-size: 11.5px; line-height: 1.5; color: var(--tfa-text-3);
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; }
.tfa-row-meta { display: flex; align-items: center; gap: 8px; margin-top: 6px; flex-wrap: wrap; }
.tfa-time { font-family: var(--tfa-mono); font-size: 9.5px; color: var(--tfa-text-3); letter-spacing: .04em; }
.tfa-row-act { flex: 0 0 auto; }

/* ── Deals at a glance ─────────────────────────────────────────────────────── */
.tfa-donut-wrap { display: flex; align-items: center; gap: 22px; flex-wrap: wrap; }
.tfa-donut { position: relative; width: 128px; height: 128px; flex: 0 0 auto; }
.tfa-donut svg { transform: rotate(-90deg); display: block; }
.tfa-donut-c { position: absolute; inset: 0; display: flex; flex-direction: column; align-items: center; justify-content: center; }
.tfa-donut-c b { font-size: 27px; line-height: 1; }
.tfa-donut-c span { margin-top: 4px; font-size: 10px; color: var(--tfa-text-3); }
.tfa-legend { flex: 1 1 150px; display: flex; flex-direction: column; gap: 8px; margin: 0; padding: 0; list-style: none; min-width: 0; }
.tfa-legend li { display: flex; align-items: center; gap: 9px; font-size: 11.5px; color: var(--tfa-text-2); }
.tfa-legend i { width: 8px; height: 8px; border-radius: 2px; flex: 0 0 auto; }
.tfa-legend b { margin-inline-start: auto; font-variant-numeric: tabular-nums; color: var(--tfa-text); }

/* ── Intelligence dock ─────────────────────────────────────────────────────── */
.tfa-dock { display: grid; gap: 16px; grid-template-columns: repeat(3, minmax(0, 1fr)); }
.tfa-dock-card { display: flex; flex-direction: column; }
.tfa-dock-card .tfa-panel-bd { display: flex; flex-direction: column; gap: 13px; flex: 1 1 auto; }
.tfa-dock-card h3 { margin: 0; font-size: 14.5px; font-weight: 650; color: #FFF; }
.tfa-dock-card > .tfa-panel-bd > p { margin: 0; font-size: 12px; line-height: 1.6; color: var(--tfa-text-2); }
.tfa-mini {
  border: 1px solid var(--tfa-bd); border-radius: var(--tfa-r-sm);
  background: var(--tfa-inset); padding: 12px 13px; display: flex; flex-direction: column; gap: 9px;
}
.tfa-mini-hd { font-family: var(--tfa-mono); font-size: 8.5px; font-weight: 700; letter-spacing: .15em; text-transform: uppercase; color: var(--tfa-text-3); }
.tfa-kv { display: flex; align-items: center; justify-content: space-between; gap: 12px; font-size: 11.5px; }
.tfa-kv span { color: var(--tfa-text-3); }
.tfa-kv b { color: var(--tfa-text); font-weight: 600; text-align: end; }

/* ── Right intelligence rail ───────────────────────────────────────────────── */
.tfa-rail { display: flex; flex-direction: column; gap: 20px; min-width: 0; }
.tfa-rail-hero { padding: 20px; text-align: center; }
.tfa-rail-hero h3 { margin: 0 0 6px; font-size: 15px; font-weight: 700; color: #FFF; }
.tfa-rail-hero p { margin: 0 0 15px; font-size: 11.5px; line-height: 1.55; color: var(--tfa-text-2); }
.tfa-poly { width: 74px; height: 74px; margin: 2px auto 13px; display: block; color: var(--tfa-gold-2); }
.tfa-attn { display: flex; flex-direction: column; }
.tfa-attn-row {
  display: flex; align-items: center; gap: 12px; padding: 12px 0;
  border-top: 1px solid var(--tfa-bd); text-decoration: none; color: inherit;
  transition: opacity var(--tfa-dur) var(--tfa-ease);
}
.tfa-attn-row:first-child { border-top: 0; padding-top: 2px; }
.tfa-attn-row:hover { opacity: .78; }
.tfa-attn-row .ix { font-family: var(--tfa-mono); font-size: 10px; font-weight: 700; color: var(--tfa-gold); flex: 0 0 auto; }
.tfa-attn-row .tx { flex: 1 1 auto; min-width: 0; font-size: 12px; color: var(--tfa-text-2); line-height: 1.45; }
.tfa-attn-row .n { font-size: 17px; flex: 0 0 auto; }

/* ═══════════════════════════════════════════════════════════════════════════════
   RESPONSIVE

   Derived from the layout, not from the reference: each breakpoint is the width at
   which a specific grid stops fitting. The rail reflows BELOW the main column
   rather than shrinking, because a 336px column of counters at 240px is unreadable.
   ═══════════════════════════════════════════════════════════════════════════════ */

/* Laptop */
@media (max-width: 1280px) {
  .tfa-work-grid { grid-template-columns: minmax(0, 1fr) 300px; }
  .tfa-journey { grid-template-columns: repeat(3, minmax(0, 1fr)); }
  .tfa-step + .tfa-step::before { display: none; }
}
@media (max-width: 1240px) {
  .tfa-nav-item { padding: 0 8px; font-size: 12px; }
}

/* Tablet — the rail drops under the main column; the dock goes two-up. */
@media (max-width: 1080px) {
  .tfa-work-grid { grid-template-columns: minmax(0, 1fr); }
  .tfa-rail { display: grid; gap: 16px; grid-template-columns: repeat(auto-fit, minmax(252px, 1fr)); align-items: start; }
  .tfa-dock { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .tfa-caps-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

/* Hero stacks; the globe stops competing with the headline for height. */
@media (max-width: 960px) {
  .tfa-hero-grid { grid-template-columns: minmax(0, 1fr); }
  .tfa-hero-vis { order: -1; max-width: 440px; margin: 0 auto 8px; }
  .tfa-lede { max-width: none; }
  .tfa-vis-card { position: static; width: 100%; margin-top: 14px; box-shadow: none; }
  .tfa-duo { grid-template-columns: minmax(0, 1fr); }
}

/* The nav collapses to a disclosure panel. It is the same list of the same real
   destinations; nothing becomes unreachable at this width.

   1080px, not a phone width: `#TB` is a single flex row that also carries the brand,
   the Match Deal Pro menu, the mode chip, New chat, Pricing, Sign in / Account and
   the API badge. Five more items fit comfortably above 1080 and start competing with
   `.tb-right` below it, and a header that wraps is a worse outcome than a header with
   a menu button. Collapsing here — the same width at which the workspace rail
   reflows — keeps the row on one line at every size. */
@media (max-width: 1080px) {
  .tfa-navtog { display: inline-flex; }
  .tfa-nav {
    position: absolute; top: var(--tfa-nav-h); inset-inline: 8px; z-index: 55;
    flex-direction: column; align-items: stretch; gap: 2px; padding: 8px;
    border-radius: 13px; border: 1px solid rgba(255, 255, 255, .1);
    background: rgba(10, 12, 17, .98); backdrop-filter: blur(26px) saturate(140%);
    box-shadow: 0 22px 58px rgba(0, 0, 0, .62);
    display: none;
  }
  .tfa-nav.open { display: flex; }
  .tfa-nav-item { min-height: 42px; justify-content: flex-start; font-size: 13.5px; padding: 0 12px; }
  .tfa-nav-item[aria-current='page']::after { display: none; }
  .tfa-sub, .tfa-submenu { position: static; }
  .tfa-submenu {
    opacity: 1; visibility: visible; transform: none; min-width: 0; box-shadow: none;
    background: none; border: 0; border-top: 1px solid rgba(255, 255, 255, .07);
    border-radius: 0; padding: 4px 0 4px 12px; margin: 2px 0 4px; display: none;
  }
  .tfa-sub.open .tfa-submenu { display: block; }
}

@media (max-width: 760px) {
  .tfa-journey { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .tfa-dock, .tfa-caps-grid { grid-template-columns: minmax(0, 1fr); }
  .tfa-panel-hd, .tfa-panel-bd { padding-inline: 16px; }
  .tfa-standards li { min-width: 50%; flex: 1 1 50%; }
  /* Touch targets stay at 44px and rows stack rather than squeeze. */
  .tfa-row { flex-wrap: wrap; }
  .tfa-row-act { width: 100%; padding-inline-start: 38px; }
  .tfa-row-act .tfa-btn { width: 100%; }
}

@media (max-width: 480px) {
  .tfa-journey { grid-template-columns: minmax(0, 1fr); }
  .tfa-launch-grid { grid-template-columns: minmax(0, 1fr); }
  .tfa-donut-wrap { justify-content: center; }
}

/* ═══════════════════════════════════════════════════════════════════════════════
   RTL

   The layer is authored in logical properties throughout, so mirroring is limited
   to the two places a physical direction was unavoidable: the eyebrow's leading
   rule and the animated arcs. `index.html` itself ships no translation runtime —
   Arabic and RTL live in `mdp/app/i18n/`, untouched by this phase — so these rules
   exist so that a future `dir="rtl"` on this document is correct on arrival rather
   than a layout bug to discover later.
   ═══════════════════════════════════════════════════════════════════════════════ */
[dir='rtl'] .tfa-eyebrow::before { background: linear-gradient(270deg, transparent, var(--tfa-gold)); }
[dir='rtl'] .tfa-globe { transform: scaleX(-1); }

/* ═══════════════════════════════════════════════════════════════════════════════
   REDUCED MOTION & HIGH CONTRAST — honoured, not overridden.
   ═══════════════════════════════════════════════════════════════════════════════ */
@media (prefers-reduced-motion: reduce) {
  #TFA_HOME *, .tfa-nav *, .tfa-submenu {
    animation: none !important;
    transition-duration: 1ms !important;
  }
  .tfa-globe .gl-arc { stroke-dashoffset: 0 !important; }
  .tfa-globe .gl-hub { opacity: .85 !important; }
}
@media (prefers-contrast: more) {
  #TFA_HOME {
    --tfa-bd: rgba(255, 255, 255, .34);
    --tfa-bd-2: rgba(255, 255, 255, .5);
    --tfa-text-2: rgba(242, 239, 232, .88);
    --tfa-text-3: rgba(242, 239, 232, .74);
  }
  .tfa-nav-item { color: rgba(242, 239, 232, .88); }
}

/* ═══════════════════════════════════════════════════════════════════════════════
   NAV ZONE

   `#TB` is `justify-content:space-between`. Everything added to the header is
   therefore wrapped in ONE element, so the header still has exactly three
   children — brand · nav · controls — and `#TB`'s own rule needs no change.
   ═══════════════════════════════════════════════════════════════════════════════ */
.tfa-navzone {
  display: flex; align-items: center; gap: 6px;
  flex: 1 1 auto; min-width: 0; justify-content: center;
}
@media (max-width: 1080px) { .tfa-navzone { flex: 0 0 auto; justify-content: flex-start; } }

/* ── The signed-in / signed-out switch ────────────────────────────────────────
   One attribute on <html>, set from the page's own session object by wrapping
   `updateTopbar()`. The DEFAULT (attribute absent, or "out") is the public
   homepage, so a script failure lands on the marketing page rather than on a
   blank workspace — and the workspace is never the fallback for an unknown
   state. `#BOOT` covers the document until the session is resolved, so neither
   state is ever briefly visible to the wrong visitor. */
html[data-tfa-auth='in'] .tfa-public { display: none !important; }
html[data-tfa-auth='in'] #TFA_WORK { display: block; }

/* Signed in, the hero gives its vertical space back to the work: no globe, no
   marketing lede, no full-viewport band. §6 of the brief — do not waste vertical
   space above the operational surface. */
html[data-tfa-auth='in'] .tfa-hero { padding: 30px 0 22px; }
html[data-tfa-auth='in'] .tfa-hero-grid { grid-template-columns: minmax(0, 1fr); gap: 0; }
html[data-tfa-auth='in'] .tfa-h1 { font-size: clamp(24px, 3vw, 38px); margin-bottom: 10px; }
html[data-tfa-auth='in'] .tfa-hero::before { mask-image: radial-gradient(140% 100% at 50% 0%, #000 30%, transparent 100%); }
#TFA_WORK { display: none; }
.tfa-private { display: none; }
html[data-tfa-auth='in'] .tfa-private { display: block; }

/* ═══════════════════════════════════════════════════════════════════════════════
   PHASE 2 · VISUAL INTEGRATION, LIVE QA & DESIGN FIDELITY

   Every rule below fixes a defect that was REPRODUCED in a real browser at a real
   viewport — nothing here is speculative, and nothing here redesigns a surface the
   phase was told to leave alone. Each block records what was measured, so a later
   phase can re-run the same measurement before changing it.

   Appended rather than merged into the sections above so the Phase 1 layer and the
   Phase 2 corrections stay separately reviewable and separately revertible.
   ═══════════════════════════════════════════════════════════════════════════════ */

/* ── 1 · HORIZONTAL OVERFLOW IN THE HEADER ──────────────────────────────────────
   VERIFIED BUG. `document.scrollWidth` exceeded `clientWidth` at four measured
   viewports, in both signed-out and signed-in states:

     390px public  497 / 390  (+107)      768px private  822 / 768  (+54)
     430px public  497 / 430  (+67)       834px private  875 / 834  (+41)
     390px private 527 / 390  (+137)
     430px private 527 / 430  (+97)

   Isolated to ONE element at every one of them: `.tb-right`, the header's control
   cluster, which is `display:flex; flex-wrap:nowrap` and whose children are all
   fixed-size. Measured children at 390px signed in — `#TB_MD_WRAP` 204..288,
   `.tb-upgrade` 299..380, `#TB_ACCT` 391..483, `.api-badge` 494..527 — so the row
   needs 527px in a 390px viewport. `#TFA_HOME` already clips its own overflow
   (`overflow-x: clip`, above), and `#TB` is outside it, so no rule in this layer
   was containing the header.

   The overflow is older than this layer: `#APP` used to be `overflow:hidden`, which
   CLIPPED the row rather than fixing it — at 390px that silently cut the right edge
   off the Sign In button. The redesign's `#APP{overflow:visible}` turned a hidden
   clip into a visible horizontal scrollbar, which is how the measurement finally
   surfaced. Neither state is acceptable, so the row is made to FIT.

   Two declarations, both the idiom the frozen stylesheet already uses at these
   widths (it hides `.tb-mode` and `.tb-new` and truncates `.api-badge` itself at
   ≤480px), and neither removes a control:

   `.api-badge` is a non-interactive status readout — a coloured dot plus a word the
   frozen sheet already hides at ≤480px. 1080px is the width its own Phase 1 comment
   identifies as the point where "five more items … start competing with .tb-right".
   `.tb-name` is the wordmark beside the gold `TF` mark, not a control: the mark stays,
   and it is the same link target it was. Nothing becomes unreachable at any width.

   After both: 390px signed in measures 360/390, 768px signed in 718/768. */
@media (max-width: 1080px) { #TB .api-badge { display: none; } }
@media (max-width: 480px)  { #TB .tb-brand .tb-name { display: none; } }

/* ── 2 · MATCH DEAL PRO MENU CLIPPED AT ≤430px ──────────────────────────────────
   VERIFIED BUG, and the reason rule 1 is worth stating in full: the 296px panel is
   anchored with `inset-inline-start:0` on `.tb-md-wrap` (frozen, `@media(max-width:
   860px)`), so it opens from wherever the wrap sits. With the wordmark present the
   wrap sat at x=204, putting the panel at 204..496 — past the right edge of a 390px
   and a 430px viewport, and all 13 rows measured as horizontally truncated.

   Rule 1 moves the wrap to x≈56, which puts the panel at 56..348 inside a 390px
   viewport with room to spare. The menu's own width, position, max-height, scroll
   behaviour, z-order, hover corridor and keyboard handling are untouched — this
   phase was told to correct regressions in the dropdown's environment, not to
   redesign the dropdown, and its environment is exactly what changed. Verified
   after the fix: 0 truncated rows and 0 unreachable rows at 390px and 430px. */

/* ── 3 · ~1,150px OF EMPTY RIGHT COLUMN IN THE WORKSPACE ────────────────────────
   VERIFIED BUG. At 1440×900 signed in the grid measured `.tfa-col` 896×1721 beside
   `.tfa-rail` 336×547: the rail ran out of content at y≈866 and left the remaining
   ~1,150px of the right column blank while the reader scrolled the left one.

   The rail is made sticky instead of being refilled. Nothing moves, nothing is
   added, and no second copy of any figure appears: the attention panel simply stays
   on screen for the whole scroll, which is what a command centre's attention rail is
   FOR — §3's "What requires my attention?" stops being a question the reader has to
   scroll back up to re-read.

   Gated on both axes. Above 1080px because that is where the rail is a side column
   at all (below it, it already reflows underneath). Above 680px tall because the
   rail measures 547–566px and `--tfa-nav-h` is 62px: any shorter and a sticky rail
   would pin content the viewport cannot show. `#TFA_HOME` is `overflow-x: clip`,
   which — unlike `hidden` — does not create a scroll container, so the rail sticks
   to the document viewport exactly as `#TB` does. */
@media (min-width: 1081px) and (min-height: 680px) {
  .tfa-rail { position: sticky; top: calc(var(--tfa-nav-h) + 16px); align-self: start; }
}

/* ── 4 · ORPHANED LAST TILE IN THE ACTION LAUNCHER ──────────────────────────────
   VERIFIED BUG. `repeat(auto-fit, minmax(178px, 1fr))` over five tiles measured
   4+1 at 1280/1366/1440/1600/1920 and 3+2 at 768/834 — a ragged last row at every
   desktop width, which is the first thing a reader sees signed in.

   Five never tiles evenly, so the count is made explicit and the fifth tile — "Ask
   TradeFinanceAI", the catch-all action, deliberately last in the DOM — spans the
   row instead of sitting in a gap. Measured after: 4+1(full) at ≥1081px and
   2+2+1(full) between 481px and 1080px. ≤480px stays one per row (above). */
@media (min-width: 1081px) { .tfa-launch-grid { grid-template-columns: repeat(4, minmax(0, 1fr)); } }
@media (min-width: 481px) and (max-width: 1080px) {
  .tfa-launch-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
@media (min-width: 481px) { .tfa-launch-grid > :last-child { grid-column: 1 / -1; } }

/* ── 5 · ORPHANED FIFTH RULEBOOK IN THE STANDARDS STRIP ─────────────────────────
   VERIFIED BUG. `flex: 1 1 auto; min-width: 116px` over five rulebooks measured
   4+1 at 1440 — one chip alone on a second row inside a bordered strip, which reads
   as a rendering fault rather than as a list.

   1120px, not 960px, because the strip is not the viewport: it sits inside
   `.tfa-hero-copy`, the ~1.04fr side of the hero grid, and measures far narrower.
   Forcing five columns from 961px was tried first and regressed — at a 458px strip
   each column gave a 59px content box while the unbreakable word "Documentary"
   needs 67px, so "Documentary credits" and "Incoterms 2020" spilled their cells at
   1024 and 1080. Measured strip widths: 430 at 961, 458 at 1024, 483 at 1080, 502
   at 1120, 542 at 1200, 619 at 1366 and above.

   So five columns apply from 1120px, where 502/5 fits the longest label, and the
   flex rule keeps 961–1119 at 3+2 — a filled row plus a pair, never a lone chip.
   The existing 50% basis still governs ≤760px. Verified after: 5 across at
   1120–1920, 3+2 at 961–1119, and 0 cells with spilling text at any width. */
@media (min-width: 1120px) {
  .tfa-standards { display: grid; grid-template-columns: repeat(5, minmax(0, 1fr)); }
  .tfa-standards li { min-width: 0; }
  /* Five equal columns cannot put every rulebook on one line, and no padding or
     tracking change makes them: the strip's own box is 619px at its widest (it is
     capped by `.tfa-hero-copy`, not by the viewport), giving a 92px content box,
     while "Incoterms 2020" measures 107px in the mono face at 12.5px. So the label
     wraps to two lines in one cell out of five — which on its own is fine, except it
     pushed that cell's sublabel a line below the other four and made a deliberately
     aligned strip look ragged. Reserving two lines for every rulebook name puts all
     five sublabels on one baseline. The line box is pinned explicitly — `normal`
     resolved to 17px for a one-line label but 34px for the wrapped one, so an `em`
     or single-value reservation left a 1px stagger on exactly the cell it was meant
     to fix. 17px x 2 = 34px is the same box either way. Verified
     after: identical `<i>` top offsets
     across all five cells at 1120, 1280, 1440 and 1920. */
  .tfa-standards b { line-height: 17px; min-height: 34px; }
}

/* ── 6 · ASSISTANT CARD OCCLUDING GLOBE LABELS ──────────────────────────────────
   VERIFIED BUG, and wider than the first measurement suggested. The card is an
   absolute overlay pinned to the globe's bottom-inline-end corner, so how much of
   the globe it covers depends entirely on how wide the globe has been allowed to
   get. Swept every 40–90px from 961 to 1920, recording which `.tfa-globe text`
   labels intersect the card's box:

     961  globe 397  RIYADH · SAR grazed 8px, SINGAPORE · SGD FULLY COVERED
     1024 globe 423  SINGAPORE · SGD FULLY COVERED
     1080 globe 446  SINGAPORE · SGD FULLY COVERED
     1120 globe 464  SINGAPORE · SGD grazed 9px
     1200 globe 500  clear
     1280+ globe 520 clear (capped by max-width)

   "Fully covered" means the label's whole box sat inside the card's box: at 1024 a
   corridor label was invisible, not merely tight. The overlay is only sound once the
   globe reaches its 520px cap, so it is scoped to where it is sound. Between 961 and
   1199 the card takes the same static, full-width, shadowless treatment the ≤960px
   block already gives it — one presentation, two width bands, no new idiom — and it
   still sits directly above the composer it focuses.

   At 1200 and up the 10px of extra drop clears the 1px graze measured at 1440,
   where the label's box (483..495) met the card's top edge (494). Verified after: 0
   intersecting labels at every swept width. */
@media (min-width: 961px) and (max-width: 1199px) {
  .tfa-vis-card { position: static; width: 100%; margin-top: 12px; box-shadow: none; }
}
@media (min-width: 1200px) { .tfa-vis-card { bottom: -10px; } }

/* ── 6b · THE GLOBE WAS COMPETING WITH THE CARD FOR THE SAME ROW ────────────────
   VERIFIED BUG, found by making 6 true and then measuring it. `.tfa-hero-vis` is a
   flex row, which is invisible while the card is `position:absolute` and out of
   flow — but the ≤960px block already takes the card static, so at every phone and
   tablet width the card has been a flex ITEM sitting BESIDE the globe, not below it,
   despite its own `margin-top`. Measured before this rule, `flex-direction: row` at
   all five:

     390  globe 161x213 | card 180   768  globe 211x213 | card 229
     430  globe 181x213 | card 199   834  globe 211x213 | card 229
                                     960  globe 211x213 | card 229

   A 480x430 viewBox rendered 161px wide puts the corridor labels at roughly 4px, so
   §2's "world-map prominence" was inverted on mobile: the map was the smallest thing
   in the hero. Stacking is what the static card's `margin-top` was always written
   for, and it applies to both static bands. Verified after: globe 340x302 at 390,
   440x391 at 768, card full width beneath it, 0 side-by-side at any width. */
@media (max-width: 1199px) {
  .tfa-hero-vis { flex-direction: column; align-items: center; }
}

/* ── 7 · MOBILE HERO LED WITH THE ILLUSTRATION ──────────────────────────────────
   VERIFIED BUG against §2 and §7. At ≤960px `order:-1` put the globe at y=98 and
   the headline at y=349, so a phone opened on a decorative wireframe and the
   positioning statement, the lede and both calls to action were below it. §7 asks
   for a layout that is reflowed rather than shrunk: the headline leads, the visual
   follows it, and the assistant card — already `position:static` at this width —
   lands directly above the composer it focuses. */
@media (max-width: 960px) {
  .tfa-hero-vis { order: 0; margin: 6px auto 0; }
}

/* ── 8 · TOUCH TARGETS ON COARSE POINTERS ───────────────────────────────────────
   Measured 27px tall for every `.tfa-link` at 768/834 with a touch pointer. They
   clear WCAG 2.5.8's 24×24 minimum but not comfortably, and they are the panel
   headers' only affordance. Padding, not height, so no row metric changes. */
@media (pointer: coarse) {
  .tfa-link { min-height: 36px; padding-block: 5px; }
}

/* ── 9 · RTL: THE DOCUMENT NEVER ACTUALLY MIRRORED ──────────────────────────────
   VERIFIED BUG, and the answer to §8's structural question. Rendering the root page
   under `dir="rtl"` mirrored the two things this layer states explicitly — the
   globe (`scaleX(-1)`) and the journey chevrons (`rotate(-135deg)`) — and NOTHING
   else: `getComputedStyle(document.querySelector('.tfa-work-grid')).direction`
   measured `ltr` with `document.documentElement.dir === 'rtl'`, so the workspace
   rail stayed at 1005..1341 and the main column at 89..985, exactly as in LTR.

   Root cause is `index.html`'s frozen stylesheet, line 137: `html,body{ …
   direction:ltr }`. A `dir` ATTRIBUTE is a presentational hint that any author
   declaration beats, so `[dir='rtl']` selectors matched while the computed direction
   never changed — the worst of the two states, a half-mirrored page.

   One additive rule restores the attribute's meaning. It cannot match the shipped
   document (`<html lang="en" dir="ltr">`) so it changes nothing today; it means the
   logical properties this layer is already written in resolve correctly the moment a
   future phase sets `dir="rtl"`. That is the whole of the fix: no translation
   runtime is introduced, no string is localised, and `mdp/app/i18n/` is untouched.
   Verified after: the grid, the rail, the nav, the action rows and the attention
   panel all mirror, with no horizontal overflow beyond the LTR baseline. */
html[dir='rtl'], html[dir='rtl'] body { direction: rtl; }

/* 10 · SIGNED-IN HERO HIERARCHY — the marketing headline outranked the operator.
   Measured at 1440x900 signed in: `.tfa-h1` ("The Operating System for Global
   Trade Finance.") rendered at 38px / weight 800 and occupied 81px, while the
   operator's own context ("Good evening, Amira") rendered at 16.5px inside
   `.tfa-lede` — the marketing slogan was 2.3x the size of the only line on the
   page that is actually about this session. §3 of the brief names that exact
   failure mode: the workspace is an institutional command center and must NOT
   read as a marketing dashboard, and it must answer "what is happening with my
   deals" first.

   Fixed the ranking, not the content: signed in, the platform name drops to a
   compact institutional title (the gold second line is kept, so brand presence
   survives) and the greeting becomes the opening statement. Public state is
   untouched — the selector is scoped to [data-tfa-auth='in'], where the slogan
   IS the headline and correctly stays at clamp(30px, 4.6vw, 60px).

   Nothing here changes markup or semantics: `.tfa-h1` remains the section's
   `aria-labelledby` target and the page's only level-1 heading. Font weight and
   colour on #TFA_GREET are left to the inline style Phase 1 set, so this rule
   adjusts size and rhythm only.
   Verified after at 1440x900: h1 box 81px -> 52px (38px -> 21px type), greeting
   16.5px -> 34px, hero 257px -> 248px, so the hierarchy inverts at no vertical
   cost. Attention rows stay entirely above the fold at every laptop height the
   brief names (last row 562 of 768 at 1366x768, 554 of 720 at 1280x720), and no
   viewport gains overflow.

   Layout-shift cost, measured 4 runs at 1440x900 signed in, with and without the
   two rules below: 0.0936 -> 0.100 in the settled case. The +0.006 is the content
   below the hero starting 9px higher, which is the point of the change. The larger
   excursions seen in some loads (0.121-0.127) are NOT from this block — the same
   4-run sweep with these rules removed reproduces 0.1211, and the extra 0.0381
   always attributes to `.tfa-hero-vis.tfa-public` painting before the session
   resolves and the public hero is removed. That race predates Phase 2, happens
   underneath the opaque #BOOT cover so no visitor sees it, and cannot be closed
   without making the signed-out homepage stop being the default state — which the
   Phase 1 comment above deliberately requires as the script-failure fallback. Left
   alone and reported. */
html[data-tfa-auth='in'] .tfa-h1 {
  font-size: clamp(17px, 1.5vw, 21px); font-weight: 700;
  letter-spacing: -.008em; line-height: 1.24; margin-bottom: 14px;
  color: var(--tfa-text-2);
}
html[data-tfa-auth='in'] #TFA_GREET {
  display: inline-block; margin-bottom: 4px;
  font-size: clamp(23px, 2.5vw, 34px); letter-spacing: -.022em; line-height: 1.14;
}
