/* ================================================================
   portal.css — Client Portal
   Authored ENTIRELY against the engine's theme CSS variables emitted
   by theme_css_vars() (header.php injects them inline). NO hardcoded
   brand palette, NO dark/light toggle, NO custom display font — the
   portal inherits whatever theme the owner has active.

   Engine vars consumed (see admin/functions.php theme_css_vars()):
     --bg-page --bg-section --bg-header --bg-nav-bar --bg-footer
     --accent --text-primary --text-secondary --text-inverse
     --font-body --font-heading --font-nav
     --color-navy --color-slate --color-sand --color-ivory --color-brass

   Derived --portal-* tokens below translate that surface into the
   component vocabulary the portal pages use (cards, borders, tints,
   shadows). color-mix() does the derivation with a flat fallback for
   engines/browsers without support. Status signal colors (success /
   warning / error / info) are functional, not part of the theme
   palette, so they are fixed accessible values.
   ================================================================ */

:root {
  /* --- surfaces, mapped straight onto engine roles --- */
  --portal-bg:          var(--bg-page, #F4EFE6);
  /* Flat white card surface from the template (--bg-card), NOT the sand accent
     (--bg-section). Using the accent here made cards and inputs share a fill. */
  --portal-bg-raised:   var(--bg-card, #fff);
  --portal-input-bg:    var(--bg-card, #fff);   /* inputs always a clean light fill, set apart by their border */
  --portal-surface:     var(--bg-section, #F0F0F0);

  /* --- text --- */
  --portal-text:        var(--text-primary, #151C28);
  --portal-text-muted:  var(--text-secondary, #5A6473);

  /* --- accent + tints derived from the active accent --- */
  --portal-accent:        var(--accent, #A9824A);
  --portal-accent-hover:  color-mix(in srgb, var(--accent, #A9824A) 82%, #000 18%);
  --portal-accent-tint:   color-mix(in srgb, var(--accent, #A9824A) 12%, transparent);
  --portal-accent-tint-2: color-mix(in srgb, var(--accent, #A9824A) 20%, transparent);
  --portal-on-accent:     var(--text-inverse, #FFFFFF);

  /* --- structure (borders/shadows derived from text color) --- */
  --portal-border:      color-mix(in srgb, var(--text-primary, #151C28) 14%, transparent);
  --portal-border-soft: color-mix(in srgb, var(--text-primary, #151C28) 8%, transparent);
  --portal-shadow:      0 1px 3px rgba(0,0,0,.06), 0 4px 12px rgba(0,0,0,.04);
  --portal-shadow-md:   0 4px 16px rgba(0,0,0,.08), 0 8px 32px rgba(0,0,0,.06);

  /* --- typography (inherit engine fonts) --- */
  --portal-font:         var(--font-body, system-ui, -apple-system, sans-serif);
  --portal-font-heading: var(--font-heading, var(--font-body, system-ui, sans-serif));

  /* --- radii — mapped to the template's radius scale (4 / 8 / 12) --- */
  --portal-radius:    var(--radius-md, 8px);
  --portal-radius-sm: var(--radius-sm, 4px);
  --portal-radius-lg: var(--radius-lg, 12px);

  /* --- layout --- */
  --portal-header-h: 56px;
  --portal-max:      960px;

  /* --- functional signal colors (not theme palette) --- */
  --portal-success:        #047857;
  --portal-success-bg:     #ecfdf5;
  --portal-success-border: #6ee7b7;
  --portal-error:          #dc2626;
  --portal-error-bg:       #fef2f2;
  --portal-error-border:   #fca5a5;
  --portal-warning:        #b45309;
  --portal-warning-bg:     #fffbeb;
  --portal-info:           #1d4ed8;
  --portal-info-bg:        #eff6ff;

  /* Inline status text (e.g. saved-note "Saved", "Acknowledged") that sits
     directly on a theme surface, not inside a tinted alert chip. A flat
     success/error hex can only pass on ONE of light/dark themes, so blend the
     signal hue toward the active text color: stays >=4.5:1 on BOTH the light
     and dark theme surfaces. */
  --portal-status-ok:     color-mix(in srgb, #16a34a 68%, var(--portal-text));
  --portal-status-danger: color-mix(in srgb, #e11d48 68%, var(--portal-text));
}

/* Fallback for engines without color-mix(): fixed neutral border/tints
   so the chrome never collapses to invisible. */
@supports not (background: color-mix(in srgb, red, blue)) {
  :root {
    --portal-accent-hover:  var(--accent, #A9824A);
    --portal-accent-tint:   rgba(0,0,0,.06);
    --portal-accent-tint-2: rgba(0,0,0,.10);
    --portal-border:      rgba(0,0,0,.14);
    --portal-border-soft: rgba(0,0,0,.08);
    /* No mix available — fall back to the fixed functional hues (tuned for the
       default light theme; legacy engines without color-mix ship light themes). */
    --portal-status-ok:     #15803d;
    --portal-status-danger: #be123c;
  }
}

/* Keystone realty palettes set --accent (engine alias) per palette but leave
   the engine theme's --text-inverse intact — that can be a light ivory which,
   on a mid-tone accent (e.g. luxe gold), gives near-invisible button text that
   only "appears" once :hover darkens the fill. Every keystone accent is
   WCAG-verified for WHITE text, so pin on-accent text to white inside the
   portal subtree for guaranteed button/badge contrast on all four palettes. */
[data-keystone] .portal-scope { --portal-on-accent: #fff; }

/* ----------------------------------------------------------------
   Reset
   ---------------------------------------------------------------- */
*,
*::before,
*::after {
  box-sizing: border-box;
  margin: 0;
  padding: 0;
}

html {
  font-size: 16px;
  -webkit-text-size-adjust: 100%;
}

body {
  font-family: var(--portal-font);
  color: var(--portal-text);
  background-color: var(--portal-bg);
  min-height: 100vh;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}

/* Portal content type scale — scoped to .portal-scope so it never shrinks the
   site chrome (header/nav/footer) text on portal pages. */
.portal-scope {
  font-size: 0.9375rem;
  line-height: 1.6;
}

h1, h2, h3, h4, h5, h6,
.portal-page-title,
.portal-card__title,
.portal-stat__value,
.portal-login__heading,
.portal-empty__heading,
.portal-dash-header__greeting {
  font-family: var(--portal-font-heading);
}

/* Accent colour for PROSE/content links only (classless <a> inside cards and
   message bodies). Styled component anchors — buttons, tabs, badges, breadcrumb,
   footer — carry their own class + colour, so they MUST be excluded here: a bare
   `.portal-scope a` (0,1,1) out-specifies `.portal-btn { color }` (0,1,0) and
   paints button text in the accent colour → invisible accent-on-accent fills.
   `a:not([class])` targets only unclassed content links and leaves every
   component to colour itself. */
.portal-scope a:not([class]) {
  color: var(--portal-accent);
  text-decoration: none;
}

.portal-scope a:not([class]):hover {
  text-decoration: underline;
}

img {
  max-width: 100%;
  display: block;
}

:focus-visible {
  outline: 2px solid var(--portal-accent);
  outline-offset: 2px;
}

/* ----------------------------------------------------------------
   Skip link
   ---------------------------------------------------------------- */
.portal-skip-link {
  position: absolute;
  top: -100%;
  left: 16px;
  z-index: 10000;
  padding: 10px 20px;
  background: var(--portal-accent);
  color: var(--portal-on-accent);
  font-weight: 600;
  font-size: 14px;
  border-radius: 0 0 8px 8px;
  text-decoration: none;
}

.portal-skip-link:focus {
  top: 0;
}

/* ----------------------------------------------------------------
   Layout wrapper
   ---------------------------------------------------------------- */
.portal-wrap {
  /* Legacy wrapper. The portal now renders inside the site chrome's .container,
     so this is a passthrough — no max-width and no fixed-header offset. */
  max-width: 100%;
  margin: 0;
  padding: 0;
}

/* ----------------------------------------------------------------
   Secondary portal nav (sits below the site header, inside .container)
   ---------------------------------------------------------------- */
/* Portal shell — desktop two-column: a left section rail + the content. On
   phones the rail is hidden and the same links fold into the site's mobile
   menu overlay (.portal-ovnav), so the page itself stays clean. */
.portal-shell {
  display: grid;
  grid-template-columns: 224px minmax(0, 1fr);
  gap: 36px;
  align-items: start;
  margin-top: 24px;
}
.portal-shell--solo { display: block; }   /* auth pages (login/register): no rail */

.portal-sidebar {
  position: sticky;
  /* Clear the sticky site header so the rail isn't tucked behind it on scroll.
     --portal-sticky-top is measured from #site-header by the footer script (it
     tracks the keystone header's scroll-shrink); 100px is a sane no-JS fallback. */
  top: var(--portal-sticky-top, 100px);
  display: flex;
  flex-direction: column;
  gap: 12px;
  min-width: 0;
  padding-bottom: 28px;   /* breathing room under Sign out vs. whatever sits below the rail */
  max-height: calc(100vh - var(--portal-sticky-top, 100px) - 16px);
  overflow-y: auto;
  scrollbar-width: thin;
}
.portal-sidenav { display: flex; flex-direction: column; gap: 2px; }

.portal-sidenav__link {
  display: flex;
  align-items: center;
  gap: 11px;
  padding: 10px 12px;
  border-radius: var(--portal-radius-sm);
  font-family: var(--font-nav, var(--portal-font, inherit));
  font-size: 14px;
  font-weight: 600;
  color: var(--portal-text-muted);
  text-decoration: none;
  transition: color .15s, background .15s;
}
.portal-sidenav__link svg { width: 18px; height: 18px; flex-shrink: 0; opacity: .85; }
.portal-sidenav__link:hover {
  color: var(--portal-text);
  text-decoration: none;
  background: color-mix(in srgb, var(--portal-text) 5%, transparent);
}
.portal-sidenav__link.active,
.portal-sidenav__link[aria-current="page"] {
  color: var(--portal-accent);
  background: var(--portal-accent-tint);
}
.portal-sidenav__link.active svg,
.portal-sidenav__link[aria-current="page"] svg { opacity: 1; }

.portal-sidenav__foot {
  margin-top: 4px;
  padding-top: 12px;
  border-top: 1px solid var(--portal-border);
}
/* The signed-in name wraps inside the rail; a long name or an email-like
   business name never runs out under the rail's edge. */
.portal-sidenav__who {
  display: block;
  font-size: 12px;
  line-height: 1.45;
  color: var(--portal-text-muted);
  padding: 0 12px 8px;
  white-space: normal;
  overflow-wrap: anywhere;
}
.portal-sidenav__link--signout { color: var(--portal-text-muted); }
.portal-sidenav__link--signout:hover {
  color: var(--portal-error);
  background: color-mix(in srgb, var(--portal-error) 8%, transparent);
}

/* Section nav folded into the site's mobile menu overlay (#nav-overlay). The
   keystone overlay bg is --color-bg (adapts light/dark); the engine default
   overlay is dark navy — so default links = white, keystone links = themed. */
/* Compact 2-column tile grid (not a tall stacked list) so the account section
   stays short and the site nav below it is reachable without a long scroll.
   The label / "signed in" / sign-out span both columns; section links tile. */
.portal-ovnav {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 8px;
  margin: 0 0 1.2rem;
  padding-bottom: 1.15rem;
  color: #fff;
  border-bottom: 1px solid color-mix(in srgb, currentColor 16%, transparent);
}
[data-keystone] .portal-ovnav { color: var(--color-text); }
.portal-ovnav__label {
  grid-column: 1 / -1;
  font-size: .72rem;
  font-weight: 700;
  letter-spacing: .08em;
  text-transform: uppercase;
  opacity: .55;
  margin: 1rem 0 0;   /* clear of the menu's search field above it */
}
.portal-ovnav__link {
  display: flex;
  align-items: center;
  gap: 10px;
  min-height: 48px;
  padding: 10px 12px;
  font-size: .9rem;
  font-weight: 600;
  color: inherit;
  text-decoration: none;
  border-radius: 12px;
  background: color-mix(in srgb, currentColor 7%, transparent);
  transition: background .15s, color .15s;
}
.portal-ovnav__link svg { width: 18px; height: 18px; flex-shrink: 0; opacity: .8; }
.portal-ovnav__link span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.portal-ovnav__link:hover,
.portal-ovnav__link:focus-visible {
  background: color-mix(in srgb, currentColor 13%, transparent);
  text-decoration: none;
}
.portal-ovnav__link.active,
.portal-ovnav__link[aria-current="page"] {
  color: var(--portal-accent);
  background: color-mix(in srgb, var(--portal-accent) 18%, transparent);
}
.portal-ovnav__link.active svg,
.portal-ovnav__link[aria-current="page"] svg { opacity: 1; }
[data-keystone] .portal-ovnav__link.active,
[data-keystone] .portal-ovnav__link[aria-current="page"] {
  color: var(--color-accent);
  background: color-mix(in srgb, var(--color-accent) 15%, transparent);
}
.portal-ovnav__who { grid-column: 1 / -1; font-size: .8rem; opacity: .55; margin: .35rem 0 0; }
.portal-ovnav__link--signout {
  grid-column: 1 / -1;
  background: transparent;
  min-height: 0;
  padding: 8px 4px;
  opacity: .8;
}
.portal-ovnav__link--signout:hover { background: color-mix(in srgb, currentColor 10%, transparent); }

/* Centred auth card (login / register / forgot / reset) inside the site chrome. */
.portal-auth {
  max-width: 460px;
  margin: 40px auto 56px;
}

/* ----------------------------------------------------------------
   Header / Nav — flat full-width bar
   ---------------------------------------------------------------- */
.portal-header {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  z-index: 110;
  background: var(--portal-bg-raised);
  border-bottom: 1px solid var(--portal-border);
}

.portal-header__inner {
  display: flex;
  align-items: center;
  justify-content: space-between;
  height: var(--portal-header-h);
  max-width: var(--portal-max);
  margin: 0 auto;
  padding: 0 24px;
  gap: 12px;
}

.portal-logo {
  display: flex;
  align-items: center;
  gap: 8px;
  font-weight: 700;
  font-size: 1rem;
  color: var(--portal-text);
  text-decoration: none;
  white-space: nowrap;
  flex-shrink: 0;
  min-width: 0;
}

.portal-logo:hover {
  text-decoration: none;
  color: var(--portal-accent);
}

.portal-logo__mark {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 28px;
  height: 28px;
  background: var(--portal-accent);
  border-radius: 6px;
  color: var(--portal-on-accent);
  flex-shrink: 0;
}

.portal-logo__name {
  font-family: var(--portal-font-heading);
  font-weight: 700;
  font-size: 1rem;
  letter-spacing: -0.01em;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.portal-header__actions {
  display: flex;
  align-items: center;
  gap: 8px;
  flex-shrink: 0;
}

.portal-header__client-name {
  font-size: 0.8125rem;
  color: var(--portal-text-muted);
  white-space: nowrap;
  max-width: 160px;
  overflow: hidden;
  text-overflow: ellipsis;
}

.portal-nav {
  display: flex;
  align-items: center;
  gap: 4px;
  flex-wrap: wrap;
}

.portal-nav__link {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 6px 10px;
  border-radius: 100px;
  font-family: var(--font-nav, var(--portal-font));
  font-size: 13px;
  font-weight: 500;
  letter-spacing: 0.04em;
  color: var(--portal-text-muted);
  text-decoration: none;
  transition: color 0.2s, background 0.15s;
  white-space: nowrap;
  position: relative;
  z-index: 1;
}

.portal-nav__link:hover {
  color: var(--portal-text);
  background: var(--portal-accent-tint);
  text-decoration: none;
}

.portal-nav__link.active,
.portal-nav__link[aria-current="page"] {
  color: var(--portal-accent);
  background: var(--portal-accent-tint);
  font-weight: 600;
}

.portal-nav__link--logout {
  color: var(--portal-text-muted);
}

.portal-nav__link--logout:hover {
  color: var(--portal-error);
  background: var(--portal-error-bg);
}

/* ----------------------------------------------------------------
   Main content area
   ---------------------------------------------------------------- */
.portal-main {
  padding-top: 8px;
  padding-bottom: 48px;
}

/* ----------------------------------------------------------------
   Page title row
   ---------------------------------------------------------------- */
.portal-page-header {
  margin-bottom: 24px;
}

.portal-page-title {
  font-size: 1.5rem;
  font-weight: 700;
  line-height: 1.25;
  color: var(--portal-text);
}

.portal-page-subtitle {
  margin-top: 6px;
  font-size: 0.9375rem;
  color: var(--portal-text-muted);
}

/* ----------------------------------------------------------------
   Card
   ---------------------------------------------------------------- */
.portal-card {
  background: var(--portal-bg-raised);
  border: 1px solid var(--portal-border);
  border-radius: var(--portal-radius);
  padding: 20px;
  margin-bottom: 20px;
}

.portal-card:last-child {
  margin-bottom: 0;
}

.portal-card__title {
  font-size: 1rem;
  font-weight: 700;
  color: var(--portal-text);
  margin-bottom: 16px;
  padding-bottom: 12px;
  border-bottom: 1px solid var(--portal-border);
  display: flex;
  align-items: center;
  gap: 8px;
}

.portal-card__title svg {
  color: var(--portal-accent);
  flex-shrink: 0;
}

/* ----------------------------------------------------------------
   Dashboard greeting header
   ---------------------------------------------------------------- */
.portal-dash-header {
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  gap: 16px;
  flex-wrap: wrap;
  margin-bottom: 24px;
}

.portal-dash-header__greeting {
  font-size: 1.625rem;
  font-weight: 800;
  line-height: 1.15;
  color: var(--portal-text);
  letter-spacing: -0.02em;
}

.portal-dash-header__sub {
  margin-top: 4px;
  font-size: 0.9375rem;
  color: var(--portal-text-muted);
}

/* ----------------------------------------------------------------
   Stats grid — icon-chip metric cards
   ---------------------------------------------------------------- */
.portal-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
  gap: 16px;
  margin-bottom: 24px;
}

.portal-stat {
  display: flex;
  align-items: center;
  gap: 14px;
  background: var(--portal-bg-raised);
  border: 1px solid var(--portal-border);
  border-radius: var(--portal-radius);
  padding: 18px 20px;
  transition: border-color 0.15s;
}
.portal-stat:hover {
  border-color: var(--portal-accent);
}

.portal-stat__icon {
  width: 42px;
  height: 42px;
  border-radius: var(--portal-radius-sm);
  flex-shrink: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  background: var(--portal-accent-tint);
  color: var(--portal-accent);
}

.portal-stat__body { min-width: 0; }

.portal-stat__value {
  font-size: 1.75rem;
  font-weight: 800;
  line-height: 1;
  color: var(--portal-text);
  display: block;
}

.portal-stat__label {
  font-size: 0.75rem;
  font-weight: 600;
  color: var(--portal-text-muted);
  text-transform: uppercase;
  letter-spacing: 0.05em;
  margin-top: 4px;
  display: block;
}

.portal-stat--alert .portal-stat__icon { background: var(--portal-warning-bg); color: var(--portal-warning); }
.portal-stat--alert .portal-stat__value { color: var(--portal-warning); }

/* Dashboard stat strip — compact metric tiles (was previously unstyled). */
.portal-stat-row {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(140px, 1fr));
  gap: 14px;
  margin-bottom: 22px;
}

/* ----------------------------------------------------------------
   Bento grid — dashboard card mosaic (replaces full-width stacks)
   12-col grid with span modifiers; reflows to one column on phones.
   grid-auto-flow:dense lets conditional cards backfill gaps.
   ---------------------------------------------------------------- */
.portal-bento {
  display: grid;
  grid-template-columns: repeat(12, 1fr);
  grid-auto-flow: row dense;
  gap: 18px;
}
.portal-bento > .portal-card {
  margin-bottom: 0;
  height: 100%;
  grid-column: span 12;
}
@media (min-width: 721px) {
  .portal-bento > .portal-card { grid-column: span 6; }   /* default: half */
  .portal-bento > .pb-wide     { grid-column: span 8; }
  .portal-bento > .pb-narrow   { grid-column: span 4; }
  .portal-bento > .pb-full     { grid-column: span 12; }
}

/* ----------------------------------------------------------------
   Filter tabs
   ---------------------------------------------------------------- */
.portal-filter-tabs {
  display: flex;
  align-items: center;
  gap: 2px;
  flex-wrap: wrap;
  margin-bottom: 20px;
  border-bottom: 1px solid var(--portal-border);
}

.portal-filter-tab {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  padding: 9px 14px;
  font-size: 0.875rem;
  font-weight: 500;
  color: var(--portal-text-muted);
  text-decoration: none;
  border-bottom: 2px solid transparent;
  margin-bottom: -1px;
  transition: color 0.15s, border-color 0.15s;
  white-space: nowrap;
}
.portal-filter-tab:hover {
  color: var(--portal-text);
  text-decoration: none;
}
.portal-filter-tab--active {
  color: var(--portal-accent);
  font-weight: 600;
  border-bottom-color: var(--portal-accent);
}

.portal-filter-tab__count {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 20px;
  height: 18px;
  padding: 0 6px;
  border-radius: 999px;
  font-size: 0.6875rem;
  font-weight: 700;
  background: var(--portal-surface);
  color: var(--portal-text-muted);
}
.portal-filter-tab--active .portal-filter-tab__count {
  background: var(--portal-accent);
  color: var(--portal-on-accent);
}

/* ----------------------------------------------------------------
   Badges
   ---------------------------------------------------------------- */
.portal-badge {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  padding: 2px 8px;
  border-radius: 999px;
  font-size: 0.75rem;
  font-weight: 600;
  line-height: 1.6;
  white-space: nowrap;
  background: var(--portal-surface);
  color: var(--portal-text-muted);
  border: 1px solid var(--portal-border-soft);
}

/* Status badges: one meaning per color, the same on every portal page.
     neutral  not started, open, closed, resolved (shown as Closed), low/medium priority
     info     new
     warn     in progress, waiting on you, changes not sent, high priority
     ok       sent, signed, accepted, done
     danger   critical/urgent, declined, overdue, error
   The stored keys stay as they are; only the color a key maps to is set here. */
.portal-badge--neutral,
.portal-badge--open,
.portal-badge--closed,
.portal-badge--resolved,
.portal-badge--archived,
.portal-badge--inactive,
.portal-badge--priority-low,
.portal-badge--priority-medium {
  /* a grey from the text color, not the section fill: on some palettes that
     fill is the brand's sand or brass and read as a status of its own */
  background: color-mix(in srgb, var(--portal-text) 7%, transparent);
  color: var(--portal-text-muted);
  border-color: var(--portal-border);
}

.portal-badge--accent,
.portal-badge--info,
.portal-badge--new {
  background: var(--portal-accent-tint);
  color: var(--portal-accent);
  border-color: transparent;
}

.portal-badge--pending,
.portal-badge--in_progress,
.portal-badge--lead,
.portal-badge--warning,
.portal-badge--priority-high {
  background: var(--portal-warning-bg);
  color: var(--portal-warning);
  border-color: transparent;
}

.portal-badge--active,
.portal-badge--success {
  background: var(--portal-success-bg);
  color: var(--portal-success);
  border-color: var(--portal-success-border);
}

.portal-badge--danger,
.portal-badge--error,
.portal-badge--critical,
.portal-badge--urgent,
.portal-badge--priority-urgent,
.portal-badge--priority-critical {
  background: var(--portal-error-bg);
  color: var(--portal-error);
  border-color: var(--portal-error-border);
}

/* ----------------------------------------------------------------
   Table
   ---------------------------------------------------------------- */
.portal-table-wrap {
  overflow-x: auto;
  -webkit-overflow-scrolling: touch;
}

.portal-table {
  width: 100%;
  border-collapse: collapse;
  font-size: 0.875rem;
}

.portal-table th {
  text-align: left;
  padding: 10px 12px;
  font-size: 0.75rem;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  color: var(--portal-text-muted);
  border-bottom: 1px solid var(--portal-border);
  white-space: nowrap;
}

.portal-table td {
  padding: 12px 12px;
  border-bottom: 1px solid var(--portal-border);
  color: var(--portal-text);
  vertical-align: middle;
}

.portal-table tbody tr {
  transition: background 0.1s;
}

.portal-table tbody tr:hover {
  background: var(--portal-accent-tint);
}

.portal-table tbody tr:last-child td {
  border-bottom: none;
}

/* Only the first column (the document or subject name) wraps. Dates, statuses
   and action buttons stay on one line, and a table too wide for a phone scrolls
   sideways inside .portal-table-wrap instead of stacking its buttons. */
.portal-table td:not(:first-child) { white-space: nowrap; }
.portal-table td:first-child { min-width: 10rem; }
.portal-table .portal-btn-row { flex-direction: row; flex-wrap: nowrap; align-items: center; }

/* Text links in a table cell. A button in a cell (Download, Review & sign)
   styles itself: a bare `.portal-table a` (0,1,1) out-ranks .portal-btn (0,1,0)
   and paints the label in the accent over an accent fill, hiding the text. */
.portal-table a:not(.portal-btn) {
  color: var(--portal-accent);
  font-weight: 500;
}

.portal-table a:not(.portal-btn):hover {
  text-decoration: underline;
}

/* ----------------------------------------------------------------
   Forms
   ---------------------------------------------------------------- */
.portal-form .portal-field {
  margin-bottom: 16px;
}

.portal-label {
  display: block;
  font-size: 0.875rem;
  font-weight: 600;
  color: var(--portal-text);
  margin-bottom: 6px;
}

.portal-label .portal-label__hint {
  font-weight: 400;
  color: var(--portal-text-muted);
  font-size: 0.8125rem;
}

.portal-input,
.portal-select,
.portal-textarea {
  display: block;
  width: 100%;
  /* Input fill == card fill, so this border is the field's ONLY boundary —
     --portal-border (14% text) sits at ~1.3:1 and is effectively invisible
     (WCAG 1.4.11 wants 3:1). Blend the palette border 70% toward text 30% so
     the boundary clears 3:1 in light + dark on every palette. On the
     non-keystone engine --color-border is unset, so it falls back to a concrete
     neutral slate (#8A93A3): blended 70/30 with navy it resolves to ~5:1 on a
     white card (the old `transparent` fallback collapsed the mix to ~1.9:1,
     below WCAG 1.4.11's 3:1). */
  border: 1px solid color-mix(in srgb, var(--color-border, #8A93A3) 70%, var(--text-primary, #151C28) 30%);
  border-radius: var(--portal-radius-sm);
  background: var(--portal-input-bg, #fff);
  color: var(--portal-text);
  font-family: var(--portal-font);
  font-size: 0.9375rem;
  line-height: 1.5;
  transition: border-color 0.15s, box-shadow 0.15s;
  outline: none;
  -webkit-appearance: none;
}

.portal-input,
.portal-select {
  height: 44px;
  padding: 0 12px;
}

.portal-select {
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 24 24' fill='none' stroke='%23888888' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='6 9 12 15 18 9'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right 10px center;
  padding-right: 36px;
  cursor: pointer;
}

.portal-textarea {
  padding: 10px 12px;
  resize: vertical;
  min-height: 120px;
}

.portal-input:focus,
.portal-select:focus,
.portal-textarea:focus {
  border-color: var(--portal-accent);
  box-shadow: 0 0 0 3px var(--portal-accent-tint-2);
}

.portal-input::placeholder,
.portal-textarea::placeholder {
  color: var(--portal-text-muted);
}

.portal-input:disabled,
.portal-select:disabled,
.portal-textarea:disabled {
  opacity: 0.6;
  cursor: not-allowed;
  background: var(--portal-surface);
}

.portal-field-help {
  margin-top: 5px;
  font-size: 0.8125rem;
  color: var(--portal-text-muted);
}

/* "Keep me signed in" (remember-me) row on the login form. */
.portal-remember {
  margin-top: 12px;
}
.portal-remember__label {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  font-size: 0.9rem;
  cursor: pointer;
}
.portal-remember__check {
  width: 16px;
  height: 16px;
  flex: none;
  accent-color: var(--portal-accent, #8a6634);
  cursor: pointer;
}
.portal-remember__note {
  margin: 4px 0 0;
  font-size: 0.78rem;
  color: var(--portal-text-muted);
}

/* ----------------------------------------------------------------
   Buttons
   ---------------------------------------------------------------- */
.portal-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  height: 44px;
  padding: 0 22px;
  background: var(--portal-accent);
  color: var(--portal-on-accent);
  border: none;
  border-radius: var(--portal-radius-sm);
  font-family: var(--portal-font);
  font-size: 15px;
  font-weight: 600;
  cursor: pointer;
  text-decoration: none;
  transition: background 0.15s;
  white-space: nowrap;
  line-height: 1;
  -webkit-appearance: none;
}

.portal-btn:hover {
  background: var(--portal-accent-hover);
  text-decoration: none;
  color: var(--portal-on-accent);
}

.portal-btn:disabled {
  opacity: 0.55;
  cursor: not-allowed;
  transform: none;
  box-shadow: none;
}

.portal-btn--ghost {
  background: transparent;
  color: var(--portal-text);
  border: 1.5px solid var(--portal-border);
  box-shadow: none;
}

.portal-btn--ghost:hover {
  background: var(--portal-surface);
  border-color: var(--portal-accent);
  color: var(--portal-text);
  filter: none;
  transform: none;
  box-shadow: none;
}

.portal-btn--sm {
  height: 34px;
  padding: 0 14px;
  font-size: 0.8125rem;
}

.portal-btn--danger {
  background: var(--portal-error);
  color: #fff;
}

.portal-btn--danger:hover {
  background: var(--portal-error);
  filter: brightness(0.92);
  box-shadow: var(--portal-shadow-md);
  color: #fff;
}

.portal-btn-row {
  display: flex;
  align-items: center;
  gap: 10px;
  flex-wrap: wrap;
  margin-top: 8px;
}

/* Button hierarchy. The solid fill is for the action a card exists for: a
   form's submit (a <button>), a link the markup marks .portal-btn--primary
   (Review & sign), or the one action beside a page title (New message). Any
   other link drawn as a button only goes somewhere (Open inbox, Go to
   documents, Manage preferences, View, Download, Back), so it is the outlined
   secondary style, and a card never shows two solid buttons. */
.portal-scope a.portal-btn:not(.portal-btn--primary):not(.portal-btn--danger):not(.portal-page-header a):not(.portal-page-title ~ a) {
  background: transparent;
  color: var(--portal-text);
  border: 1.5px solid var(--portal-border);
  box-shadow: none;
}
.portal-scope a.portal-btn:not(.portal-btn--primary):not(.portal-btn--danger):not(.portal-page-header a):not(.portal-page-title ~ a):hover {
  background: var(--portal-surface);
  border-color: var(--portal-accent);
  color: var(--portal-text);
  filter: none;
}

/* A destructive action repeated on every row (Remove on a document) is an
   outline in the danger hue; the solid danger fill is kept for a single final
   step such as "Decline to sign". The browser still asks before it removes. */
.portal-scope :is(.portal-fileitem__actions, .portal-table) .portal-btn--danger {
  background: transparent;
  color: var(--portal-status-danger);
  border: 1.5px solid color-mix(in srgb, var(--portal-status-danger) 55%, transparent);
  box-shadow: none;
}
.portal-scope :is(.portal-fileitem__actions, .portal-table) .portal-btn--danger:hover {
  background: color-mix(in srgb, var(--portal-status-danger) 10%, transparent);
  color: var(--portal-status-danger);
  filter: none;
}

/* ----------------------------------------------------------------
   Alerts
   ---------------------------------------------------------------- */
.portal-alert {
  padding: 12px 16px;
  border-radius: var(--portal-radius-sm);
  margin-bottom: 16px;
  font-size: 0.9375rem;
  display: flex;
  align-items: flex-start;
  gap: 10px;
}

.portal-alert--error {
  background: var(--portal-error-bg);
  color: var(--portal-error);
}

.portal-alert--success {
  background: var(--portal-success-bg);
  color: var(--portal-success);
}

.portal-alert--warning {
  background: var(--portal-warning-bg);
  color: var(--portal-warning);
}

.portal-alert--info {
  background: var(--portal-info-bg);
  color: var(--portal-info);
}

/* ----------------------------------------------------------------
   Notices (dashboard banners) — dismissible
   ---------------------------------------------------------------- */
.portal-notice {
  display: flex;
  align-items: flex-start;
  gap: 12px;
  padding: 14px 16px;
  margin-bottom: 16px;
  border: 1px solid var(--portal-border);
  border-radius: var(--portal-radius-sm);
  background: var(--portal-bg-raised);
  box-shadow: var(--portal-shadow);
}

.portal-notice__content {
  flex: 1;
  min-width: 0;
  font-size: 0.9375rem;
  line-height: 1.5;
  color: var(--portal-text);
}

.portal-notice__title {
  font-weight: 700;
  color: var(--portal-text);
}

.portal-notice__body {
  display: block;
  margin-top: 4px;
  font-size: 0.875rem;
  color: var(--portal-text-muted);
}

.portal-notice__dismiss-form { flex-shrink: 0; line-height: 0; }

.portal-notice__dismiss {
  width: 26px;
  height: 26px;
  display: flex;
  align-items: center;
  justify-content: center;
  background: none;
  border: none;
  border-radius: 6px;
  cursor: pointer;
  font-size: 1.25rem;
  line-height: 1;
  color: var(--portal-text-muted);
  transition: background 0.12s, color 0.12s;
}

.portal-notice__dismiss:hover {
  background: var(--portal-surface);
  color: var(--portal-text);
}

.portal-notice--warning { border-color: var(--portal-warning); }
.portal-notice--info    { border-color: var(--portal-accent); }

/* ----------------------------------------------------------------
   Policies — the dashboard's policy-update card, the Policies list,
   and the status bars around a policy read in the portal
   ---------------------------------------------------------------- */
.portal-notice__content > h2.portal-notice__title {
  margin: 0;
  font-family: inherit;
  font-size: 1rem;
  line-height: 1.4;
}
.portal-notice__content > p.portal-notice__body { margin: 4px 0 0; }

.portal-policy-actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px;
}
.portal-policy-form { margin: 0; display: inline-flex; }
.portal-notice--policy .portal-notice__content > .portal-policy-actions { margin-top: 12px; }

.portal-policy-list {
  list-style: none;
  margin: 12px 0 0;
  padding: 0;
  border-top: 1px solid var(--portal-border);
}
.portal-policy-list__item {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 8px 16px;
  padding: 10px 0;
  border-bottom: 1px solid var(--portal-border);
}
.portal-policy-list__name {
  display: flex;
  flex-direction: column;
  min-width: 0;
  font-weight: 600;
  color: var(--portal-text);
}
.portal-policy-list__meta {
  font-weight: 400;
  font-size: 0.8125rem;
  color: var(--portal-text-muted);
}

/* The list is a .portal-card, so the card sets its padding. */
.portal-policy-rows { list-style: none; margin: 0 0 16px; }
.portal-policy-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px 16px;
  padding: 16px 0;
  border-bottom: 1px solid var(--portal-border-soft);
}
.portal-policy-row:first-child { padding-top: 0; }
.portal-policy-row:last-child { padding-bottom: 0; border-bottom: none; }
.portal-policy-row__main {
  display: flex;
  flex-direction: column;
  gap: 4px;
  min-width: 0;
}
.portal-policy-row__name {
  font-weight: 600;
  color: var(--portal-text);
  text-decoration: none;
  overflow-wrap: anywhere;
}
.portal-policy-row__name:hover { color: var(--portal-accent); text-decoration: underline; }
.portal-policy-row__meta,
.portal-policy-status__detail {
  font-size: 0.8125rem;
  color: var(--portal-text-muted);
}
.portal-policy-row__status {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 6px 10px;
  margin-top: 2px;
}
.portal-policy-row > .portal-policy-actions { flex-shrink: 0; justify-content: flex-end; }

.portal-policy-status {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 12px 16px;
  padding: 14px 16px;
  margin-bottom: 16px;
  border: 1px solid var(--portal-border);
  border-radius: var(--portal-radius-sm);
  background: var(--portal-bg-raised);
}
.portal-policy-status--pending {
  border-color: color-mix(in srgb, var(--portal-warning) 55%, transparent);
  background: color-mix(in srgb, var(--portal-warning) 9%, var(--portal-bg-raised));
}
.portal-policy-status--end { margin: 16px 0 0; }
.portal-policy-status__text {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 6px 10px;
  min-width: 0;
}
.portal-policy-status__ask { color: var(--portal-text); }
.portal-policy-doc { overflow-wrap: anywhere; }
.portal-policy-doc .prose { max-width: 72ch; }

@media (max-width: 600px) {
  .portal-policy-row { flex-direction: column; align-items: stretch; }
  .portal-policy-actions { width: 100%; }
  .portal-policy-actions > .portal-btn,
  .portal-policy-actions > .portal-policy-form { flex: 1 1 0; min-width: 0; }
  .portal-policy-actions .portal-policy-form > .portal-btn { width: 100%; }
  .portal-policy-actions .portal-btn { white-space: normal; text-align: center; height: auto; min-height: 40px; padding-top: 8px; padding-bottom: 8px; line-height: 1.25; }
}

/* ----------------------------------------------------------------
   Login / Register / Reset page
   ---------------------------------------------------------------- */
.portal-login {
  min-height: 100vh;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  padding: 24px;
  background: var(--portal-bg);
}

.portal-login::before {
  content: '';
  display: block;
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  height: 4px;
  background: var(--portal-accent);
  z-index: 200;
}

.portal-login__card {
  width: 100%;
  max-width: 440px;
  background: var(--portal-bg-raised);
  border: 1px solid var(--portal-border);
  border-radius: var(--portal-radius-lg);
  padding: 40px 36px;
  box-shadow: var(--portal-shadow);
}

.portal-login__brand {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 10px;
  margin-bottom: 28px;
}

.portal-login__logo-mark {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 40px;
  height: 40px;
  background: var(--portal-accent);
  border-radius: var(--portal-radius);
  color: var(--portal-on-accent);
  font-weight: 800;
  font-size: 1.1rem;
  letter-spacing: -0.03em;
}

.portal-login__brand-name {
  font-family: var(--portal-font-heading);
  font-size: 1.125rem;
  font-weight: 700;
  color: var(--portal-text);
}

.portal-login__heading {
  font-size: 1.25rem;
  font-weight: 700;
  color: var(--portal-text);
  text-align: center;
  margin-bottom: 6px;
}

.portal-login__subheading {
  font-size: 0.875rem;
  color: var(--portal-text-muted);
  text-align: center;
  margin-bottom: 28px;
}

.portal-login .portal-btn {
  width: 100%;
  margin-top: 8px;
}

.portal-login__footer {
  margin-top: 20px;
  text-align: center;
  font-size: 0.875rem;
  color: var(--portal-text-muted);
}

.portal-login__disclaimer {
  display: flex;
  align-items: flex-start;
  gap: 10px;
  width: 100%;
  max-width: 440px;
  margin: 16px auto 0;
  padding: 12px 16px;
  background: var(--portal-bg-raised);
  border: 1px solid var(--portal-border);
  border-radius: var(--portal-radius-sm);
  font-size: 0.8125rem;
  color: var(--portal-text-muted);
  line-height: 1.5;
}

.portal-login__disclaimer svg {
  flex-shrink: 0;
  margin-top: 1px;
  color: var(--portal-accent);
}

.portal-login__disclaimer a { color: var(--portal-accent); }

.portal-login__legal {
  text-align: center;
  margin-top: 16px;
  font-size: 0.75rem;
  color: var(--portal-text-muted);
}

.portal-login__legal a {
  color: var(--portal-text-muted);
  text-decoration: none;
  transition: color 0.15s;
}

.portal-login__legal a:hover { color: var(--portal-accent); }

/* ----------------------------------------------------------------
   Empty state
   ---------------------------------------------------------------- */
.portal-empty {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  padding: 48px 24px;
  text-align: center;
  color: var(--portal-text-muted);
}

.portal-empty__icon {
  width: 48px;
  height: 48px;
  margin-bottom: 16px;
  opacity: 0.4;
  color: var(--portal-text-muted);
}

.portal-empty__heading {
  font-size: 1rem;
  font-weight: 600;
  color: var(--portal-text);
  margin-bottom: 6px;
}

.portal-empty__body {
  font-size: 0.875rem;
  color: var(--portal-text-muted);
  max-width: 320px;
  margin-bottom: 20px;
}

/* ----------------------------------------------------------------
   Copy button
   ---------------------------------------------------------------- */
.portal-copy-btn {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  padding: 3px 10px;
  height: 28px;
  font-size: 0.75rem;
  font-weight: 600;
  border: 1px solid var(--portal-border);
  border-radius: 6px;
  background: var(--portal-bg);
  color: var(--portal-text-muted);
  cursor: pointer;
  font-family: var(--portal-font);
  transition: background 0.12s, color 0.12s, border-color 0.12s;
  vertical-align: middle;
}

.portal-copy-btn:hover {
  background: var(--portal-accent-tint);
  color: var(--portal-accent);
  border-color: var(--portal-accent);
}

.portal-copy-btn.copied {
  background: var(--portal-success-bg);
  color: var(--portal-success);
  border-color: var(--portal-success-border);
}

/* ----------------------------------------------------------------
   Message / reply thread
   ---------------------------------------------------------------- */
.portal-thread-body {
  background: var(--portal-bg);
  border: 1px solid var(--portal-border);
  border-radius: var(--portal-radius-sm);
  padding: 16px;
  font-size: 0.9375rem;
  line-height: 1.7;
  color: var(--portal-text);
  white-space: pre-wrap;
  word-break: break-word;
  margin-bottom: 16px;
}

.portal-thread-meta {
  display: flex;
  align-items: center;
  gap: 12px;
  flex-wrap: wrap;
  font-size: 0.8125rem;
  color: var(--portal-text-muted);
  margin-bottom: 16px;
}

.portal-thread-meta strong { color: var(--portal-text); }

/* A conversation's facts (status, priority, category, sent): each label sits
   above its value in a small grid — up to four across on desktop, two on phones —
   instead of one long run of label/value pairs. */
.portal-meta-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(140px, 1fr));
  gap: 14px 24px;
  margin: 0;
  padding-top: 14px;
  border-top: 1px solid var(--portal-border-soft);
}
.portal-meta-grid__item { min-width: 0; }
.portal-meta-grid dt {
  margin: 0 0 4px;
  font-size: 0.6875rem;
  font-weight: 600;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--portal-text-muted);
}
.portal-meta-grid dd {
  margin: 0;
  font-size: 0.9375rem;
  line-height: 1.45;
  color: var(--portal-text);
  overflow-wrap: anywhere;
}
@media (max-width: 640px) {
  .portal-meta-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

.portal-replies {
  margin-top: 24px;
}

.portal-reply {
  padding: 16px;
  background: var(--portal-bg);
  border: 1px solid var(--portal-border);
  border-radius: var(--portal-radius-sm);
  margin-bottom: 12px;
}

/* owner-authored reply gets the accent tint; client replies stay neutral */
.portal-reply--owner {
  background: var(--portal-accent-tint);
  border-color: var(--portal-accent-tint-2);
}

.portal-reply__meta {
  font-size: 0.8125rem;
  color: var(--portal-text-muted);
  margin-bottom: 8px;
  display: flex;
  align-items: center;
  gap: 8px;
}

.portal-reply__from {
  font-weight: 600;
  color: var(--portal-text);
}

.portal-reply__body {
  font-size: 0.9375rem;
  line-height: 1.65;
  color: var(--portal-text);
  white-space: pre-wrap;
  word-break: break-word;
}

/* ----------------------------------------------------------------
   Profile / Account
   ---------------------------------------------------------------- */
.portal-profile-row {
  display: flex;
  align-items: flex-start;
  gap: 24px;
  margin-bottom: 20px;
  padding-bottom: 20px;
  border-bottom: 1px solid var(--portal-border);
}

.portal-profile-row:last-child {
  margin-bottom: 0;
  padding-bottom: 0;
  border-bottom: none;
}

.portal-profile-label {
  font-size: 0.8125rem;
  font-weight: 600;
  color: var(--portal-text-muted);
  text-transform: uppercase;
  letter-spacing: 0.05em;
  min-width: 120px;
  padding-top: 2px;
  flex-shrink: 0;
}

.portal-profile-value {
  font-size: 0.9375rem;
  color: var(--portal-text);
  word-break: break-word;
}

/* ----------------------------------------------------------------
   Breadcrumb
   ---------------------------------------------------------------- */
.portal-breadcrumb {
  display: flex;
  align-items: center;
  gap: 6px;
  font-size: 0.8125rem;
  color: var(--portal-text-muted);
  margin-bottom: 16px;
  flex-wrap: wrap;
}

.portal-breadcrumb a { color: var(--portal-text-muted); }
.portal-breadcrumb a:hover { color: var(--portal-accent); }
.portal-breadcrumb__sep { color: var(--portal-border); }
.portal-breadcrumb__current {
  color: var(--portal-text);
  font-weight: 500;
}

/* The document viewer's back link reads like the breadcrumb on every other
   detail page: one way back, one look. */
.portal-scope .docview-back {
  font-size: 0.8125rem;
  font-weight: 500;
  color: var(--portal-text-muted);
}
.portal-scope .docview-back:hover,
.portal-scope .docview-back:focus-visible { color: var(--portal-accent); }

/* ----------------------------------------------------------------
   Misc utilities
   ---------------------------------------------------------------- */
.portal-divider {
  border: none;
  border-top: 1px solid var(--portal-border);
  margin: 24px 0;
}

.portal-row {
  display: flex;
  align-items: center;
  gap: 12px;
}

.portal-row--between { justify-content: space-between; }
.portal-row--wrap { flex-wrap: wrap; }
.portal-spacer { flex: 1; }

/* Quick-action link cards (dashboard) */
.portal-quick-links {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 12px;
  margin-bottom: 24px;
}
@media (max-width: 540px) {
  .portal-quick-links { grid-template-columns: 1fr 1fr; }
  .portal-quick-links .portal-quick-link--span { grid-column: 1 / -1; }
}

.portal-quick-link {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 8px;
  padding: 16px;
  background: var(--portal-bg-raised);
  border: 1px solid var(--portal-border);
  border-radius: var(--portal-radius);
  text-decoration: none;
  color: inherit;
  transition: border-color .15s, background .15s;
}
.portal-quick-link:hover {
  border-color: var(--portal-accent);
  background: var(--portal-accent-tint);
  text-decoration: none;
}
.portal-quick-link__icon {
  width: 36px;
  height: 36px;
  border-radius: var(--portal-radius-sm);
  background: var(--portal-accent-tint);
  color: var(--portal-accent);
  display: flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
}
.portal-quick-link__label {
  font-size: 0.875rem;
  font-weight: 700;
  color: var(--portal-text);
  line-height: 1.2;
}
.portal-quick-link__sub {
  font-size: 0.75rem;
  color: var(--portal-text-muted);
  line-height: 1.4;
}

/* ----------------------------------------------------------------
   Footer
   ---------------------------------------------------------------- */
.portal-footer {
  border-top: 1px solid var(--portal-border);
  margin-top: 64px;
  padding: 32px 0 28px;
}

.portal-footer__inner {
  max-width: var(--portal-max);
  margin: 0 auto;
  padding: 0 24px;
}

.portal-footer__disclaimer {
  background: var(--portal-bg-raised);
  border: 1px solid var(--portal-border);
  border-radius: var(--portal-radius-sm);
  padding: 14px 18px;
  margin-bottom: 20px;
  font-size: 0.8125rem;
  color: var(--portal-text-muted);
  line-height: 1.6;
}

.portal-footer__disclaimer-title {
  font-size: 0.6875rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.07em;
  color: var(--portal-accent);
  margin-bottom: 4px;
}

.portal-footer__bottom {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  flex-wrap: wrap;
  font-size: 0.8125rem;
  color: var(--portal-text-muted);
}

.portal-footer__copyright a { color: var(--portal-text-muted); }
.portal-footer__copyright a:hover { color: var(--portal-accent); }

.portal-footer__legal {
  display: flex;
  align-items: center;
  gap: 4px;
  flex-wrap: wrap;
}

.portal-footer__legal a {
  color: var(--portal-text-muted);
  text-decoration: none;
  padding: 4px 8px;
  border-radius: var(--portal-radius-sm);
  transition: color 0.15s, background 0.15s;
}

.portal-footer__legal a:hover {
  color: var(--portal-accent);
  background: var(--portal-accent-tint);
  text-decoration: none;
}

/* ----------------------------------------------------------------
   Responsive — mobile
   ---------------------------------------------------------------- */
/* Tablet/phone — collapse the rail; the section links live in the site's
   mobile menu overlay (.portal-ovnav) once the header switches to the hamburger. */
@media (max-width: 860px) {
  /* minmax(0, …): a bare 1fr column grows to its widest child (a table, a
     button row) and pushes the page sideways on phones. */
  .portal-shell { grid-template-columns: minmax(0, 1fr); gap: 0; margin-top: 14px; }
  .portal-sidebar { display: none; }
}

@media (max-width: 640px) {
  .portal-wrap {
    padding-left: 16px;
    padding-right: 16px;
  }

  .portal-header__inner {
    padding: 0 16px;
    gap: 6px;
  }

  .portal-nav { display: none; }
  .portal-header__client-name { display: none; }

  .portal-main {
    padding-top: 4px;
    padding-bottom: 40px;
  }

  .portal-card { padding: 16px; }

  .portal-grid {
    grid-template-columns: 1fr 1fr;
    gap: 12px;
  }

  .portal-stat { padding: 16px; }
  .portal-stat__value { font-size: 1.5rem; }

  .portal-login__card { padding: 28px 20px; }

  .portal-profile-row {
    flex-direction: column;
    gap: 4px;
  }

  .portal-profile-label { min-width: unset; }

  .portal-table th,
  .portal-table td { padding: 10px 8px; }
  .portal-table td:first-child { min-width: 8rem; }

  .portal-btn-row {
    flex-direction: column;
    align-items: stretch;
  }

  .portal-btn-row .portal-btn { justify-content: center; }

  .portal-page-title { font-size: 1.25rem; }

  .portal-dash-header__greeting { font-size: 1.375rem; }
}

@media (max-width: 400px) {
  .portal-grid { grid-template-columns: 1fr; }
}

/* ── F10 inactivity-logout modal ─────────────────────────────────────────── */
.idle-logout { position: fixed; inset: 0; z-index: 9999; display: none; align-items: center; justify-content: center; padding: 1rem; background: rgba(0,0,0,.55); }
.idle-logout--on { display: flex; }
.idle-logout__box { width: 100%; max-width: 400px; background: var(--portal-bg-raised); color: var(--portal-text); border: 1px solid var(--portal-border); border-radius: 14px; padding: 1.5rem 1.5rem 1.25rem; box-shadow: var(--portal-shadow-md); text-align: center; font-family: var(--portal-font); }
.idle-logout__title { font-size: 1.15rem; font-weight: 800; margin-bottom: .5rem; color: var(--portal-text); font-family: var(--portal-font-heading); }
.idle-logout__body { font-size: .9rem; color: var(--portal-text-muted); line-height: 1.6; margin-bottom: 1.25rem; }
.idle-logout__count { color: var(--portal-text); font-weight: 700; font-variant-numeric: tabular-nums; }
.idle-logout__actions { display: flex; gap: .5rem; justify-content: center; flex-wrap: wrap; }
.idle-logout__btn { font: inherit; font-size: .9rem; font-weight: 600; padding: .55rem 1.15rem; border-radius: 10px; cursor: pointer; border: 1px solid transparent; }
.idle-logout__btn--ghost { background: transparent; color: var(--portal-text); border-color: var(--portal-border); }
.idle-logout__btn--go { background: var(--portal-accent); color: var(--portal-on-accent); }
.idle-logout__btn--go:disabled { opacity: .6; cursor: default; }

/* ── "Are you sure?" dialog (js/confirm-dialog.js, data-portal-confirm) ────── */
.portal-confirm { padding: 0; border: 1px solid var(--portal-border); border-radius: 14px; background: var(--portal-bg-raised); color: var(--portal-text); width: calc(100% - 2rem); max-width: 420px; box-shadow: var(--portal-shadow-md); font-family: var(--portal-font); }
.portal-confirm::backdrop { background: rgba(0,0,0,.55); }
.portal-confirm__inner { padding: 1.4rem 1.5rem 1.25rem; }
.portal-confirm__msg { margin: 0 0 1.25rem; font-size: 1rem; line-height: 1.55; overflow-wrap: anywhere; }
.portal-confirm__actions { display: flex; gap: .5rem; justify-content: flex-end; flex-wrap: wrap; }
.portal-confirm__actions .portal-btn:focus-visible { outline: 2px solid var(--portal-accent); outline-offset: 2px; }
@media (max-width: 420px) { .portal-confirm__actions .portal-btn { flex: 1 1 auto; } }

/* ================================================================
   UPLOAD DROPZONE + FILE LIST  (Document Center / Files)
   Token-only document-hub rows + a drag-and-drop uploader. The real
   <input type=file> is visually hidden but kept FOCUSABLE and bound by
   `for=` to the .portal-dropzone label, so it works with JS off.
   ================================================================ */
.portal-upload {
  margin-top: 20px;
  padding-top: 20px;
  border-top: 1px solid var(--portal-border);
}

.portal-dropzone {
  display: flex;
  align-items: center;
  gap: 16px;
  width: 100%;
  min-height: 96px;
  padding: 20px 22px;
  border: 2px dashed var(--portal-border);
  border-radius: var(--portal-radius-lg);
  background: var(--portal-surface);
  color: var(--portal-text);
  cursor: pointer;
  text-align: left;
  transition: border-color .15s, background .15s, box-shadow .15s;
}
.portal-dropzone:hover { border-color: var(--portal-accent); background: var(--portal-accent-tint); }
/* keyboard focus is on the visually-hidden input → mirror the ring + drag-over onto the zone */
.portal-dropzone.is-dragover,
.portal-dropzone__input:focus-visible + .portal-dropzone {
  border-color: var(--portal-accent);
  border-style: solid;
  background: var(--portal-accent-tint);
  box-shadow: 0 0 0 3px var(--portal-accent-tint-2);
}

/* real input: hidden visually, kept FOCUSABLE (never display:none) */
.portal-dropzone__input {
  position: absolute;
  width: 1px; height: 1px;
  padding: 0; margin: -1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
  border: 0;
}

.portal-dropzone__icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 48px; height: 48px;
  flex-shrink: 0;
  border-radius: var(--portal-radius);
  background: var(--portal-accent-tint);
  color: var(--portal-accent);
}
.portal-dropzone__icon svg { width: 24px; height: 24px; }

.portal-dropzone__copy { display: flex; flex-direction: column; gap: 3px; min-width: 0; }
.portal-dropzone__title { font-weight: 700; font-size: .9375rem; color: var(--portal-text); }
.portal-dropzone__browse { color: var(--portal-accent); text-decoration: underline; }
.portal-dropzone__hint { font-size: .8125rem; color: var(--portal-text-muted); }

/* selected-file chip (JS reveals; replaces idle copy) */
.portal-dropzone__chip {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  min-width: 0;
  padding: 6px 10px 6px 8px;
  border-radius: 999px;
  background: var(--portal-bg-raised);
  border: 1px solid var(--portal-border);
  font-size: .8125rem;
  color: var(--portal-text);
}
.portal-dropzone__chip[hidden] { display: none; }
.portal-dropzone.has-file .portal-dropzone__copy { display: none; }
.portal-dropzone__chip-icon { display: inline-flex; color: var(--portal-accent); flex-shrink: 0; }
.portal-dropzone__chip-icon svg { width: 16px; height: 16px; }
.portal-dropzone__chip-name {
  font-weight: 600;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis; max-width: 220px;
}
.portal-dropzone__chip-size { color: var(--portal-text-muted); flex-shrink: 0; }
.portal-dropzone__chip-swap {
  margin-left: 2px; padding-left: 8px;
  border-left: 1px solid var(--portal-border);
  color: var(--portal-accent); font-weight: 600; flex-shrink: 0;
}

.portal-upload__fields {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
  gap: 16px;
  margin-top: 16px;
}
.portal-upload__fields .portal-field { margin-bottom: 0; }

.portal-upload__foot {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  flex-wrap: wrap;
  margin-top: 16px;
}

/* previously-unstyled bits */
.portal-hint { font-size: .8125rem; color: var(--portal-text-muted); margin: 0; line-height: 1.5; }
.portal-title {
  font-family: var(--portal-font-heading);
  font-size: 1.5rem;
  font-weight: 700;
  line-height: 1.25;
  color: var(--portal-text);
  margin-bottom: 20px;
}

/* ---- file list — card-like rows with coloured type tiles ----- */
.portal-filelist { display: flex; flex-direction: column; gap: 8px; }

.portal-fileitem {
  display: flex;
  align-items: center;
  gap: 14px;
  padding: 12px 14px;
  border: 1px solid var(--portal-border);
  border-radius: var(--portal-radius);
  background: var(--portal-bg-raised);
  transition: border-color .12s, background .12s;
}
.portal-fileitem:hover { border-color: var(--portal-accent); background: var(--portal-accent-tint); }

/* coloured file-type tile. default = accent; families = fixed signal tokens. */
.portal-fileitem__icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 40px; height: 40px;
  flex-shrink: 0;
  border-radius: var(--portal-radius-sm);
  background: var(--portal-accent-tint);
  color: var(--portal-accent);
}
.portal-fileitem__icon svg { width: 20px; height: 20px; }
.portal-fileitem__icon--pdf   { background: var(--portal-error-bg);   color: var(--portal-error); }
.portal-fileitem__icon--image { background: var(--portal-success-bg); color: var(--portal-success); }
.portal-fileitem__icon--sheet { background: var(--portal-success-bg); color: var(--portal-success); }
.portal-fileitem__icon--doc   { background: var(--portal-info-bg);    color: var(--portal-info); }
.portal-fileitem__icon--zip   { background: var(--portal-warning-bg); color: var(--portal-warning); }
.portal-fileitem__icon--text,
.portal-fileitem__icon--file  { background: var(--portal-surface);    color: var(--portal-text-muted); }

.portal-fileitem__main { flex: 1; min-width: 0; }
.portal-fileitem__name {
  display: inline-block;
  font-weight: 600;
  font-size: .9375rem;
  color: var(--portal-accent);
  text-decoration: none;
  word-break: break-word;
}
.portal-fileitem__name:hover { text-decoration: underline; }

.portal-file__note {
  margin-top: 2px;
  font-size: .8125rem;
  color: var(--portal-text-muted);
  line-height: 1.45;
}

.portal-fileitem__meta {
  display: flex;
  align-items: center;
  gap: 6px;
  flex-wrap: wrap;
  margin-top: 4px;
  font-size: .75rem;
  color: var(--portal-text-muted);
}
.portal-fileitem__dot { opacity: .55; }

/* small ext badge in the meta line — coloured by family */
.portal-ftype {
  display: inline-flex; align-items: center;
  padding: 1px 7px;
  border-radius: var(--portal-radius-sm);
  font-size: .6875rem;
  font-weight: 700;
  letter-spacing: .04em;
  background: var(--portal-accent-tint);
  color: var(--portal-accent);
}
.portal-ftype--pdf   { background: var(--portal-error-bg);   color: var(--portal-error); }
.portal-ftype--image,
.portal-ftype--sheet { background: var(--portal-success-bg); color: var(--portal-success); }
.portal-ftype--doc   { background: var(--portal-info-bg);    color: var(--portal-info); }
.portal-ftype--zip   { background: var(--portal-warning-bg); color: var(--portal-warning); }
.portal-ftype--text,
.portal-ftype--file  { background: var(--portal-surface);    color: var(--portal-text-muted); }

.portal-fileitem__actions {
  display: flex;
  align-items: center;
  gap: 8px;
  flex-shrink: 0;
  margin-left: auto;
}
.portal-fileitem__actions form { display: inline; line-height: 0; }

@media (prefers-reduced-motion: reduce) {
  .portal-dropzone,
  .portal-dropzone__chip,
  .portal-fileitem { transition: none; }
}

@media (max-width: 640px) {
  .portal-fileitem { flex-wrap: wrap; }
  /* full row under the tile: indented by the tile, 100% overran the card by 54px */
  .portal-fileitem__actions { width: 100%; margin-left: 0; }
  .portal-upload__foot { flex-direction: column; align-items: stretch; }
  .portal-upload__foot .portal-btn { width: 100%; }
}

/* ================================================================
   DARK-MODE ACCENT LEGIBILITY  (keystone palettes only)
   ----------------------------------------------------------------
   --portal-accent → var(--accent), and keystone sets --accent ONLY in its
   LIGHT palette blocks; the dark @media block redefines --color-accent /
   --color-accent-bright but never the --accent alias. So in OS dark mode every
   element that paints the accent as a FOREGROUND / indicator (active-tab text +
   underline, stat-chip icon, card-title icon, focus ring) is drawn in the dim
   LIGHT accent on a near-black surface and falls below WCAG contrast.
   Retarget those to the per-palette dark --color-accent-bright (which keystone
   DOES brighten for dark). Buttons are intentionally untouched: they use the
   accent as a BACKGROUND with white text, which already passes — brightening it
   there would invert the problem (white-on-light-blue).
   Scoped to [data-keystone] .portal-scope so the native engine + light mode are
   never affected. Verified contrast (dark): bright accent fg lands 5.8–7.3:1.
   ================================================================ */
@media (prefers-color-scheme: dark) {
  /* Prose / content links (email, phone, in-body links) — same stuck-light
     accent, ~2:1 on the dark card. Brighten to the per-palette dark accent so
     they read clearly AND stay visibly "link-coloured" against the white body
     text. */
  [data-keystone] .portal-scope a:not([class]) { color: var(--color-accent-bright); }

  /* Left rail: active link uses the stuck-light accent on the dark page → brighten. */
  [data-keystone] .portal-scope .portal-sidenav__link.active,
  [data-keystone] .portal-scope .portal-sidenav__link[aria-current="page"] {
    color: var(--color-accent-bright);
    background: color-mix(in srgb, var(--color-accent-bright) 14%, transparent);
  }
  [data-keystone] .portal-scope .portal-sidenav__link--signout:hover { color: #f87171; }

  /* Mobile menu overlay nav (lives OUTSIDE .portal-scope, in #nav-overlay). */
  [data-keystone] .portal-ovnav__link.active,
  [data-keystone] .portal-ovnav__link[aria-current="page"] { color: var(--color-accent-bright); }

  [data-keystone] .portal-scope .portal-card__title svg { color: var(--color-accent-bright); }

  [data-keystone] .portal-scope .portal-stat__icon {
    background: color-mix(in srgb, var(--color-accent-bright) 18%, transparent);
    color: var(--color-accent-bright);
  }
  /* keep the warning/alert chip its signal colour, not the bright accent */
  [data-keystone] .portal-scope .portal-stat--alert .portal-stat__icon {
    background: var(--portal-warning-bg);
    color: var(--portal-warning);
  }

  [data-keystone] .portal-scope .portal-input:focus,
  [data-keystone] .portal-scope .portal-select:focus,
  [data-keystone] .portal-scope .portal-textarea:focus {
    border-color: var(--color-accent-bright);
    box-shadow: 0 0 0 3px color-mix(in srgb, var(--color-accent-bright) 45%, transparent);
  }

  /* ---- Upload dropzone + file list (accent-as-foreground on dark) ---- */
  [data-keystone] .portal-scope .portal-dropzone:hover {
    border-color: var(--color-accent-bright);
    background: color-mix(in srgb, var(--color-accent-bright) 10%, transparent);
  }
  [data-keystone] .portal-scope .portal-dropzone.is-dragover,
  [data-keystone] .portal-scope .portal-dropzone__input:focus-visible + .portal-dropzone {
    border-color: var(--color-accent-bright);
    background: color-mix(in srgb, var(--color-accent-bright) 12%, transparent);
    box-shadow: 0 0 0 3px color-mix(in srgb, var(--color-accent-bright) 35%, transparent);
  }
  [data-keystone] .portal-scope .portal-dropzone__icon {
    background: color-mix(in srgb, var(--color-accent-bright) 18%, transparent);
    color: var(--color-accent-bright);
  }
  [data-keystone] .portal-scope .portal-dropzone__browse,
  [data-keystone] .portal-scope .portal-dropzone__chip-icon,
  [data-keystone] .portal-scope .portal-dropzone__chip-swap { color: var(--color-accent-bright); }

  [data-keystone] .portal-scope .portal-fileitem__name { color: var(--color-accent-bright); }
  [data-keystone] .portal-scope .portal-fileitem:hover {
    border-color: var(--color-accent-bright);
    background: color-mix(in srgb, var(--color-accent-bright) 8%, transparent);
  }
  /* default (no-family) tile + badge: brighten BOTH bg and glyph so the tile stays visible */
  [data-keystone] .portal-scope .portal-fileitem__icon,
  [data-keystone] .portal-scope .portal-ftype {
    background: color-mix(in srgb, var(--color-accent-bright) 16%, transparent);
    color: var(--color-accent-bright);
  }
  /* RE-PIN every signal family (at .portal-scope specificity) so the default
     brighten above can't bleed onto PDF/image/doc/zip/text/file tiles. */
  [data-keystone] .portal-scope .portal-fileitem__icon--pdf,
  [data-keystone] .portal-scope .portal-ftype--pdf   { background: var(--portal-error-bg);   color: var(--portal-error); }
  [data-keystone] .portal-scope .portal-fileitem__icon--image,
  [data-keystone] .portal-scope .portal-fileitem__icon--sheet,
  [data-keystone] .portal-scope .portal-ftype--image,
  [data-keystone] .portal-scope .portal-ftype--sheet { background: var(--portal-success-bg); color: var(--portal-success); }
  [data-keystone] .portal-scope .portal-fileitem__icon--doc,
  [data-keystone] .portal-scope .portal-ftype--doc   { background: var(--portal-info-bg);    color: var(--portal-info); }
  [data-keystone] .portal-scope .portal-fileitem__icon--zip,
  [data-keystone] .portal-scope .portal-ftype--zip   { background: var(--portal-warning-bg); color: var(--portal-warning); }
  [data-keystone] .portal-scope .portal-fileitem__icon--text,
  [data-keystone] .portal-scope .portal-fileitem__icon--file,
  [data-keystone] .portal-scope .portal-ftype--text,
  [data-keystone] .portal-scope .portal-ftype--file  { background: var(--portal-surface);    color: var(--portal-text-muted); }

  /* the new prominent ghost Download button: brighten its hover border too */
  [data-keystone] .portal-scope .portal-btn--ghost:hover { border-color: var(--color-accent-bright); }

  /* Accent-as-foreground the earlier remediation missed — all stuck at the light
     --accent on the dark page (WCAG 1.4.3 / 1.4.11): Inbox subject links (the
     reported faint links), the active status-filter tab + its underline, the
     GLOBAL keyboard focus ring, and accent hover states on breadcrumb / footer /
     login legal links + the copy button. --color-accent-bright is the per-palette
     dark accent keystone.css defines. */
  [data-keystone] .portal-scope .portal-table a:not(.portal-btn) { color: var(--color-accent-bright); }
  [data-keystone] .portal-scope .portal-filter-tab--active {
    color: var(--color-accent-bright);
    border-bottom-color: var(--color-accent-bright);
  }
  [data-keystone] .portal-scope :focus-visible { outline-color: var(--color-accent-bright); }
  [data-keystone] .portal-scope .portal-breadcrumb a:hover,
  [data-keystone] .portal-scope .portal-footer__legal a:hover,
  [data-keystone] .portal-scope .portal-login__legal a:hover,
  [data-keystone] .portal-scope .portal-copy-btn:hover { color: var(--color-accent-bright); }
}

/* ================================================================
   AUTH BAND + CARD  —  shared-safe refinements (login/register/forgot/reset/join)
   .portal-auth, .portal-card, .portal-auth__card, .portal-auth__title,
   .portal-auth__intro are reused by ALL auth pages, so these stay generic.
   Login-only flourishes live under .portal-login__* further down. Token-only
   colors → retint automatically to brass(gold) or harbor(blue).
   ================================================================ */

/* Center the card in the band between the site header and the footer,
   killing the old "card floats high, big empty gap below" problem. */
.portal-auth {
  max-width: 460px;
  margin: 0 auto;
  padding: 32px 0 48px;
  min-height: calc(100vh - var(--portal-header-h, 56px) - 140px);
  display: flex;
  flex-direction: column;
  justify-content: center;
}

/* Width cap + comfortable padding + refined depth for the auth card specifically
   (applies equally to register/forgot/reset/join). */
.portal-auth__card {
  width: 100%;
  padding: 36px 34px 32px;
  border-radius: var(--portal-radius-lg);
  box-shadow: var(--portal-shadow-md);
}

/* Generic auth title — crisp, centered, applies to every auth page. */
.portal-auth__title {
  font-family: var(--portal-font-heading);
  font-size: 1.5rem;
  font-weight: 800;
  line-height: 1.2;
  letter-spacing: -0.015em;
  text-align: center;
  color: var(--portal-text);
  margin: 0;
}

/* Generic auth intro — settled spacing under the title, all auth pages. */
.portal-auth__intro {
  text-align: center;
  font-size: 0.9375rem;
  line-height: 1.55;
  color: var(--portal-text-muted);
  margin: 8px auto 22px;
  max-width: 36ch;
}

/* The auth alert should breathe inside the card. */
.portal-auth__card .portal-alert { margin-bottom: 18px; }

/* ================================================================
   LOGIN-ONLY flourishes  —  NEW classes, only emitted by portal/index.php
   ================================================================ */

/* Brand crest: tinted accent wash square with the accent-coloured house mark. */
.portal-login__mark {
  width: 52px;
  height: 52px;
  margin: 0 auto 18px;
  border-radius: var(--portal-radius);
  display: flex;
  align-items: center;
  justify-content: center;
  background: var(--portal-accent-tint);
  color: var(--portal-accent);
  border: 1px solid var(--portal-accent-tint-2);
}
.portal-login__mark svg { display: block; }

/* Demo credentials callout — a tidy tinted panel, not a run-on sentence. */
.portal-login__demo {
  margin: 4px 0 20px;
  padding: 14px 16px;
  background: var(--portal-accent-tint);
  border: 1px solid var(--portal-accent-tint-2);
  border-radius: var(--portal-radius);
}
.portal-login__demo-head {
  display: flex;
  align-items: center;
  gap: 7px;
  font-size: 0.6875rem;
  font-weight: 700;
  letter-spacing: 0.07em;
  text-transform: uppercase;
  color: var(--portal-accent);
  margin-bottom: 10px;
}
.portal-login__demo-head svg { flex-shrink: 0; }
.portal-login__demo-row {
  display: flex;
  align-items: baseline;
  gap: 10px;
  font-size: 0.875rem;
  line-height: 1.5;
}
.portal-login__demo-row + .portal-login__demo-row { margin-top: 5px; }
.portal-login__demo-label {
  flex-shrink: 0;
  width: 72px;
  font-size: 0.6875rem;
  font-weight: 700;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  color: var(--portal-text-muted);
}
.portal-login__demo-val {
  font-family: 'SFMono-Regular', 'Consolas', 'Liberation Mono', monospace;
  font-size: 0.8125rem;
  color: var(--portal-text);
  word-break: break-all;
}

/* "or" divider between the credential form and the secondary demo button. */
.portal-login__or {
  display: flex;
  align-items: center;
  gap: 12px;
  margin: 18px 0;
  font-size: 0.75rem;
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--portal-text-muted);
}
.portal-login__or::before,
.portal-login__or::after {
  content: '';
  flex: 1;
  height: 1px;
  background: var(--portal-border);
}

/* Demo button: full-width secondary, sits below the divider. */
.portal-login__demo-btn { width: 100%; }

/* Footnote under the demo button + the self-registration line. */
.portal-login__note {
  text-align: center;
  margin-top: 10px;
}
.portal-login__signup {
  text-align: center;
  margin-top: 20px;
  padding-top: 16px;
  border-top: 1px solid var(--portal-border);
}

/* ---- Mobile: full-width card, 16px inputs (no iOS zoom), 44px targets ---- */
@media (max-width: 640px) {
  .portal-auth {
    max-width: none;
    padding: 16px 0 40px;
    min-height: calc(100vh - var(--portal-header-h, 56px) - 96px);
  }
  .portal-auth__card { padding: 26px 20px 24px; }
  .portal-auth__title { font-size: 1.3125rem; }
  /* 16px font-size on inputs prevents iOS Safari auto-zoom on focus. */
  .portal-auth__card .portal-input { font-size: 16px; }
  /* Stack label above value so a long email never collides with its label or
     forces horizontal scroll on narrow phones. */
  .portal-login__demo-row { flex-direction: column; align-items: flex-start; gap: 2px; }
  .portal-login__demo-label { width: auto; }
}

/* A portal table marked --stack becomes one block per row on a phone, so the
   row's action (e.g. "Review & sign") is always in view instead of past the
   right edge of a sideways-scrolling table. Desktop is unchanged. */
@media (max-width: 640px) {
  .portal-table--stack thead { display: none; }
  .portal-table--stack,
  .portal-table--stack tbody,
  .portal-table--stack tr,
  .portal-table--stack td { display: block; width: 100%; }
  .portal-table--stack { min-width: 0; }
  .portal-table--stack tbody tr { padding: .85rem 1rem; border-bottom: 1px solid var(--portal-border, var(--border)); }
  .portal-table--stack tbody tr:last-child { border-bottom: 0; }
  .portal-table--stack td { padding: .15rem 0; border: 0; }
  .portal-table--stack td:first-child { font-weight: 600; color: var(--text-primary); }
  .portal-table--stack td[data-label]::before { content: attr(data-label) " \00B7  "; color: var(--text-secondary); }
  .portal-table--stack td:last-child { padding-top: .65rem; }
  .portal-table--stack td:last-child .portal-btn-row { flex-wrap: wrap; }
  /* A theme's table cell rules (a rule under every cell, roomy padding) are
     for rows side by side; stacked, only the row keeps its rule. */
  .portal-scope .portal-table.portal-table--stack tbody td { border: 0; padding: .15rem 0; }
  .portal-scope .portal-table.portal-table--stack tbody td:last-child:has(.portal-btn) { padding-top: .65rem; }
}

/* ----------------------------------------------------------------
   Card body copy
   A sentence or paragraph inside a card is set in the body face. A one-line
   hint under a field stays .portal-field-help.
   ---------------------------------------------------------------- */
.portal-card__text {
  margin: 0 0 12px;
  font-family: var(--portal-font);
  font-size: 0.875rem;
  line-height: 1.6;
  color: var(--portal-text-muted);
}
.portal-card__text:last-child { margin-bottom: 0; }

/* Two tables stacked on one page (To sign: awaiting, then signed) share one set
   of column widths, so their dates and buttons line up. */
.portal-table--fixed { table-layout: fixed; }
.portal-table--fixed th:first-child { width: 60%; }
.portal-table--fixed th:not(:first-child) { width: 20%; }
.portal-table--fixed td:first-child { min-width: 0; overflow-wrap: anywhere; }

/* The owner's avatar on a message: their first initial in a tile. */
.portal-msg__avatar {
  display: inline-grid;
  place-items: center;
  flex: none;
  width: 28px;
  height: 28px;
  border-radius: 50%;
  background: var(--portal-accent-tint);
  color: var(--portal-accent);
  font-size: 0.8125rem;
  font-weight: 700;
  line-height: 1;
  text-transform: uppercase;
}
.portal-reply__meta .portal-msg__avatar { width: 22px; height: 22px; font-size: 0.6875rem; }

/* A conversation's one meta line under its title: status (when shown) and
   "Started Sep 28, 2026". */
.portal-msg-meta {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px;
}

/* A checkbox setting with its note below (Settings: "Email me when I reply"),
   set off from the fields above by a rule. */
.portal-field--check {
  border-top: 1px solid var(--portal-border);
  padding-top: 1.1rem;
  margin-top: .25rem;
}
.portal-field--check > label {
  display: flex;
  align-items: flex-start;
  gap: .6rem;
  line-height: 1.6;
  cursor: pointer;
}
.portal-field--check > label > input { flex: none; margin-top: .25rem; }
.portal-field--check > label > span { font-weight: 600; color: var(--portal-text); }
.portal-field--check > .portal-field-help { margin-top: .25rem; padding-left: calc(16px + .6rem); }

/* ----------------------------------------------------------------
   Form-builder forms inside the portal (intake forms)
   The form engine is shared with the public site, and its labels, fields and
   buttons come from the site stylesheet (and any owner CSS written for public
   forms). Inside the portal it takes the portal's own form language instead:
   portal labels, portal fields, portal buttons, and help text BELOW the field,
   as on every other portal form.
   ---------------------------------------------------------------- */
.portal-scope .vp-form .form-label:not(.vp-form__check) {
  display: block;
  margin: 0 0 6px;
  font-family: var(--portal-font);
  font-size: 0.875rem;
  font-weight: 600;
  line-height: 1.45;
  letter-spacing: 0;
  text-transform: none;
  color: var(--portal-text);
}

/* Help below the field: the field is a column, the fieldset of a choice group
   becomes one too, and the help paragraph moves after the control. */
.portal-scope .vp-form .form-field > fieldset { display: flex; flex-direction: column; min-width: 0; }
.portal-scope .vp-form .form-field p[id$="_help"] {
  order: 1;
  font-family: var(--portal-font);
  line-height: 1.5;
  color: var(--portal-text-muted);
}
.portal-scope .vp-form .vp-form__field-error { order: 2; }

.portal-scope .vp-form :is(.form-input, .form-textarea):not(.vp-file__input) {
  width: 100%;
  border: 1px solid color-mix(in srgb, var(--color-border, #8A93A3) 70%, var(--text-primary, #151C28) 30%);
  border-radius: var(--portal-radius-sm);
  background-color: var(--portal-input-bg, #fff);
  color: var(--portal-text);
  font-family: var(--portal-font);
  font-size: 0.9375rem;
  line-height: 1.5;
}
.portal-scope .vp-form .form-input:not(.vp-file__input) { min-height: 44px; padding: 0 12px; }
.portal-scope .vp-form .form-textarea { padding: 10px 12px; min-height: 120px; }
.portal-scope .vp-form select.form-input {
  -webkit-appearance: none;
  appearance: none;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 24 24' fill='none' stroke='%23888888' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='6 9 12 15 18 9'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right 10px center;
  padding-right: 36px;
  cursor: pointer;
}
.portal-scope .vp-form :is(.form-input, .form-textarea):not(.vp-file__input):focus {
  outline: none;
  border-color: var(--portal-accent);
  box-shadow: 0 0 0 3px var(--portal-accent-tint-2);
}

.portal-scope .vp-form .btn {
  min-height: 44px;
  padding: 0 22px;
  border: 0;
  border-radius: var(--portal-radius-sm);
  box-shadow: none;
  font-family: var(--portal-font);
  font-size: 15px;
  font-weight: 600;
  letter-spacing: 0;
  line-height: 1;
}
.portal-scope .vp-form .btn--sm { min-height: 34px; padding: 0 14px; font-size: 0.8125rem; }
.portal-scope .vp-form .btn--primary { background: var(--portal-accent); color: var(--portal-on-accent); }
.portal-scope .vp-form .btn--primary:hover { background: var(--portal-accent-hover); color: var(--portal-on-accent); }
.portal-scope .vp-form .btn--ghost { background: transparent; color: var(--portal-text); border: 1.5px solid var(--portal-border); }
.portal-scope .vp-form .btn--ghost:hover { background: var(--portal-surface); border-color: var(--portal-accent); }

/* A form sent in a conversation sits in the message that sent it: no second
   frame inside the message's own. */
.portal-scope .portal-reply--card .jr-card {
  margin-top: 8px;
  padding: 0;
  border: 0;
  background: transparent;
}

/* ----------------------------------------------------------------
   E-sign fields on the page
   The document is drawn at the width of the screen, so a field is a few pixels
   tall on a phone. Each field is its own size container, and the words in it
   follow the field's height: never taller than the box, never cut off. The
   largest sizes are the desktop ones from esign.css. Browsers without
   container units keep those.
   ---------------------------------------------------------------- */
.portal-scope .esign-sfield { container-type: size; }
.portal-scope .esign-sfield__hint { font-size: clamp(6px, 48cqh, 0.7rem); line-height: 1; }
.portal-scope .esign-sfield__text {
  min-width: 0;
  max-width: 100%;
  font-size: clamp(6px, 60cqh, 0.78rem);
  line-height: 1.1;
  text-overflow: ellipsis;
}
.portal-scope .esign-sfield__input { font-size: clamp(6px, 60cqh, 0.8rem); }
