/* ============================================================================
   Portmasters v2 — AuthSplitLayout — auth-split-layout.css  (Visual System v2)
   ----------------------------------------------------------------------------
   PROVENANCE (re-skin + PROMOTE, NOT a redesign). The full-viewport TWO-COLUMN
   page scaffold behind every pre-login screen: a centered white auth FORM panel
   on the LEFT and a branded PROMO panel on the RIGHT, collapsing to a single
   column (form only) on mobile.

   SOURCE OF TRUTH (verbatim captures, authenticated dev.portmasters.nl):
     · line-forwarder-prelogin/001-home            LEFT = "Login" (email + password
         + "Forget your password?" + primary button); RIGHT = brand surface with a
         product-dashboard screenshot bleeding in.
     · line-forwarder-prelogin/004-forget          LEFT = "Forgot Password" (lead +
         email + "Send Recovery Code" + a leading "← Back"); RIGHT = brand surface
         with the centered Portmasters logo lockup + repeating-wordmark watermark.
     · line-forwarder-prelogin/003-register-verify SAME frame, verify step on LEFT.
   The captured OUTER markup this file NAMES + re-skins to catalog tokens (verbatim
   classes lifted from 004-forget/dom.html):
       <div class="grid md:grid-cols-2 h-screen items-center">
         <div class="md:w-1/2 h-full"> … <div class="flex flex-col h-full bg-white">
             <div class="flex flex-col space-y-6 justify-center flex-1"> …FORM… </div>
         <div class="h-full hidden md:flex items-center overflow-hidden justify-center
                     bg-primary-950 relative">
             <div class="absolute … w-[1000px] h-[1000px] rounded-full
                         bg-[#810E8F] blur-[200px]"></div>          ← the glow
             <svg … class="z-20 w-1/2"> …BRAND MARK… </svg>
   The two-column grid, the white left column, the centered-form vertical rhythm,
   the branded right column, and the md single-column
   collapse are ALL captured — this file reproduces THAT scaffold (the branded column's
   glow/watermark/lockup/screenshot are reproduced by the consumed brand-panel). Nothing is
   added, removed, reworded, or reordered. (Note: the product wrote `md:grid-cols-2`
   with a redundant `items-center` on a `h-screen` grid; we drop that stray
   alignment and let each column own full height — the visual is identical.)

   THIS COMPONENT IS A COMPOSITION SHELL. It owns ONLY: the full-viewport two-column
   frame, the LEFT white form-panel surface + its centered/scrolling form column,
   the RIGHT branded promo surface (the STAGE that hosts the consumed auth-brand-panel),
   and the single-column mobile collapse. Where a slot IS an existing catalog component
   it CONSUMES that component and does NOT re-implement:
     • the form fields (email / password / code) → text-field.css (.pm-textfield) —
         label + control + helper, focus ring, invalid/valid, disabled all live
         there. This file only lays them into the centered form column.
     • the submit + the "Back" affordance        → button.css (.pm-btn). The submit
         is `.pm-btn .pm-btn--filled .pm-btn--primary .pm-btn--lg` + a block modifier
         (below) to span the column; "Back" is a quiet `.pm-btn` text/regular button.
         All button visuals + the two-layer focus ring live in button.css.
     • "Forget your password?" / "Back to login" → a real inline text LINK (this
         file styles the link ink only; it is an <a>, focusable, underlined).
     • an optional trust/status line on the panel → status.css (.pm-status) dot+word
         (e.g. "All systems operational") — NEVER a pill.
     • ALL promo-panel artwork (sail motif, brand glow, repeating-wordmark watermark,
         wordmark lockup, bleeding product screenshot) → auth-brand-panel.css
         (.pm-brandpanel), dropped INTO .pm-auth__promo-col. This file owns only that
         promo column stage + its mobile collapse — never the artwork.

   ANTI-INVENTION / NO-PILL CONTRACT (Amir hard veto — supersedes any marketing
   carve-out): nothing here is a pill / chip / eyebrow. The promo panel is a plain
   branded surface (fill + glow + logo), not a rounded tag. A trust line is a DOT +
   a WORD (status.css). The inline recovery / back link is underlined text, not a
   filled tag. No wrapper here is a rounded-full badge.

   TOKEN MAP (source class → v2 role, ZERO new hex / ZERO raw px outside --space):
     page / left form panel (bg-white) → var(--surface-1)   raised white panel (FLIPS
                                                            to --deep-2 in dark)
     form-panel page gutter behind it   → var(--bg)          page base (flips). In DARK
                                                            that is --deep #0f0715, the
                                                            page plane — correct. In
                                                            LIGHT it is --paper #faf8fc,
                                                            which is the TRAY plane; the
                                                            light PAGE plane #f4f2f6 has
                                                            no token (see the note at
                                                            the foot of this file).
     right promo base (bg-primary-950)  → var(--brand-deep)  FIXED brand surface, the
                                                            dark PAGE plane #0f0715
                                                            (does NOT flip — see DARK)
     promo glow (bg-[#810E8F])          → var(--brand-glow)  brand-family radial glow
     promo ink / logo / trust           → var(--text-on-dark) white on the brand fill
     form heading ink                   → var(--text-primary) near-black (flips)
     form lead / body ink               → var(--text-secondary) lead ink (flips)
     inline recovery/back link ink      → var(--accent)      brand magenta (flips light)
     seam hairline (rtl/ltr, optional)  → var(--border)      default hairline (flips)
     focus ring (on the link)           → var(--focus-ring) + panel-surface offset
   The LEFT column flips light→dark via its roles (tokens-semantic.css). The RIGHT
   promo column is a BRAND surface — it is ALREADY dark (the page plane #0f0715) and
   stays branded in BOTH themes (a dark-mode login must not turn the brand panel into
   plain layer-01 grey). Its ink is white in both. See the DARK section for the proof.
   All radii come from the sanctioned radius roles; no raw px outside the --space ramp.

   Class model:
     frame     .pm-auth                              <div>         the full-viewport 2-col grid
       form    .pm-auth__form-col                      <div>       LEFT column track (full height)
         panel .pm-auth__panel                           <main>    the WHITE form panel surface (landmark)
           top .pm-auth__panel-top                         <div>   optional top row (e.g. a "Back" button / logo), pinned above the centered form
           body .pm-auth__body                             <div>   the CENTERED (vertically) form region — grows to fill, scrolls if tall
             form .pm-auth__fields                          <form> the actual form: heading + lead + fields + actions (space-y rhythm)
               head .pm-auth__heading                        <h1>  the screen title ("Login" / "Forgot Password")
               lead .pm-auth__lead                           <p>   optional supporting line under the heading
               link .pm-auth__link                           <a>   inline text link (recovery / back-to-login) — underlined, NOT a pill
             foot .pm-auth__panel-foot                       <div> optional bottom row (legal / locale / trust dot+word), pinned below the form
       promo   .pm-auth__promo-col                      <aside>    RIGHT branded promo column (aria-hidden decorative OR labelled);
                                                                    HOSTS the consumed auth-brand-panel (.pm-brandpanel) — the
                                                                    sail/glow/watermark/lockup/screenshot live THERE, not here
     modifiers
       .pm-auth--promo-left                           mirror: promo on the LEFT, form on the RIGHT (RTL-friendly / variant)
       .pm-auth__submit  (used WITH .pm-btn)          block-width submit: `.pm-btn.pm-btn--filled.pm-btn--primary.pm-btn--lg.pm-auth__submit`
     helpers (frozen, screenshot-only): none needed — this shell has no stateful pseudo of its own
                                        (the consumed button/field/link own their own states).

   RESPONSIVE / SINGLE-COLUMN COLLAPSE (captured: the product hides the promo panel
   on mobile — `hidden md:flex`): below --pm-auth-bp the grid drops to ONE column and
   the promo column is display:none — the form panel fills the viewport. Desktop shows
   BOTH equal columns. No horizontal page scroll: the promo art is clipped
   (overflow:hidden) and the form column owns its own vertical overflow.
   ============================================================================ */

@import url("../../tokens/tokens.css");
@import url("../../tokens/tokens-semantic.css");
@import url("../../tokens/tokens-type.css");  /* product type ramp — the 14 named Figma text styles (2026-08-01) */

/* ----------------------------------------------------------------------------
   FRAME — the full-viewport two-column grid (grid md:grid-cols-2 h-screen). Two
   EQUAL columns on desktop; min-height:100vh so a short form still fills the fold
   and the promo panel spans the whole side (matches the capture's h-screen). Each
   column is minmax(0,1fr) so wide slot content (a long form, a bleeding screenshot)
   shrinks/clips INSIDE its column instead of forcing the page wide. --pm-auth-bp is
   the single-column breakpoint (md, 48rem). The frame is a plain grid wrapper — the
   form panel + promo column carry the landmarks.
   Uses 100dvh where supported (mobile browser chrome) with a 100vh fallback.
   ---------------------------------------------------------------------------- */
.pm-auth {
  --pm-auth-bp: 48rem;                   /* 768px — the md single-column breakpoint (product md:) */
  box-sizing: border-box;
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);  /* two EQUAL columns */
  min-height: 100vh;                     /* h-screen */
  min-height: 100dvh;                    /* dynamic viewport where supported (mobile chrome) */
  min-width: 0;
  background-color: var(--bg);           /* page base behind the panels (flips dark) */
  color: var(--text-primary);
  font-family: var(--font-body, "Inter", system-ui, sans-serif);
}
.pm-auth *, .pm-auth *::before, .pm-auth *::after { box-sizing: border-box; }

/* ============================================================================
   LEFT — WHITE FORM COLUMN. A full-height track hosting the white form PANEL. The
   panel is the surface (bg-white → --surface-1); the form is centered vertically in
   it with an optional pinned top row (a "Back" button) and an optional pinned foot
   (legal / locale / trust). The panel owns its own vertical overflow so a tall form
   scrolls WITHIN the column, never the whole page.
   ============================================================================ */
.pm-auth__form-col {
  display: flex;
  flex-direction: column;
  min-height: 0;                         /* so the panel can scroll, not the column */
  min-width: 0;
}

/* THE WHITE PANEL (bg-white → --surface-1). A raised white surface that FLIPS to the
   dark layer-01 (--deep-2) under [data-theme="dark"] — this is the surface a user
   reads the form on, so it must never be white-on-white in dark. A landmark
   (<main>) in markup. Comfortable responsive gutters via clamp on the --space ramp
   endpoints (mobile → desktop); the inner body caps the reading measure. */
.pm-auth__panel {
  display: flex;
  flex-direction: column;
  flex: 1 1 auto;
  min-height: 0;
  min-width: 0;
  overflow-y: auto;                      /* tall forms scroll inside the panel */
  overflow-x: hidden;
  overscroll-behavior: contain;
  background-color: var(--surface-1);    /* bg-white → raised panel (flips to --deep-2) */
  color: var(--text-primary);
  /* gutter grows mobile→desktop between two --space endpoints (no raw px) */
  padding: clamp(var(--space-6), 6vw, var(--space-8));
}

/* OPTIONAL TOP ROW — pinned above the centered form (the captured "← Back" on the
   forget screen, or a small logo). A quiet leading row; it does NOT take part in the
   vertical centering (flex:none). Consumers drop a `.pm-btn` "Back" here. */
.pm-auth__panel-top {
  flex: none;
  display: flex;
  align-items: center;
  gap: var(--space-2);
  min-width: 0;
  margin-bottom: var(--space-6);         /* separation from the centered body */
}

/* BODY — the vertically-CENTERED form region. Grows to fill the panel (flex:1) and
   centers its single child (the form) — the captured "space-y-6 justify-center
   flex-1". Centering is done with AUTO block-margins on the form (see .pm-auth__fields
   below), NOT `justify-content:center`: a centered flex child TALLER than this scroll
   container would have its TOP clipped and unreachable by the panel's overflow scroll
   (the classic flex-centering-in-a-scroller pitfall). Auto margins center when there is
   spare room yet collapse to 0 when the form overflows, so the panel's overflow-y can
   scroll all the way to the form's top edge. */
.pm-auth__body {
  flex: 1 1 auto;
  min-height: 0;
  min-width: 0;
  display: flex;
  flex-direction: column;
}

/* THE FORM — heading + lead + fields + actions in one vertical stack with the
   captured space-y-6 rhythm. Capped to a comfortable reading measure and CENTERED
   horizontally within the white half — the captures wrap the form column in
   `flex items-center flex-1 justify-center` (004-forget/dom.html), so the ~416px
   form block sits symmetric in the white panel, not pinned to the inline-start
   edge. A real <form> element. */
.pm-auth__fields {
  display: flex;
  flex-direction: column;
  gap: var(--space-5);                   /* space-y-6 → 24px between form blocks (--space-5) */
  width: 100%;
  max-width: 26rem;                      /* ~416px reading measure (capture ≈ that) */
  min-width: 0;
  margin-block: auto;                    /* AUTO block-margins = scroll-safe vertical centering
                                            (see .pm-auth__body): centers with spare room, yet
                                            collapses so a tall form can scroll to its top. */
}

/* Horizontal placement of the form within the panel. Default CENTERED (matches the
   captured `items-center … justify-center` wrapper). Exposed via --pm-auth-align so a
   consumer can pin it start (--pm-auth-align:0) without editing this file:
     centered (default) → margin-inline: auto
     start-aligned       → margin-inline: 0 auto 0 0   i.e. set --pm-auth-align:0. */
.pm-auth__fields { margin-inline: var(--pm-auth-align, auto); }

/* HEADING — the screen title ("Login" / "Forgot Password"). Ink is the primary text
   role (flips). Size/weight come from the consumer's chosen typography recipe
   (.pm-text-*) in markup; this rule only owns the ink + tight margins so the title
   sits close to its lead. */
.pm-auth__heading {
  margin: 0;
  color: var(--text-primary);
  /* NO letter-spacing here (2026-08-01). Tracking is SIZE-SPECIFIC in the ramp, and
     this rule does not own the size — the consumer's .pm-text-* / .pm-type-* class
     does, and it brings that style's own tracking with it. The old bare −0.028em was
     a fixed value applied to whatever size landed here (T3-TRACK-WRONG). */
  text-wrap: balance;
}

/* LEAD — optional supporting line under the heading (forget: "Enter your email
   address and we'll send you a recovery code."). Secondary ink; sits tight under the
   heading via a NEGATIVE-free small gap: it lives in its own tiny stack with the
   heading (consumer wraps heading+lead in .pm-auth__intro when both exist). */
.pm-auth__lead {
  margin: 0;
  color: var(--text-secondary);
}

/* INTRO GROUP — optional wrapper pairing heading + lead so they sit tight (small
   gap) while the outer form keeps its space-y-6 between BLOCKS. Use when a lead
   exists; otherwise put the heading directly in the form. */
.pm-auth__intro {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);                   /* tight heading↔lead */
  min-width: 0;
}

/* SUBMIT (block width) — used WITH the button component:
     class="pm-btn pm-btn--filled pm-btn--primary pm-btn--lg pm-auth__submit"
   button.css owns the fill/height/focus-ring; this modifier ONLY makes it span the
   form column (the captured login/recovery buttons are full-width). Nothing about
   the button's colour/shape is restated here. */
.pm-auth__submit {
  width: 100%;
}

/* INLINE LINK — "Forget your password?" / "Back to login". A real <a>: underlined
   INK text, NOT a pill/button. Sits inline in the form flow (e.g. right under the
   password field). Two-layer focus ring on keyboard focus (house recipe) offset
   against the panel surface.
   2026-08-03 — FOUNDER RULING #3, OPTION A: accent magenta is banned as small text,
   so this 13.5px link moved off --accent onto an ink role in BOTH themes. The
   PERMANENT underline (already here, offset 2px) is now the link's whole
   affordance, which is exactly the .pm-detail-list__add pattern. Hover keeps its
   direction — accent→accent-hover RAISED contrast in both themes, and
   secondary→primary raises it too: light 9.31→15.50 on the plate, dark 7.62→14.27
   on the card. */
/* → body/strong. The link declared NO size at all, so it rendered at the 16px
   document default with no tracking and no line-height (T1/T2/T4). */
.pm-auth__link {
  align-self: flex-start;
  color: var(--text-secondary);          /* WAS --accent #d342f0 (3.05-3.62 light, banned). Ink role, flips: #353c4d light / #B4BFC7 dark — AA on every plane in both themes */
  font-size: var(--type-body-strong-size);
  font-weight: var(--type-body-strong-weight);
  line-height: var(--type-body-strong-leading);
  letter-spacing: var(--type-body-strong-tracking);
  text-decoration: underline;
  text-underline-offset: 2px;
  border-radius: var(--radius-focus);    /* 3px. WAS --radius-control 12px on a 19.6px line — a capsule, and a half-height lint failure. The comment always said what this is FOR ("only so the focus ring has tidy corners"); it now uses the mark named for that. */
  transition: color var(--motion-duration, 150ms) var(--motion-standard);
}
.pm-auth__link:hover { color: var(--text-primary); }   /* WAS --accent-hover. Hover still RAISES contrast in both themes (#16131c light / #ffffff dark) */
.pm-auth__link:focus-visible {
  outline: 2px solid transparent;        /* forced-colors visible ring */
  outline-offset: 2px;
  box-shadow:
    0 0 0 2px var(--surface-1),          /* panel-surface offset (flips) */
    0 0 0 4px var(--focus-ring);         /* --primary-500 accent ring */
}

/* OPTIONAL FOOT — pinned below the centered form (legal line / locale switcher /
   a trust dot+word). flex:none so it stays out of the vertical centering. Muted ink;
   hosts a .pm-status dot+word for a trust line if the consumer wants one. */
.pm-auth__panel-foot {
  flex: none;
  display: flex;
  align-items: center;
  gap: var(--space-3);
  min-width: 0;
  margin-top: var(--space-6);
  color: var(--text-muted);
}

/* ============================================================================
   RIGHT — BRANDED PROMO COLUMN. A FIXED brand surface (bg-primary-950 → --brand-deep,
   the dark page plane #0f0715) that stays branded in BOTH themes. It is the STAGE hosting the
   consumed auth-brand-panel (.pm-brandpanel) — the sail motif, brand glow, repeating-
   wordmark watermark, wordmark lockup and bleeding product screenshot ALL live in that
   sibling component, dropped in here (never re-implemented on .pm-auth__* parts).
   overflow:hidden clips the art so the page never scrolls sideways. Decorative by
   default (the login works without it) — the consumer decides whether to label it.
   ============================================================================ */
.pm-auth__promo-col {
  position: relative;                    /* positioning context for the consumed brand-panel art */
  display: flex;
  align-items: center;
  justify-content: center;
  min-height: 0;
  min-width: 0;
  overflow: hidden;                      /* clip the brand-panel art + bleed (no horizontal page scroll) */
  isolation: isolate;
  color: var(--text-on-dark);            /* white ink on the brand material (both themes) */
  background-color: var(--brand-deep);   /* near-black brand base (see DARK) */
  /* LIT DARK MATERIAL (not a flat purple bath): a restrained magenta key-light
     top-right + a purple fill bottom-left over the near-black base — matches the
     consumed .pm-brandpanel so a dropped-in panel is seamless, and a bare promo
     column already reads premium. */
  /* 2026-08-02 — the two accent stops were 24% / 38% while the panel they must match
     is 26% / 40%, so the comment above ("matches the consumed .pm-brandpanel") was
     false and a bare stage sat a shade flatter than a filled one. Now byte-identical
     to auth-brand-panel.css: same geometry, same stops, same plane pair. */
  background-image:
    radial-gradient(120% 90% at 92% 8%, color-mix(in srgb, var(--brand-glow) 26%, transparent) 0%, transparent 46%),
    radial-gradient(120% 110% at 4% 108%, color-mix(in srgb, var(--primary-800) 40%, transparent) 0%, transparent 50%),
    linear-gradient(180deg, var(--brand-lift) 0%, var(--brand-deep) 60%);
  /* 2026-07-29 — inner shadows removed file-wide (Figma parity).
     The lit top edge + edge vignette were the only material inset shadows in
     components/; every other `inset` here is a focus ring or an accent rail
     and survives untouched. */
}
/* blueprint grid texture behind whatever brand content is dropped in */
.pm-auth__promo-col::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 0;
  pointer-events: none;
  background-image:
    linear-gradient(to right, color-mix(in srgb, var(--text-on-dark) 4%, transparent) 1px, transparent 1px),
    linear-gradient(to bottom, color-mix(in srgb, var(--text-on-dark) 4%, transparent) 1px, transparent 1px);
  background-size: 44px 44px;
  -webkit-mask-image: radial-gradient(120% 100% at 70% 30%, black 0%, transparent 72%);
          mask-image: radial-gradient(120% 100% at 70% 30%, black 0%, transparent 72%);
}
.pm-auth__promo-col > * { position: relative; z-index: 1; }

/* ============================================================================
   PROMO-LEFT MIRROR — .pm-auth--promo-left swaps the columns: promo on the LEFT,
   form on the RIGHT. Order via `order` so the SAME source order (form first, promo
   second) works for both — no markup reorder needed, and the DOM/reading order stays
   form-first (better for AT). Useful as a variant and for RTL taste.
   ============================================================================ */
.pm-auth--promo-left .pm-auth__form-col  { order: 2; }
.pm-auth--promo-left .pm-auth__promo-col { order: 1; }

/* ============================================================================
   RESPONSIVE — SINGLE-COLUMN COLLAPSE below --pm-auth-bp (768px). The grid drops to
   ONE column and the promo column is hidden (product `hidden md:flex`); the white
   form panel fills the viewport. Desktop shows BOTH equal columns.

   The grid-track collapse is keyed to the VIEWPORT `@media`: .pm-auth is, by contract,
   the full-viewport page frame (viewport width == component width), and — critically —
   an element that declares `container-type: inline-size` is NOT reliably restyled by
   its OWN size container query (Chromium ignores a `grid-template-columns` override on
   the container element inside its own `@container` block, since that would feed back
   into the queried axis). Verified empirically: keying the collapse to `@container`
   alone left the frame at two 187.5px columns at a 375px viewport while only the
   descendant promo hid — a broken half-empty mobile layout. So the frame collapse uses
   `@media`, which always applies.

   The `.pm-auth` is ALSO a size container (below) purely so DESCENDANT container
   queries (the promo hide) still track the COMPONENT width when the scaffold is ever
   embedded narrower than the viewport — a legitimate descendant-only use that the
   self-styling limitation does not affect.
   ============================================================================ */
.pm-auth { container-type: inline-size; container-name: pm-auth; }

/* Frame grid collapse — VIEWPORT-keyed (always applies; the frame is the page). */
@media (max-width: 48rem) {
  .pm-auth { grid-template-columns: minmax(0, 1fr); }  /* one column */
  .pm-auth__promo-col { display: none; }               /* promo hidden on mobile */
}

/* Descendant enhancement — when the scaffold is EMBEDDED in a box narrower than the
   viewport, hide the promo based on the COMPONENT width too (targets a descendant, so
   the self-styling limitation does not apply). The grid stays 2-col in this embedded
   case, but with the promo hidden the form column fills the pair — acceptable, and the
   common full-page case is fully handled by the @media above. */
@container pm-auth (max-width: 48rem) {
  .pm-auth__promo-col { display: none; }
}

/* ----------------------------------------------------------------------------
   FORCED COLORS (Windows High Contrast) — the promo panel's brand fill + glow are
   colour cues the OS palette flattens; the white form panel and its ink map to the
   system Canvas/CanvasText automatically. Give the two columns a system border seam
   so the split stays legible, and ensure the promo ink stays on the system canvas.
   ---------------------------------------------------------------------------- */
@media (forced-colors: active) {
  .pm-auth__promo-col {
    border-inline-start: 1px solid CanvasText;
    color: CanvasText;
  }
  .pm-auth--promo-left .pm-auth__promo-col {
    border-inline-start: 0;
    border-inline-end: 1px solid CanvasText;
  }
}

/* ----------------------------------------------------------------------------
   REDUCED MOTION — the only motion here is the inline link's colour transition;
   disable it for users who opt out. Mirrors the family convention (card / list /
   master-detail-layout): `transition: none`. (The promo art is static — no animation.)
   ---------------------------------------------------------------------------- */
@media (prefers-reduced-motion: reduce) {
  .pm-auth__link { transition: none; }
}

/* ============================================================================
   DARK — the split behaves ASYMMETRICALLY, by design:

   • LEFT form column: every colour is a semantic ROLE (--bg, --surface-1,
     --text-primary/-secondary/-muted, --accent, --focus-ring) or a color-mix of a
     role, so [data-theme="dark"] flips it via tokens-semantic.css — the white panel
     → --deep-2 (layer-01), ink → white/neutral-300, the link stays accent #d342f0,
     the consumed text-field / button / status flip on their own roles. No
     white-on-white.

   • RIGHT promo column: it is a BRAND surface (--brand-deep, the dark page plane
     #0f0715) and stays branded in BOTH themes — a dark-mode login must NOT turn the
     brand panel into plain layer-01 grey. --brand-deep / --brand-glow are fixed
     brand primitives that do NOT repoint under [data-theme="dark"]; the promo ink is
     --text-on-dark (white) in both. So in light mode you get white-form ↔ brand-panel;
     in dark you get deep-form ↔ (same) brand-panel — the brand column is the constant.

   VERIFIED in _preview.html (the [data-theme="dark"] copy) and its screenshot.
   ============================================================================ */

/* FIXED BRAND PRIMITIVES for the promo panel. Defined on .pm-auth so they are scoped
   to this component and can be overridden per-instance, but they intentionally do NOT
   have a [data-theme="dark"] override — the brand column is theme-invariant.
     --brand-deep = --deep #0f0715, the dark PAGE plane  (RESTATED 2026-08-02: this
                    block still said "--primary-950 #47034F" from before the
                    2026-07-29 plane move. The captured product base WAS
                    bg-primary-950 #47034F; the approved ladder replaced that purple
                    bath with the five-plane deep ramp, and the code has painted
                    --deep since. The comment was the stale half, not the value.)
     --brand-lift = --deep-2 #1e1029, the dark TRAY plane (the lit top of the material)
     --brand-glow = --primary-500 #d342f0, the ONE magenta light. It stands in for the
                    capture's #810E8F blur-[200px] orb — a ramp stop, not a raw hex.
   All three are brand values, identical in light + dark (that is the point). */
.pm-auth {
  --brand-deep: var(--deep);          /* #0f0715 — the dark PAGE plane; magenta reads as a light, not a bath (was #0b0410 before the 2026-07-29 plane move) */
  --brand-lift: var(--deep-2);        /* #1e1029 — the dark TRAY plane; the lit corner of the material. 2026-08-02: was var(--deep-3), the DEPRECATED alias tokens.css:143 names this file as a remaining reader of. Same value, no visual change — the deprecated read is gone. */
  --brand-glow: var(--primary-500);   /* #d342f0 — the one magenta accent/light */
}

/* Explicit guard: if any ancestor sets [data-theme="dark"], re-assert the brand
   surface on the promo column so a future/global "flip every surface" rule can't
   accidentally grey it out. The ink stays white. (Belt-and-suspenders — the roles
   above never touch --brand-*, but this makes the intent un-overridable.) */
[data-theme="dark"] .pm-auth__promo-col {
  background-color: var(--brand-deep);
  color: var(--text-on-dark);
}

/* ============================================================================
   A11y contract (the styles assume this markup — set in the story / consumer):
     frame   <div class="pm-auth">  — a plain grid wrapper (NOT a landmark itself).
     form    <div class="pm-auth__form-col"> → <main class="pm-auth__panel"> — the
             form panel is the page's MAIN landmark. Inside:
               <h1 class="pm-auth__heading"> names the screen ("Login").
               <form class="pm-auth__fields" aria-labelledby="{h1 id}"> holds the
               text-field controls (each a real <label for>/<input> from text-field),
               the submit <button type="submit">, and the inline <a class="pm-auth__link">.
               A "Back" affordance in .pm-auth__panel-top is a real <button>/<a> with
               an accessible name ("Back").
     promo   <aside class="pm-auth__promo-col"> — the branded panel. DEFAULT: purely
             decorative (the login is fully usable without it), so mark the aside (or
             its inner art) aria-hidden="true" AND give the logo SVG an empty/absent
             accessible name there. If the panel instead carries a real marketing
             message the consumer wants announced, drop aria-hidden and label the logo.
             The consumed brand-panel art (sail / glow / watermark / screenshot) is
             ALWAYS decorative (aria-hidden).
     link    the inline recovery/back link is underlined text (not colour-only) and
             keyboard-focusable with the two-layer ring.
     trust   an optional .pm-status dot+word in .pm-auth__panel-foot carries role="status"
             + its visible WORD names the state (NOT colour-only); the dot is aria-hidden.
   NOT colour-only: the split's meaning is structural (form vs brand), the link is
   underlined, status is a WORD. The form panel is the single scroll region; the promo
   art never scrolls (clipped). Focus order is form-first (DOM order), independent of
   the .pm-auth--promo-left visual swap (which reorders via `order` only).
   ============================================================================ */

/* ============================================================================
   OPEN AGAINST THE TOKEN LAYER — 2026-08-02, NOT patched here (raised, not hidden)

   1. LIGHT PAGE PLANE HAS NO TOKEN. The approved light ladder is
      page #f4f2f6 · tray #faf8fc · plate #efeaf3 · card #ffffff. tokens.css carries
      only --paper #faf8fc (tray) and --paper-2 #ffffff (card); #f4f2f6 and #efeaf3
      appear nowhere in tokens/. So --bg — the role NAMED "page/body background" —
      resolves to the TRAY value in light, and .pm-auth paints its page gutter one
      step light. This is the same defect the Figma diff logs against app-shell
      (docs/2026-08-01-figma-vs-code-diff.md:49,76 "one step off the ramp"), and it
      is not fixable in a component: the only way out here would be a raw #f4f2f6,
      which the file's own "ZERO new hex" contract forbids. Dark is already correct
      (--bg → --deep #0f0715 = page). Token-layer / founder call.

   2. THE INLINE LINK MISSES AA. .pm-auth__link is --accent #d342f0 on the white
      panel --surface-1 #ffffff = 3.62:1, below the 4.5:1 floor for its 13.5px
      body/strong type. It is underlined, so it is not colour-only, and --accent for
      a text link is an existing house pattern (detail-list.css:299 does the same) —
      which is exactly why this is a LIBRARY decision, not a local edit. The next
      stop down, --accent-hover #bb25d4, measures 4.85:1 and would clear it.
      Presented, not silently changed.
   ============================================================================ */
