/* ======================================================================
   Maritime Passport — Partner Portal PRIMITIVES layer (MAR-816).

   The shared material and decoration: the panel material, buttons and
   links, status pills, notes, scope chips, the secret reveal and its copy
   control, the two-column hero, the monogram tile and the public intake
   outcome card.

   Anything a second screen needed and was promoted out of a per-screen
   sheet lands here — unless it belongs to one of the sibling layers, which
   are separate files precisely so unrelated partner tickets stop
   contending for one sheet: collections and metrics go to
   portal.data.css, controls to portal.forms.css, floating surfaces to
   portal.overlay.css.

   Tokens come from portal.css, linked ahead of this file.

   * a NEW primitive family gets its own portal.<family>.css, linked from
     partner/_head.html — it does not grow this file (MAR-816).
   ====================================================================== */

/* ════ panel primitive (Design 0.1) ════ */
.lg { /* the material: opaque white, warm hairline, flat — no shadow */
  background:var(--bg-surface);
  border:1px solid var(--mp-card-border);
  border-radius:var(--r-lg);
}
/* the panel's in-product card body (MAR-784, screen 10): the portal
   density padding step and a vertical stack, so restyled screens carry no
   inline style attributes for it. A form inside the card is layout-neutral
   — it stacks its own children on the same rhythm. */
.pp-card { padding:var(--pp-card-padding); display:flex; flex-direction:column;
           gap:16px; }
.pp-card form { display:flex; flex-direction:column; gap:16px; }
/* Same origin trap as `.pp-note` below (MAR-976): the `display:flex` above is
   an author rule and beats the UA's [hidden] { display:none }, so a form the
   page reveals on demand renders permanently open once it moves into the card
   body. Caught on /web/partner/api-keys adopting this primitive (MAR-975) —
   its create form is `hidden` until the header CTA opens it. Fixed on the
   primitive, not the page: api-keys.html sets no `screen_css`, and every
   screen the MAR-646 re-skin moves into `.pp-card` inherits the same trap. */
.pp-card form[hidden] { display:none; }

/* ── buttons — full pills, flat fills: no border on the primary, no
      shadow, no gradient (BRIEF § Visual direction · Action).

      TWO AXES, ONE MODIFIER EACH (MAR-834). The base rule below and the one
      size modifier own the BOX — height, padding, type. The pigment
      modifiers own the FILL and the LABEL COLOUR, and nothing else. That
      separation is what makes the brand owner's rule structural rather than
      per-template: a bronze CTA is always the same size as the white
      secondary beside it (settled 2026-08-03), because at a given size
      modifier there is no rule left that could make the two differ. The
      base carries Button.jsx SIZES.sm and the weight from its BASE, so the
      pigments need no typography of their own. Adding a metric to a pigment
      rule re-opens the defect this comment replaces.

      WHICH STEP IS THE DEFAULT (MAR-875). The base is SIZES.sm — 45px — and
      the 61px hero step is opt-in below. The in-app portal is where a bare
      `class="pp-btn"` actually gets written, and 45px is the standard height
      there; 61px belongs to the five public marketing surfaces, which now
      name it. Their fixed-header CTA is the exception that proves the split —
      it was the small step before and stays the base after, so it names
      nothing. The argument for flipping rather than patching screens: a new
      surface inherits whatever the default is, and while the default was the
      hero step `_invite_dialog.html` shipped four 61px buttons the day it
      was created without anyone choosing that.
      (Height, padding and type come from the bundle; the icon gap stays at
      the portal's existing 8px rather than the bundle's 12/10 — this is a
      migration of the size axis, not a restyle of the one button that has
      an icon.) ── */
.pp-btn { display:inline-flex; align-items:center; justify-content:center; gap:8px;
  font-family:inherit; font-size:15px; font-weight:500; line-height:21px; letter-spacing:-.005em;
  height:45px; padding:0 24px; border-radius:var(--r-pill); border:1px solid transparent; cursor:pointer;
  text-decoration:none; /* .pp-btn renders on <a> too (MAR-667 hero CTAs) */
  transition:transform 140ms var(--ease-out), background 140ms; }
.pp-btn:hover { transform:translateY(-1.5px); }
.pp-btn:focus-visible { outline:2px solid var(--mp-navy); outline-offset:3px; }
.pp-btn[disabled] { opacity:.45; cursor:not-allowed; transform:none; }
/* The one size step above the base (Button.jsx SIZES.md) — the public hero
   surfaces opt into it. Named `--md` to keep the 1:1 mapping with the
   bundle's own SIZES keys, which have exactly `md` and `sm`; that fidelity
   is worth more than matching the portal's local `--lg`-means-bigger habit,
   because this comment's whole job is to be checkable against Button.jsx.
   Metrics only — every pigment resolves its own fill through the rules that
   follow. */
.pp-btn--md { height:61px; padding:0 36px;
  font-size:18px; line-height:25.2px; }
/* the bronze CTA — the one action that matters per screen. Label is white
   (SETTLED: the 3.61:1 white-on-bronze contrast is accepted deliberately by
   the brand owner — at 18px/500 originally, extended to the 15px step on
   2026-08-03, MAR-795; that step is the base since MAR-875). Fill and label
   colour live here ONLY, so both CTA sizes resolve to the same bronze by
   construction. */
.pp-btn--cta { background:var(--mp-bronze); color:var(--text-inverse); }
.pp-btn--cta:hover { background:var(--mp-bronze-hover); }
.pp-btn--deep { background:var(--mp-navy); color:var(--text-inverse); }
.pp-btn--glass { background:var(--bg-surface); color:var(--mp-navy);
  border:1.5px solid var(--mp-card-border); }
.pp-btn--quiet { background:transparent; color:var(--ink-2); }
.pp-btn--quiet:hover { background:var(--tint-hover); color:var(--ink); }
.pp-btn--danger { background:transparent; color:var(--status-danger-fg);
  border-color:color-mix(in srgb, var(--status-danger-fg) 32%, transparent); }
.pp-acts { display:flex; flex-wrap:wrap; gap:10px; align-items:center; }
.pp-link { font-size:13.5px; color:var(--mp-navy); text-decoration:underline;
           text-underline-offset:3px; text-decoration-thickness:1.2px; }

/* ── pills ── */
.pp-pill { display:inline-flex; align-items:center; gap:6px; padding:5px 12px;
  border-radius:var(--r-pill); font-size:11.5px; font-weight:600; white-space:nowrap; }
.pp-pill::before { content:""; width:6px; height:6px; border-radius:50%; background:currentColor; flex:none; }
/* Status pigments are the SHARED triples — a compliance state must read
   identically here, in the admin console and on the seafarer surfaces. */
.pp-pill--ok { background:var(--status-success-bg); color:var(--status-success-fg); }
.pp-pill--warn { background:var(--status-warning-bg); color:var(--status-warning-fg); }
.pp-pill--stop { background:var(--status-danger-bg); color:var(--status-danger-fg); }
.pp-pill--info { background:var(--status-info-bg); color:var(--status-info-fg); }
.pp-pill--neut { background:var(--status-neutral-bg); color:var(--status-neutral-fg);
                 border:1px solid var(--rule); }

/* ── notes ── */
.pp-note { display:flex; gap:12px; align-items:flex-start; padding:14px 17px;
  border-radius:var(--r-md); font-size:13.5px; border:1px solid; }
/* `display:flex` above is an author rule and beats the UA's
   [hidden] { display:none } — origin, not specificity. Without this, a note
   marked hidden paints an empty coloured bar (MAR-976, /web/partner/api-keys).
   Previously patched per page in portal.invitations.css and portal.sign-in.css;
   fixed at the primitive here. */
.pp-note[hidden] { display:none; }
.pp-note__i { font-weight:700; flex:none; }
.pp-note--ok { background:var(--status-success-bg);
  border-color:color-mix(in srgb, var(--status-success-fg) 24%, transparent); }
.pp-note--ok .pp-note__i { color:var(--status-success-fg); }
.pp-note--warn { background:var(--status-warning-bg);
  border-color:color-mix(in srgb, var(--status-warning-fg) 24%, transparent); }
.pp-note--warn .pp-note__i { color:var(--status-warning-fg); }
.pp-note--stop { background:var(--status-danger-bg);
  border-color:color-mix(in srgb, var(--status-danger-fg) 24%, transparent); }
.pp-note--stop .pp-note__i { color:var(--status-danger-fg); }
/* The fourth pigment (MAR-1011), completing the triple the pill above already
   had, from the same shared status tokens. It exists because some outcomes are
   neither a success nor a problem: a voucher refused because the partner's
   EXISTING rate is better is RFC-011's non-stacking rule working as designed —
   green would claim a change that did not happen, red would call a protected
   rate a failure. */
.pp-note--info { background:var(--status-info-bg);
  border-color:color-mix(in srgb, var(--status-info-fg) 24%, transparent); }
.pp-note--info .pp-note__i { color:var(--status-info-fg); }

/* ── scope chips (from the design mock) — shared: the API keys create form
      (MAR-660) and the public landing picker (MAR-712) both render them ── */
.pp-scopes { display:flex; flex-wrap:wrap; gap:12px 22px; }
.pp-scope { display:flex; align-items:center; gap:9px; font-size:13px; }
/* The same origin trap as `.pp-note` and `.pp-card form` above (MAR-976), on a
   fourth primitive. MAR-1140's kind selector hides individual scope chips: an
   issuing key carries `certificates:issue` alone and a standard key may never
   carry it, so picking a kind takes the other's chips out of the choice. Without
   this reset the chips stay on screen and the partner is offered a selection the
   server refuses — the exact round trip the client-side mirror exists to save.
   (The box is unchecked and disabled as well, so nothing illegal could be
   SUBMITTED either way; what leaked was the offer.) */
.pp-scope[hidden] { display:none; }
.pp-scope code { font-family:var(--mono); font-size:11.5px; }

/* ── secret reveal: light, with the amber stripe carrying the weight
      (MAR-660; ported from docs/design/partner-portal screen 16 — no dark
      slab: emphasis is the stripe + warning + explicit dismissal) ── */
.pp-reveal { border-radius:var(--r-md); background:var(--bg-surface);
  border:1px solid var(--mp-card-border); border-left:3px solid var(--mp-gold);
  padding:16px 18px; display:flex; flex-direction:column; gap:11px; }
.pp-reveal__l { font-size:10px; font-weight:700; letter-spacing:.13em; text-transform:uppercase;
                color:var(--mp-gold-600); }
.pp-keyrow { display:flex; align-items:center; gap:10px; flex-wrap:wrap; }
.pp-secret { flex:1 1 280px; min-width:0; font-family:var(--mono); font-size:13.5px;
  color:var(--ink); background:var(--mp-panel); border:1px solid var(--rule);
  border-radius:var(--r-sm); padding:12px 14px; overflow-x:auto; white-space:nowrap;
  letter-spacing:.02em; }

/* ── copy button: the convention every credential portal uses ── */
.pp-copy { display:inline-flex; align-items:center; gap:7px; flex:none;
  font-family:inherit; font-size:12.5px; font-weight:600; line-height:1;
  padding:11px 15px; border-radius:var(--r-sm); cursor:pointer;
  background:var(--bg-surface); color:var(--ink); border:1px solid var(--mp-card-border);
  transition:transform 140ms var(--ease-out); }
.pp-copy:hover { transform:translateY(-1px); }
.pp-copy:focus-visible { outline:2px solid var(--mp-navy); outline-offset:2px; }
.pp-copy svg { width:14px; height:14px; flex:none; }
/* applied at runtime by the copy script — not present in static markup */
.pp-copy--done { background:var(--status-success-bg); color:var(--status-success-fg);
  border-color:color-mix(in srgb, var(--status-success-fg) 28%, transparent); }
.pp-copy--ghost { background:transparent; border-color:var(--rule);
                  color:var(--ink-2); padding:8px 12px; font-size:12px; }
/* .pp-reveal is opaque white, so a same-white control needs its own step. */
.pp-reveal .pp-copy { background:var(--mp-beige);
                      border-color:color-mix(in srgb, var(--mp-navy) 22%, transparent);
                      color:var(--mp-navy); }
.pp-reveal .pp-copy:hover { background:var(--mp-beige-2); }
.pp-reveal .pp-copy--done { background:var(--status-success-bg);
                            border-color:color-mix(in srgb, var(--status-success-fg) 28%, transparent);
                            color:var(--status-success-fg); }

/* ── first sign-in hero (MAR-667, bundle screen 7) ── */
.pp-2col { display:grid; grid-template-columns:1.15fr .85fr; gap:24px; align-items:center; }
@media (max-width:820px) { .pp-2col { grid-template-columns:1fr; } }

/* shared monogram tile — team member rows + the org picker */
.pp-mono-sm { width:34px; height:34px; border-radius:10px; display:grid; place-items:center;
  color:var(--text-inverse); font-size:12px; font-weight:700; flex:none; font-style:normal;
  background:var(--mp-navy); }

/* ── public intake outcome card (MAR-780, BRIEF screen 21) — the single
      centred card the three outcome pages share (received, verify,
      confirm-invalid). Straight into the shared layer: three screens render
      it, satisfying the promote-on-second-use rule above. The panel material
      comes from the primitive these compose with; this rule owns only the
      measure and rhythm the templates used to carry as inline styles. The
      danger hook derives its tone from the settled status triple — the
      refusal page's key, never a fourth treatment. ── */
.pp-outcome { width:100%; max-width:640px; margin:0 auto;
  padding:var(--pp-card-padding); display:flex; flex-direction:column; gap:18px; }
.pp-outcome--narrow { max-width:520px; }
.pp-outcome--danger { border-left:3px solid var(--status-danger-fg); }
.pp-outcome__steps { margin:0; padding-left:22px;
  display:flex; flex-direction:column; gap:10px; }
