/*
 * Mercor Wealth — THE THRESHOLD (sign-in and sign-out)
 * ---------------------------------------------------------------------------
 * THE VAULT (owner-selected from a four-way bake-off): the rose-engine
 * engraving is not an ornament on the page — it IS the room. One immense
 * engine turn fills the viewport, its single bronze thread alive, and the
 * reader signs in standing inside it. The engraving's calm eye holds the
 * mark and the act, so the instrument and the engraving never touch. The
 * sign-out is the SAME room — seed 7, the house's one seal — entered and
 * left.
 *
 * Both pages are pre-auth ISLANDS: they cannot load /portal/tokens.css, so
 * each carries the canonical token values inline and this sheet may only
 * consume tokens the islands supply (gated by check-surfaces).
 *
 * LAWS:
 *   · Motion is always on — no reduced-motion clause (standing owner ruling).
 *   · Hidden states live ONLY inside keyframes, filled `backwards`: content
 *     must be fully visible if animations never run.
 *   · No date, no clock (owner ruling): the door tells you where you are,
 *     not when.
 *   · No classification marking here. These pages are served anonymously —
 *     PUBLIC in the firm's own scheme (classification.js), and "a marking on
 *     a public document implies a restriction that does not exist."
 *   · One bronze engraving strand per page: the room's own thread.
 */

:root {
  /* the calm eye — the strand-free chamber the mask carves for the content */
  --eye-rx: 310px;
  --eye-ry: 260px;
  --eye-grow: 1.55;   /* the fade shore: strands are gone by rx, full by rx × grow */
}

/* ── the sheet ──────────────────────────────────────────────────────────── */
body { display: flex; flex-direction: column; min-height: 100vh; min-height: 100dvh; }
.sr-only {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip-path: inset(50%); white-space: nowrap; border: 0;
}

/* ── the room ───────────────────────────────────────────────────────────────
 * The engine turn, viewport-filling, centred on the same point as the
 * content. The MASK is the owner's ruling made structural: a clear
 * elliptical chamber at the centre, so no strand can ever cross the mark or
 * the act — at any viewport, in either theme. The engraving does not stop at
 * a box; it shallows to nothing approaching the chamber, the way a rose
 * engine's cut shallows toward the die's centre. */
.thr-room {
  position: fixed; left: 50%; top: 50%;
  /* THE ROOM MUST REACH EVERY CORNER. The medallion's outermost ring sits at
     0.465 × its box, so a fixed 1600px box ends at a 744px radius — measured
     at 1920×1080 (corner distance 1101px) the ring closed INSIDE the
     viewport and the corners went bare: a giant medallion on a page, not a
     room. 132vmax keeps the ring beyond the corner at every desktop size
     (1920: ring 1143 ≥ 1101 · 2560: 1571 ≥ 1469 · 4K: 2357 ≥ 2203). */
  width: max(1600px, 132vmax); height: max(1600px, 132vmax);
  transform: translate(-50%, -50%);
  pointer-events: none; z-index: 1;
  opacity: 0.55;
  /* TWO clear zones, intersected: the eye at the centre, AND a small local
     POCKET behind the foot line. The pocket replaced a full-width band after
     the owner ruled the art must run END TO END — the band visibly cut the
     engraving off before the bottom edge. The pocket clears only the ink of
     the one foot line; the strands run to the corners on either side of it.
     The foot was measured against the REAL rendered pixels behind it and it
     failed badly — the room's bronze strand passes directly under that line,
     giving a ground of rgb(180,164,140) in light and rgb(112,91,62) in dark,
     so 9.5px tertiary text scored 2.10:1 and 1.79:1 against a 4.5:1 floor.
     The composited-background gate could not see it: the strands are SVG
     content behind a transparent element, not a CSS background.
     A room that makes its own colophon unreadable is not a room.

     The band's stop is `calc(50% + 50vh - ...)` and that is load-bearing: a
     mask resolves against the ROOM's box, not the viewport. The room is
     1900px tall on a 900px viewport, so a naive "74px from the bottom" lands
     500px BELOW the fold and clears nothing. 50% of the box plus 50vh is the
     distance from the room's top to the viewport's bottom edge. */
  -webkit-mask-image:
    radial-gradient(
      ellipse calc(var(--eye-rx) * var(--eye-grow)) calc(var(--eye-ry) * var(--eye-grow)) at center,
      transparent 0, transparent calc(100% / var(--eye-grow)), #000 100%),
    radial-gradient(ellipse 260px 44px at 50% calc(50% + 50vh - 30px),
      transparent 0 55%, #000 100%);
  mask-image:
    radial-gradient(
      ellipse calc(var(--eye-rx) * var(--eye-grow)) calc(var(--eye-ry) * var(--eye-grow)) at center,
      transparent 0, transparent calc(100% / var(--eye-grow)), #000 100%),
    radial-gradient(ellipse 260px 44px at 50% calc(50% + 50vh - 30px),
      transparent 0 55%, #000 100%);
  -webkit-mask-composite: source-in;
  mask-composite: intersect;
}
html.dark .thr-room { opacity: 0.7; }
/* THE ENGINE TURNS (owner ruling, 3 Aug 2026). One silky revolution every
   four minutes — visibly alive, like a real engine-turn lathe, and
   perfectly registered because the WHOLE plate turns as one object.
   This is also the phones' smoothness fix at its root: the old interior
   band-rock animated groups INSIDE the SVG, which cannot composite and
   forced a full repaint of the engraving every frame. A transform on the
   svg element itself is one GPU layer — the browser never repaints the
   strands at all. The mask lives on the container, so the eye and the foot
   pocket hold still while the engraving turns inside them. */
.thr-room svg { width: 100%; height: 100%; display: block;
  animation: mw-turn 240s linear infinite; will-change: transform; }
@keyframes mw-turn { from { transform: rotate(0deg); } to { transform: rotate(360deg); } }
/* the interior rock stands down here — the turn is the room's one motion */
.thr-room svg .mw-t { animation: none; }

/* ── the corner instrument (theme) ──────────────────────────────────────── */
.thr-corner {
  position: fixed; top: calc(var(--mw-space-3) + var(--sat)); right: calc(var(--mw-space-3) + var(--sar));
  z-index: 3;
}
.thr-corner button {
  background: none; border: 0; cursor: pointer;
  display: flex; align-items: center; justify-content: center;
  padding: 9px; margin: -9px;              /* 44px touch floor, returned to layout */
}
.toggle-ring {
  width: 26px; height: 26px; border-radius: 50%;
  border: 1.5px solid var(--mw-rule);
  display: flex; align-items: center; justify-content: center; position: relative;
  transition: border-color 0.3s ease;
}
.toggle-dot { width: 7.5px; height: 7.5px; border-radius: 50%; background: var(--mw-ink);
  transition: background 0.3s ease, transform 0.3s ease; }
html.dark .toggle-dot { transform: scale(0.82); }
.toggle-ring::before {
  content: ''; position: absolute; top: -5px; left: 50%; transform: translateX(-50%);
  width: 1.5px; height: 6px; border-radius: 1px; background: var(--mw-rule);
  transition: background 0.3s ease;
}
.thr-corner button:hover .toggle-ring { border-color: var(--mw-text-secondary); }
/* THE FOCUS RING MUST NOT DEPEND ON color-mix().
   --mw-focus holds a color-mix(), and substituting an unsupported value into
   the `outline` SHORTHAND voids the WHOLE declaration at computed-value time —
   not just the colour. On any engine without color-mix that leaves keyboard
   users with NO focus indicator at all, which is a 2.4.7 failure caused by a
   decorative alpha. The solid role token ships first; the softened one is an
   enhancement applied only where it can actually parse. */
.thr-corner button:focus-visible,
a:focus-visible { outline: 2px solid var(--mw-bronze-line); outline-offset: 4px; border-radius: var(--mw-radius-soft); }
@supports (outline-color: color-mix(in srgb, red 50%, transparent)) {
  .thr-corner button:focus-visible,
  a:focus-visible { outline-color: var(--mw-focus); }
}

/* ── the chamber: the content in the engraving's eye ────────────────────────
 * One column, one axis, EQUAL BREATHS: every step between the chamber's
 * elements is exactly --mw-space-4 (owner refinement: tighter, and equal —
 * unequal gaps read as drift in a composition this quiet). */
.thr-main {
  position: relative; z-index: 2;
  flex: 1; display: flex; flex-direction: column;
  align-items: center; justify-content: center;
  text-align: center;
  width: 100%; max-width: calc(400px + var(--mw-space-4) * 2);
  margin: 0 auto;
  padding: var(--mw-space-5) var(--mw-space-4);
}
.thr-main > * + *,
.thr-entry > * + *, .thr-mass > * + * { margin-top: var(--mw-space-4); }
.thr-entry, .thr-mass { width: 100%; }

.mw-lockup { width: min(300px, 84vw); height: auto; display: block; margin: 0 auto; }
/* THE SIGNATURE'S COLOURS ARE FIXED BY THE IDENTITY MANUAL — "Two versions
   exist, one per ground. There is no third." (brand-standards, Signature
   chapter). These are BRAND CONSTANTS, deliberately not text tokens: the
   drift the owner spotted was exactly this lockup wearing text-secondary
   and text-tertiary instead of its own fixed greys.
   Light: dots #c0bdb8 · centre/MERCOR #1c1c1c · divider #d0cec9 · WEALTH #888.
   Dark:  dots #3a3a3a (deepened, so the centre keeps its authority) ·
          centre/MERCOR #f8f7f4 Off White · divider #333 · WEALTH #666.
   Logotype colours are exempt from text-contrast rules (WCAG 1.4.3), and
   check-surfaces knows it. */
.mk-dot    { fill: var(--mw-dot-muted); transition: fill 0.6s ease; }
html.dark .mk-dot { fill: var(--mw-dot-muted-dark); }
.mk-center { fill: #1c1c1c; transition: fill 0.6s ease; }
html.dark .mk-center { fill: #f8f7f4; }
.mk-rule   { stroke: #d0cec9; transition: stroke 0.6s ease; }
html.dark .mk-rule { stroke: #333333; }
.wm { fill: #1c1c1c; transition: fill 0.6s ease; }
html.dark .wm { fill: #f8f7f4; }
.ws { fill: #888888; transition: fill 0.6s ease; }
html.dark .ws { fill: #666666; }

.mw-thr-act {
  display: inline-flex; align-items: center; justify-content: center; gap: 14px;
  width: min(330px, 100%);
  font: var(--mw-weight-medium) 12.5px/1 var(--mw-font-sans);
  letter-spacing: 0.25em; text-transform: uppercase; text-decoration: none;
  color: var(--btn-fg); background: var(--mw-ink);
  padding: 21px var(--mw-space-5);
  border: 0.5px solid var(--mw-ink);
  border-radius: var(--mw-radius-control);
  cursor: pointer;
  transition: background-color 0.35s ease, border-color 0.35s ease,
              letter-spacing 0.35s ease, transform 0.35s var(--mw-ease), color 0.6s ease;
}
.mw-thr-act:hover {
  background: var(--mw-accent-strong); border-color: var(--mw-accent-strong);
  letter-spacing: 0.29em; transform: translateY(-1px);
}
.mw-thr-act:active { transform: translateY(0); }
.mw-thr-act .arrow {
  display: inline-block; font-size: 13px; line-height: 1;
  transition: transform 0.35s var(--mw-ease);
}
.mw-thr-act:hover .arrow { transform: translateX(4px); }

/* THE ACT MUST SAY IT HEARD YOU.
   For a returning reader whose portal tabs are closed, the door does not
   navigate on click — it preventDefault()s and runs a multi-second chain
   (a 900ms tab probe, two logout fetches, then up to five /.auth/me polls
   450ms apart). Measured: 600ms after the click the button was still
   byte-identical — no spinner, no disabled look, nothing — and because
   `accessStarting` is tested AFTER preventDefault(), every further click was
   swallowed in silence. The reasonable conclusion is that sign-in is broken.
   Motion is always on here, so the wait is a drawn one: the act dims, stops
   taking pointer events, and a bronze thread travels its foot. */
.mw-thr-act[aria-busy='true'] {
  opacity: 0.72; pointer-events: none; letter-spacing: 0.27em;
  position: relative; overflow: hidden;
}
.mw-thr-act[aria-busy='true'] .arrow { opacity: 0; }
.mw-thr-act[aria-busy='true']::after {
  content: ''; position: absolute; left: 0; bottom: 0; height: 1.5px; width: 40%;
  background: var(--mw-bronze-line);
  animation: mw-working 1.15s var(--mw-ease) infinite;
}
@keyframes mw-working {
  from { transform: translateX(-100%); }
  to   { transform: translateX(350%); }
}

.thr-note {
  font: var(--mw-weight-text) 10.5px/1.7 var(--mw-font-sans);
  letter-spacing: 0.14em; text-transform: uppercase;
  color: var(--mw-text-secondary);
}

/* ── the goodbye's chamber (same room, different mass) ────────────────────
 * The farewell is a CEREMONY: the room holds, the hold-line draws its four
 * seconds in bronze, and the page says exactly what is happening. */
.mw-thr-title {
  margin: 0;
  font: var(--mw-weight-semibold) 15px/1.5 var(--mw-font-sans);
  letter-spacing: 0.2em; text-transform: uppercase;
  color: var(--mw-ink);
  text-wrap: balance;
}
.mw-thr-body {
  font: var(--mw-weight-text) 12px/1.75 var(--mw-font-sans);
  color: var(--mw-text-secondary);
  max-width: 34ch; text-wrap: pretty;
  margin-left: auto; margin-right: auto;
}
.mw-thr-body a {
  color: var(--mw-ink); text-decoration: underline;
  text-underline-offset: 3px; text-decoration-thickness: 0.5px;
}
.mw-thr-return {
  display: inline-flex; align-items: center; justify-content: center;
  min-height: 44px;
  font: var(--mw-weight-medium) 11px/1 var(--mw-font-sans);
  letter-spacing: 0.2em; text-transform: uppercase; text-decoration: none;
  color: var(--mw-ink);
  padding: 15px var(--mw-space-4);
  border: 0.5px solid var(--mw-rule);
  border-radius: var(--mw-radius-control);
  transition: border-color 0.35s ease, letter-spacing 0.35s ease, color 0.6s ease;
}
.mw-thr-return:hover { border-color: var(--mw-text-secondary); letter-spacing: 0.23em; }

/* ── the foot: one quiet line, correctly unmarked ───────────────────────── */
.thr-foot {
  position: relative; z-index: 2;
  padding: var(--mw-space-3) var(--mw-space-4) calc(var(--mw-space-4) + var(--sab));
  text-align: center;
  font: var(--mw-weight-text) 9.5px/1 var(--mw-font-sans);
  letter-spacing: 0.19em; text-transform: uppercase;
  /* SECONDARY, not tertiary. The foot reads against the room's fade shore,
     not against clean page ground: measured on real pixels the ground behind
     it runs to rgb(230,229,224) light and rgb(36,34,32) dark even with the
     band cleared. Tertiary scores 4.06/4.39 there and only 4.78 on perfect
     ground — no margin at all. Secondary gives 5.47/6.56. */
  color: var(--mw-text-secondary);
}

/* ── MOTION: THE ROOM BREATHES IN; THE MARK IS ALREADY THERE ──────────────
 *
 * Owner rulings, 2 Aug 2026:
 *   · The mark is STILL. No assembly, no flying dots, no pulse — it is
 *     simply present from the first paint, complete and confident. The
 *     condense/strike/wipe choreography is deleted, not tuned.
 *   · The page's feel is SLOW & STATELY: few animations, long ones.
 *
 * So the whole entrance is two long breaths and nothing else:
 *   1. the engraved room fades in around the still mark (~2.8s — the
 *      engage the art module injects, slowed by the override below), and
 *   2. the chamber's mass presents once, one long fade.
 * State motion (hover, the act's busy thread, the goodbye's hold) stays —
 * that is feedback, not ceremony.
 *
 * Hidden states live ONLY inside keyframes, filled `backwards` (standing
 * law): everything is fully visible if animations never run. */

.thr-room .mw-art-engage { animation-duration: 2.8s; }

.thr-entry, .thr-mass { animation: mw-present 1.6s var(--mw-ease) 0.5s backwards; }
@keyframes mw-present { from { opacity: 0; } to { opacity: 1; } }

/* ── narrow and short ───────────────────────────────────────────────────── */
@media (max-width: 420px) {
  :root { --eye-rx: 250px; --eye-ry: 240px; }
  .thr-room { width: 1200px; height: 1200px; }
  .thr-note { font-size: 10px; }
  .thr-foot { font-size: 9px; }
  .mw-thr-act { font-size: 12px; letter-spacing: 0.2em; padding: 20px var(--mw-space-4); }
  .mw-thr-title { font-size: 14px; letter-spacing: 0.17em; }
  .mw-thr-body { font-size: 11.5px; }
}
@media (max-height: 640px) {
  .thr-main { padding-top: var(--mw-space-6); padding-bottom: var(--mw-space-4); }
  /* A short viewport still has corners. Pinning the room to a FIXED 1100px
     put its outermost ring at 512px while the corner sits at 593px (1024x600),
     716px (1280x640) or 530px (900x560) — bare corners in every case, the
     medallion-on-a-page look again. The floor drops, the vmax rule stays. */
  .thr-room { width: max(1100px, 132vmax); height: max(1100px, 132vmax); }
}

/* THE DUSK — a theme change is one slow cross-fade of the whole room
   (View Transitions), never a token snap: hundreds of strands repainting
   at once read as a stutter. Two composited snapshots, one fade. */
::view-transition-old(root), ::view-transition-new(root) {
  animation-duration: 0.6s;
  animation-timing-function: cubic-bezier(0.22, 1, 0.36, 1);
}
