/* ══════════════════════════════════════════════════════════════════
   portal.css - the "flow" and "portal" rooms (WP-0, 2026-10-10; brief section 2)

   base.html loads this file only when a child template sets
       {% set shell = 'flow' %}     details, quick questions, sign, done
       {% set shell = 'portal' %}   everything after sign-in, and the case-number view
   and writes <body ... data-shell="flow|portal">. Marketing pages (data-shell="site")
   never load it, and every rule below is scoped to [data-shell=flow] / [data-shell=portal],
   so the marketing look ("Plan A clear blue", app.css) cannot change because of it.

   What makes these rooms different: a dark slate top bar (portal) or a plain white bar
   (flow) instead of the marketing header; ink and copper instead of azure; rectangular
   buttons with 10px corners instead of pills; no illustrations, maps or big hero numbers;
   a narrower column (flow 560px, portal 720px). Not beige/cream, not serif, no full-page
   1px borders - those are what the owner rejected in 2026-09.

   ── Rules that are not taste ──
   ⛔ Font sizes ONLY as one plain var(--fs-*) (body.p-full caps them at 17px, so the sign page
      stays legal automatically). No hard-coded sizes, no calc() - not even around a capped
      variable -, no font: shorthand other than inherit, no new or redefined --fs-* variable
      (it would need its own p-full cap in app.css). Nothing that enlarges type without
      touching font-size: no zoom, no transform scale()/matrix()/perspective() or 3D function
      (translateZ, rotateX …), no scale:, no perspective:, no 3-value translate:, no X/Y rotate:,
      no size-adjust / font-size-adjust / text-size-adjust (flat rotate and translate are fine),
      with or without a -webkit- prefix, and never through var(). No custom property holding
      scale()/3D, and nothing moves or scales in a :hover / :focus / :active / :checked … rule.
      compliance.py (check_typography C3) fails on any of these in this file, wherever the
      declaration is written (any letter case, split over lines), and qa/run_ux.py measures
      the result in a real browser with every fold opened and every state rule forced on.
   ⛔ Never write a closing brace inside a comment in a :root block - compliance._block()
      stops at the first one and every token after it becomes invisible to the contrast gate.
   ⛔ Colour pairs are checked by compliance.check_contrast (PORTAL_CONTRAST_PAIRS), light and
      dark. Change a token -> run python compliance.py.
   Colour meanings are fixed: copper = something for the customer to do (rare); green = done
   or saved; amber = a date; red = an error. Colour never works alone - always with a word
   or an icon. Motion: 150ms colour transitions only.
   ══════════════════════════════════════════════════════════════════ */

/* ─────────── tokens (brief 2.2) ─────────── */

:root {
  --pt-canvas:  #F3F4F6;   /* page background */
  --pt-surface: #FFFFFF;   /* cards */
  --pt-inset:   #F8F9FA;   /* inset panels (Your details, folds) */
  --pt-line:    #E3E6EA;   /* dividers; card borders only in dark mode */
  --pt-field:   #7D8691;   /* input / pill / pad borders (non-text, needs 3:1) */
  --pt-ink:     #1B2430;   /* body text, headings */
  --pt-ink-2:   #4B5563;   /* secondary text */
  --pt-ink-3:   #5B6472;   /* captions, footnotes */
  --pt-chrome:        #1B2430;   /* portal top bar */
  --pt-chrome-ink:    #E9EDF2;   /* top bar text */
  --pt-chrome-mute:   #AEB8C4;   /* inactive tabs */
  --pt-chrome-accent: #E08A5A;   /* active tab underline */
  --pt-chrome-focus:  var(--pt-chrome-ink);   /* keyboard focus ring on the slate bar (link blue is 2.3:1 there) */
  --pt-act:       #A9522B;   /* primary button fill = your move; action banner rule */
  --pt-act-hover: #8C4322;
  --pt-act-fg:    #FFFFFF;   /* text on the primary button */
  --pt-act-ink:   #9A4A26;   /* action banner text */
  --pt-act-soft:  #FBEFE8;   /* action banner background */
  --pt-link:      #255E91;
  --pt-done:      #0C7A54;   /* completed steps, savings (same as marketing --money) */
  --pt-done-soft: #E7F6EF;
  --pt-due:       #8F5E13;   /* dates and deadlines (same as marketing --warn) */
  --pt-due-soft:  #FDF4E3;
  --pt-err:       #B42318;   /* errors only */
  --pt-err-soft:  #FEF3F2;
  --pt-todo:      #7D8691;   /* upcoming step markers (non-text, needs 3:1) */
  --pt-radius-card: 12px;
  --pt-radius:      10px;
  --pt-col-flow:   560px;
  --pt-col-portal: 720px;
  --pt-col-bar:   1080px;
}

@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    --pt-canvas:  #111418;
    --pt-surface: #1A1F26;
    --pt-inset:   #151A20;
    --pt-line:    #2A313A;
    --pt-field:   #6B7380;
    --pt-ink:     #E6E9ED;
    --pt-ink-2:   #AEB6C0;
    --pt-ink-3:   #959EAA;
    --pt-chrome:        #0B0E12;
    --pt-chrome-ink:    #E6E9ED;
    --pt-chrome-mute:   #A3ADB9;
    --pt-chrome-accent: #E38B5F;
    --pt-act:       #E38B5F;
    --pt-act-hover: #EE9D74;
    --pt-act-fg:    #1A1F26;
    --pt-act-ink:   #F2A983;
    --pt-act-soft:  #2B1F18;
    --pt-link:      #8DB8E6;
    --pt-done:      #4CC38A;
    --pt-done-soft: #13271F;
    --pt-due:       #E3A857;
    --pt-due-soft:  #2A2317;
    --pt-err:       #F97066;
    --pt-err-soft:  #2E1917;
    --pt-todo:      #6B7380;
  }
}

/* ─────────── page ─────────── */

:is([data-shell=flow],[data-shell=portal]) {
  background: var(--pt-canvas);
  color: var(--pt-ink);
  line-height: 1.6;
}
html:is(:lang(zh),:lang(ko)) :is([data-shell=flow],[data-shell=portal]) { line-height: 1.75; }
/* Korean: break lines between words, never inside one (a long word may still break rather than scroll
   sideways). Covers every flow / portal page, so the per-template copies are no longer needed (WP-1). */
html:lang(ko) :is([data-shell=flow],[data-shell=portal]),
html:lang(ko) :is([data-shell=flow],[data-shell=portal]) main { word-break: keep-all; overflow-wrap: anywhere; }

/* The marketing .wrap is a 1200px column with side padding; the bars here are full width. */
:is([data-shell=flow],[data-shell=portal]) .wrap { max-width: none; padding: 0; }

:is([data-shell=flow],[data-shell=portal]) main {
  margin: 0 auto;
  padding: var(--sp-4) var(--sp-3) var(--sp-6);
  overflow-wrap: break-word;     /* an email, case number or long address never scrolls the page sideways */
}
[data-shell=flow] main   { max-width: calc(var(--pt-col-flow) + 2 * var(--sp-3)); }
[data-shell=portal] main { max-width: calc(var(--pt-col-portal) + 2 * var(--sp-3)); padding-top: var(--sp-5); }

:is([data-shell=flow],[data-shell=portal]) :focus-visible {
  outline: 2px solid var(--pt-link); outline-offset: 2px;
}
:is([data-shell=flow],[data-shell=portal]) a { color: var(--pt-link); }
:is([data-shell=flow],[data-shell=portal]) :is(small, .small) { color: var(--pt-ink-2); }
:is([data-shell=flow],[data-shell=portal]) .tiny { color: var(--pt-ink-3); }

/* Type (brief 2.3). On the sign page every one of these drops to 17px or less by itself. */
:is([data-shell=flow],[data-shell=portal]) main h1 {
  font-size: var(--fs-h2); font-weight: 700; line-height: 1.3; letter-spacing: -.01em;
  margin: 0 0 var(--sp-2);
}
:is([data-shell=flow],[data-shell=portal]) main h2 {
  font-size: var(--fs-h3); font-weight: 700; line-height: 1.35; letter-spacing: 0;
  margin: var(--sp-5) 0 var(--sp-2); padding: 0; border: 0;
}
:is([data-shell=flow],[data-shell=portal]) main h3 {
  font-size: var(--fs-body); font-weight: 700; line-height: 1.4; margin: var(--sp-4) 0 var(--sp-1);
}
:is([data-shell=flow],[data-shell=portal]) main :is(h2, h3):first-child { margin-top: 0; }
:is([data-shell=flow],[data-shell=portal]) .lede,
.pt-lede { font-size: var(--fs-body); color: var(--pt-ink-2); line-height: inherit; margin: 0 0 var(--sp-4); }
.pt-num, :is([data-shell=flow],[data-shell=portal]) .num { font-variant-numeric: tabular-nums; }

/* ─────────── statutory box (sign page) ───────────
   Same text, same 20px bold, same 3px frame, still first on the page (base.html, outside
   every block). Only the colours get calmer: dark ink frame on white, nothing red. */
:is([data-shell=flow],[data-shell=portal]) .disclosure-band { padding: var(--sp-3) var(--sp-3) 0; }
:is([data-shell=flow],[data-shell=portal]).p-full .disclosure-band { padding-bottom: var(--sp-3); }
:is([data-shell=flow],[data-shell=portal]) .disclosure-band .disclosure {
  max-width: 960px;
  background: var(--pt-surface);
  border-color: var(--pt-ink);
}
:is([data-shell=flow],[data-shell=portal]) .disclosure p.stat { color: var(--pt-ink); }
:is([data-shell=flow],[data-shell=portal]) .disclosure .cite,
:is([data-shell=flow],[data-shell=portal]) .disclosure .gloss summary { color: var(--pt-ink-3); }
:is([data-shell=flow],[data-shell=portal]) .disclosure .gloss { color: var(--pt-ink-2); border-top-color: var(--pt-line); }

/* ─────────── flow header (brief 2.5) ───────────
   56px, white: logo · ← Back · Step 2 of 3 · Details · language · ×  */
.flowbar { background: var(--pt-surface); border-bottom: 1px solid var(--pt-line); }
.bar-in {
  margin: 0 auto; padding: 0 var(--sp-3);
  min-height: 56px; display: flex; align-items: center; gap: var(--sp-2);
}
.flowbar .bar-in { max-width: calc(var(--pt-col-flow) + 2 * var(--sp-3)); }
:is(.flowbar,.portalbar) .brand {
  display: inline-flex; align-items: center; gap: var(--sp-2); min-height: 44px;
  font-size: var(--fs-brand); font-weight: 800; letter-spacing: -.02em;
  color: inherit; text-decoration: none;
}
:is(.flowbar,.portalbar) .brand .mark { width: 28px; height: 28px; }
.flowbar .brand { color: var(--pt-ink); }
.fb-back {
  display: inline-flex; align-items: center; gap: 6px; min-height: 44px; padding: 0 var(--sp-1);
  color: var(--pt-ink-2); text-decoration: none; font-size: var(--fs-small); font-weight: 600;
  transition: color .15s ease;
}
:is([data-shell=flow],[data-shell=portal]) .fb-back { color: var(--pt-ink-2); }
.fb-back:hover { color: var(--pt-ink); }
.fb-back svg, .fb-close svg { flex: none; }
.fb-step {
  margin: 0 0 0 auto; font-size: var(--fs-small); color: var(--pt-ink-2); white-space: nowrap;
}
.fb-step .short { display: none; }
/* the language menu sits at the right edge; when there is a step label, that label carries the push
   (Done, sign-in and other flow pages without a step used to show the menu next to the logo) */
.flowbar .langmenu { margin-left: auto; }
.flowbar .fb-step ~ .langmenu { margin-left: 0; }
.fb-close {
  display: inline-flex; align-items: center; justify-content: center;
  width: 44px; height: 44px; border-radius: var(--pt-radius);
  color: var(--pt-ink-2); transition: color .15s ease, background-color .15s ease;
}
:is([data-shell=flow],[data-shell=portal]) .fb-close { color: var(--pt-ink-2); }
.fb-close:hover { color: var(--pt-ink); background: var(--pt-inset); }

/* ─────────── portal top bar (brief 2.5) ───────────
   56px slate: otter + HiHolt · My property · Documents · Account · (who) · language · Sign out
   Case-number mode: Your case · Documents · (Viewing case C26…, no login) · Create login, or
   Sign in when the property already has a login (base.html decides; .pt-barbtn is either one) */
.portalbar { background: var(--pt-chrome); color: var(--pt-chrome-ink); }
.portalbar .bar-in { max-width: calc(var(--pt-col-bar) + 2 * var(--sp-3)); gap: var(--sp-3); }
.portalbar .brand { color: var(--pt-chrome-ink); }
.pt-tabs { display: flex; align-self: stretch; gap: var(--sp-1); margin: 0 0 0 var(--sp-3); }
.pt-tabs a {
  display: inline-flex; align-items: center; min-height: 44px; padding: 0 var(--sp-3);
  color: var(--pt-chrome-mute); text-decoration: none;
  font-size: var(--fs-small); font-weight: 600;
  box-shadow: inset 0 -3px 0 0 transparent;
  transition: color .15s ease, box-shadow .15s ease;
}
:is([data-shell=flow],[data-shell=portal]) .pt-tabs a { color: var(--pt-chrome-mute); }
.pt-tabs a:hover,
:is([data-shell=flow],[data-shell=portal]) .pt-tabs a:hover { color: var(--pt-chrome-ink); }
.pt-tabs a[aria-current="page"],
:is([data-shell=flow],[data-shell=portal]) .pt-tabs a[aria-current="page"] {
  color: var(--pt-chrome-ink);
  box-shadow: inset 0 -3px 0 0 var(--pt-chrome-accent);
}
.pt-who {
  margin: 0 0 0 auto; min-width: 0;
  font-size: var(--fs-tiny); line-height: 1.35; color: var(--pt-chrome-mute);
  overflow-wrap: anywhere;
}
.pt-signout { margin: 0; }
.pt-signout button {
  min-height: 44px; padding: 0 var(--sp-2); border: 0; background: none; cursor: pointer;
  color: var(--pt-chrome-ink); font-family: var(--font); font-size: var(--fs-small); font-weight: 600;
  transition: color .15s ease;
}
.pt-signout button:hover { color: var(--pt-chrome-accent); }
.pt-barbtn,
:is([data-shell=flow],[data-shell=portal]) .pt-barbtn {
  display: inline-flex; align-items: center; min-height: 40px; padding: 0 var(--sp-3);
  border: 1.5px solid var(--pt-chrome-mute); border-radius: var(--pt-radius);
  color: var(--pt-chrome-ink); text-decoration: none; font-size: var(--fs-small); font-weight: 600;
  white-space: nowrap; transition: border-color .15s ease, color .15s ease;
}
.pt-barbtn:hover { border-color: var(--pt-chrome-ink); }
/* Keyboard focus on the slate bar. The shell-wide ring is --pt-link, which is only 2.3:1 on
   --pt-chrome; here it uses --pt-chrome-focus (the bar's own ink, 13:1; checked by
   compliance PORTAL_CONTRAST_PAIRS). The tabs fill the bar from edge to edge, so their ring is
   drawn inside them and never lands on the light page below. The language list is a white
   dropdown: its links keep the blue ring. Same specificity as the shell rule, so keep these
   after it in this file. */
.portalbar :focus-visible { outline-color: var(--pt-chrome-focus); }
.portalbar .pt-tabs a:focus-visible { outline-offset: -3px; }
.portalbar .langmenu-list :focus-visible { outline-color: var(--pt-link); }

/* language menu inside the bars: always visible, 44px target */
:is(.flowbar,.portalbar) .langmenu summary {
  min-height: 44px; min-width: 44px; justify-content: center; padding: 0 var(--sp-2);
  border-radius: var(--pt-radius); transition: color .15s ease;
}
.flowbar .langmenu summary { color: var(--pt-ink-2); }
.flowbar .langmenu summary:hover { color: var(--pt-ink); }
.portalbar .langmenu summary { color: var(--pt-chrome-ink); }
.portalbar .langmenu summary:hover { color: var(--pt-chrome-accent); }
:is(.flowbar,.portalbar) .langmenu-list {
  right: 0; left: auto; background: var(--pt-surface); border-color: var(--pt-line);
}
:is(.flowbar,.portalbar) .langmenu-list a {
  min-height: 44px; display: flex; align-items: center; color: var(--pt-ink-2);
}
:is(.flowbar,.portalbar) .langmenu-list a:hover { background: var(--pt-inset); color: var(--pt-link); }

/* ─────────── footer (flow / portal) ───────────
   One line: legal entity · Disclosures · Terms · Privacy · contact (only when CONTACT_READY),
   plus the mini disclosure on every page that does not carry the full box. No 2.165 badge. */
:is([data-shell=flow],[data-shell=portal]) footer.site {
  margin: var(--sp-6) auto 0; padding: var(--sp-4) var(--sp-3) var(--sp-5);
  border-top: 1px solid var(--pt-line);
  font-size: var(--fs-tiny); color: var(--pt-ink-3);
}
[data-shell=flow] footer.site   { max-width: calc(var(--pt-col-flow) + 2 * var(--sp-3)); }
[data-shell=portal] footer.site { max-width: calc(var(--pt-col-portal) + 2 * var(--sp-3)); }
:is([data-shell=flow],[data-shell=portal]) footer.site .disclosure.mini {
  border: 0; padding: 0; margin: 0 0 var(--sp-3);
}
:is([data-shell=flow],[data-shell=portal]) footer.site .disclosure.mini p { color: var(--pt-ink-2); }
:is([data-shell=flow],[data-shell=portal]) footer.site a { color: var(--pt-ink-2); }
/* Separators: base.html puts one aria-hidden dot before every item, in its own span outside the link, so it
   is never underlined and never inside a focus ring (they used to be ::before inside the <a> and read as
   underlined colons). The row is shifted left by one dot's width and that strip is clipped: whichever item
   starts a line, wrapped or not, has its dot cut off - a line never starts with "·". The clip stops 0.5em
   short of the text so focus rings stay whole. */
.foot-line {
  display: flex; flex-wrap: wrap; align-items: center; row-gap: var(--sp-1);
  margin: 0 0 0 -2.25em;
  clip-path: inset(-.5em -.5em -.5em 1.75em);
}
.foot-item { display: inline-flex; align-items: baseline; }
.foot-sep {
  display: inline-block; flex: none; width: 2.25em; text-align: center;
  color: var(--pt-ink-3); text-decoration: none;
}

/* ─────────── card ─────────── */

:is([data-shell=flow],[data-shell=portal]) .card,
.pt-card {
  background: var(--pt-surface); border: 0; border-radius: var(--pt-radius-card);
  box-shadow: var(--sh-md); padding: var(--sp-4); margin: 0 0 var(--sp-3);
}
:is([data-shell=flow],[data-shell=portal]) .card.flat { background: var(--pt-inset); box-shadow: none; }
/* scoped so it also wins over the shell's main h2 / h3 rules when used on a heading */
.pt-card-title,
:is([data-shell=flow],[data-shell=portal]) .pt-card-title { font-size: var(--fs-h3); font-weight: 700; line-height: 1.35; margin: 0 0 var(--sp-2); }
.pt-section { margin: var(--sp-5) 0 0; }

/* ─────────── inset box (label / value rows) ─────────── */

.pt-inset {
  background: var(--pt-inset); border-radius: var(--pt-radius);
  padding: var(--sp-3); margin: 0 0 var(--sp-3);
}
.pt-rows { display: grid; grid-template-columns: max-content 1fr; gap: var(--sp-1) var(--sp-3); margin: 0; }
.pt-rows dt { color: var(--pt-ink-3); font-size: var(--fs-small); }
.pt-rows dd { margin: 0; color: var(--pt-ink); font-weight: 600; overflow-wrap: anywhere; }

/* ─────────── tracker: Signed · Preparing · Filed · Result ───────────
   <ol class="pt-tracker" data-step="2"><li class="done">…<li class="now" aria-current="step">…
   Each li = <span class="pt-dot"></span><span class="pt-lab">Label</span>. Labels stay on phones. */
.pt-tracker {
  list-style: none; margin: var(--sp-2) 0 var(--sp-3); padding: 0;
  display: grid; grid-template-columns: repeat(var(--pt-steps, 4), 1fr);
}
.pt-tracker li {
  position: relative; margin: 0; padding: 0;
  display: flex; flex-direction: column; align-items: center; gap: var(--sp-1); text-align: center;
}
.pt-tracker li + li::before {             /* the line from the previous dot to this one */
  content: ""; position: absolute; top: 11px; right: 50%; width: 100%; height: 2px;
  background: var(--pt-line);
}
.pt-tracker li.done + li::before { background: var(--pt-done); }
.pt-dot {
  position: relative; z-index: 1; box-sizing: border-box;
  width: 24px; height: 24px; border-radius: 50%;
  background: var(--pt-surface); border: 2px solid var(--pt-todo);
}
.pt-tracker li.done .pt-dot { background: var(--pt-done); border-color: var(--pt-done); }
.pt-tracker li.done .pt-dot::after {      /* the check */
  content: ""; position: absolute; left: 7px; top: 3px; width: 6px; height: 11px;
  border: solid var(--pt-surface); border-width: 0 2px 2px 0; transform: rotate(45deg);
}
.pt-tracker li.now .pt-dot {
  background: var(--pt-ink); border-color: var(--pt-ink);
  box-shadow: 0 0 0 3px var(--pt-surface), 0 0 0 5px var(--pt-ink);
}
.pt-lab { font-size: var(--fs-small); color: var(--pt-ink-2); line-height: 1.3; }
.pt-tracker li.now .pt-lab { color: var(--pt-ink); font-weight: 700; }
.pt-tracker li.done .pt-lab { color: var(--pt-ink); }

/* ─────────── status block ─────────── */

.pt-status { margin: 0 0 var(--sp-3); }
.pt-status-title,
:is([data-shell=flow],[data-shell=portal]) .pt-status-title { font-size: var(--fs-h3); font-weight: 700; line-height: 1.35; margin: 0 0 var(--sp-1); }
.pt-status p { margin: 0 0 var(--sp-2); color: var(--pt-ink-2); }

/* ─────────── action banner: only for a real customer action ─────────── */

.pt-banner {
  display: flex; flex-wrap: wrap; align-items: center; gap: var(--sp-2) var(--sp-3);
  background: var(--pt-act-soft); color: var(--pt-act-ink);
  border-left: 4px solid var(--pt-act); border-radius: var(--pt-radius);
  padding: var(--sp-3); margin: 0 0 var(--sp-3);
}
.pt-banner p { margin: 0; flex: 1 1 240px; font-weight: 600; }
.pt-banner .btn { flex: none; }

/* ─────────── notices: info (grey) · due (amber) · error (red) · done (green) ───────────
   Never red for normal waiting. The legacy .note / .note.hard / .note.good map onto these. */
.pt-notice,
:is([data-shell=flow],[data-shell=portal]) .note {
  display: block; padding: var(--sp-2) var(--sp-3); margin: 0 0 var(--sp-3);
  border: 0; border-radius: var(--pt-radius);
  background: var(--pt-inset); color: var(--pt-ink-2); font-size: var(--fs-small); line-height: 1.55;
}
.pt-notice.due,
:is([data-shell=flow],[data-shell=portal]) .note:not(.hard):not(.good):not(.info) { background: var(--pt-due-soft); color: var(--pt-due); }
.pt-notice.err,
:is([data-shell=flow],[data-shell=portal]) .note.hard { background: var(--pt-err-soft); color: var(--pt-err); }
.pt-notice.done,
:is([data-shell=flow],[data-shell=portal]) .note.good { background: var(--pt-done-soft); color: var(--pt-done); }
.pt-notice p { margin: 0; }
.pt-quiet { color: var(--pt-ink-3); font-size: var(--fs-small); margin: 0 0 var(--sp-3); }

/* ─────────── buttons ───────────
   Primary: copper fill, 48px, 10px corners, full width on phones. One per screen.
   Secondary (.btn.ghost or .btn.secondary): 1.5px ink outline. Disabled: 40% + aria-disabled. */
:is([data-shell=flow],[data-shell=portal]) .btn {
  display: inline-flex; align-items: center; justify-content: center; gap: var(--sp-2);
  min-height: 48px; padding: 0 var(--sp-4);
  font-family: var(--font); font-size: var(--fs-body); font-weight: 600; line-height: 1.25;
  color: var(--pt-act-fg); background: var(--pt-act);
  border: 1.5px solid var(--pt-act); border-radius: var(--pt-radius);
  box-shadow: none; text-decoration: none; text-align: center; white-space: normal; cursor: pointer;
  transition: background-color .15s ease, border-color .15s ease, color .15s ease;
}
:is([data-shell=flow],[data-shell=portal]) .btn:hover {
  background: var(--pt-act-hover); border-color: var(--pt-act-hover); color: var(--pt-act-fg); box-shadow: none;
}
:is([data-shell=flow],[data-shell=portal]) .btn.big { font-size: var(--fs-body); padding: 0 var(--sp-5); }
:is([data-shell=flow],[data-shell=portal]) .btn.wide { display: flex; width: 100%; }
/* app.css `.fcta .btn.big` (specificity 0,3,0) is the marketing one-button pattern: a pill, display:block.
   Inside the shells it is the same 10px rectangle as every other .btn, label centred (0,4,0 here). */
:is([data-shell=flow],[data-shell=portal]) .fcta .btn.big { display: flex; border-radius: var(--pt-radius); }
:is([data-shell=flow],[data-shell=portal]) :is(.btn.ghost, .btn.secondary) {
  background: transparent; color: var(--pt-ink); border-color: var(--pt-ink);
}
:is([data-shell=flow],[data-shell=portal]) :is(.btn.ghost, .btn.secondary):hover {
  background: var(--pt-inset); color: var(--pt-ink); border-color: var(--pt-ink);
}
:is([data-shell=flow],[data-shell=portal]) :is(.btn[disabled], .btn[aria-disabled="true"]) {
  opacity: .4; cursor: not-allowed;
}
:is([data-shell=flow],[data-shell=portal]) :is(.btn[disabled], .btn[aria-disabled="true"]):hover {
  background: var(--pt-act); border-color: var(--pt-act);
}
.pt-linkbtn {
  display: inline-flex; align-items: center; min-height: 44px; padding: 0;
  border: 0; background: none; cursor: pointer;
  color: var(--pt-link); font-family: var(--font); font-size: var(--fs-small); font-weight: 600;
  text-decoration: underline; text-underline-offset: 2px;
}
.pt-actions { display: flex; flex-wrap: wrap; align-items: center; gap: var(--sp-2) var(--sp-3); margin: var(--sp-4) 0 0; }
.pt-under { margin: var(--sp-2) 0 0; font-size: var(--fs-small); color: var(--pt-ink-2); }

/* ─────────── fields ─────────── */

:is([data-shell=flow],[data-shell=portal]) label {
  display: block; margin: 0 0 6px; font-size: var(--fs-small); font-weight: 600; color: var(--pt-ink);
}
:is([data-shell=flow],[data-shell=portal]) :is(input[type=text], input[type=email], input[type=tel],
  input[type=search], input[type=password], input[type=number], input[type=date], select) {
  width: 100%; min-height: 48px; padding: 0 14px;
  font-family: var(--font); font-size: var(--fs-body); line-height: 1.4;
  color: var(--pt-ink); background: var(--pt-surface);
  border: 1.5px solid var(--pt-field); border-radius: var(--pt-radius);
}
:is([data-shell=flow],[data-shell=portal]) textarea {
  width: 100%; padding: 10px 14px;
  font-family: var(--font); font-size: var(--fs-body); line-height: 1.5;
  color: var(--pt-ink); background: var(--pt-surface);
  border: 1.5px solid var(--pt-field); border-radius: var(--pt-radius);
}
/* file picker (tax bill on Quick questions, "Upload a letter" on Documents): a 48px box, the native
   button drawn as a secondary button; the whole box opens the picker. Scoped under main (0,2,2) so a
   page's own `.x input[type=file]` (0,2,1) cannot shrink the box or push the button onto the frame. */
:is([data-shell=flow],[data-shell=portal]) main input[type=file] {
  width: 100%; min-height: 48px; padding: 5px;
  font-family: var(--font); font-size: var(--fs-small); line-height: 1.4;
  color: var(--pt-ink-2); background: var(--pt-surface);
  border: 1.5px dashed var(--pt-field); border-radius: var(--pt-radius); cursor: pointer;
}
:is([data-shell=flow],[data-shell=portal]) main input[type=file]::file-selector-button {
  min-height: 36px; margin: 0 var(--sp-2) 0 0; padding: 0 var(--sp-3);
  font-family: var(--font); font-size: var(--fs-small); font-weight: 600;
  color: var(--pt-ink); background: var(--pt-surface);
  border: 1.5px solid var(--pt-ink); border-radius: var(--pt-radius); cursor: pointer;
  transition: background-color .15s ease;
}
:is([data-shell=flow],[data-shell=portal]) main input[type=file]:hover::file-selector-button { background: var(--pt-inset); }
:is([data-shell=flow],[data-shell=portal]) :is(input, select, textarea):focus {
  outline: 2px solid var(--pt-link); outline-offset: 1px; border-color: var(--pt-link);
}
:is([data-shell=flow],[data-shell=portal]) :is(input, select, textarea)[aria-invalid="true"],
:is([data-shell=flow],[data-shell=portal]) :is(input, select, textarea)[aria-invalid="true"]:focus { border-color: var(--pt-err); }
/* yes/no pills: the radio itself is invisible, so its error shows on the pill (aria-invalid on the radio
   or on the whole fieldset.pt-q) */
:is([data-shell=flow],[data-shell=portal]) .pt-q[aria-invalid="true"] .pt-pills span,
.pt-pills input[aria-invalid="true"] + span { border-color: var(--pt-err); }
.pt-field { margin: 0 0 var(--sp-3); }
.pt-hint  { margin: 6px 0 0; font-size: var(--fs-small); color: var(--pt-ink-3); }
.pt-field label + .pt-hint { margin: 0 0 6px; }
.pt-error { margin: 6px 0 0; font-size: var(--fs-small); font-weight: 600; color: var(--pt-err); }
.pt-errsum {
  margin: 0 0 var(--sp-3); padding: var(--sp-3); border-radius: var(--pt-radius);
  background: var(--pt-err-soft); color: var(--pt-err); font-size: var(--fs-small);
}
.pt-errsum:focus { outline: 2px solid var(--pt-err); outline-offset: 2px; }
.pt-errsum ul { margin: var(--sp-1) 0 0; }

/* password: rule visible before typing, Show toggle (44px), live "7/10" counter
   <div class="pt-field pt-pw"><label for=pw>…</label><p class="pt-hint" id=pw-rule>…</p>
     <div class="pt-pw-row"><input type=password id=pw …><button type=button class="pt-pw-show" aria-pressed=false>Show</button></div>
     <p class="pt-pw-count" id=pw-count aria-live=polite data-ok>7/10</p></div> */
.pt-pw-row { position: relative; }
:is([data-shell=flow],[data-shell=portal]) .pt-pw-row input { padding-right: 76px; }
.pt-pw-show {
  position: absolute; top: 2px; right: 2px; bottom: 2px; min-width: 64px; min-height: 44px;
  padding: 0 var(--sp-2); border: 0; border-radius: var(--pt-radius); background: transparent; cursor: pointer;
  color: var(--pt-link); font-family: var(--font); font-size: var(--fs-small); font-weight: 600;
}
.pt-pw-count { margin: 6px 0 0; font-size: var(--fs-small); color: var(--pt-ink-3); font-variant-numeric: tabular-nums; }
.pt-pw-count[data-ok] { color: var(--pt-done); }

/* yes / no pills over native radios
   <fieldset class="pt-q"><legend>…</legend><div class="pt-pills">
     <label><input type=radio name=x value=yes><span>Yes</span></label> … </div></fieldset> */
.pt-q { border: 0; margin: 0 0 var(--sp-4); padding: 0; min-width: 0; }
.pt-q legend { padding: 0; margin: 0 0 var(--sp-2); font-weight: 600; color: var(--pt-ink); }
.pt-pills { display: flex; flex-wrap: wrap; gap: var(--sp-2); }
.pt-pills label { position: relative; display: inline-flex; margin: 0; font-size: var(--fs-body); }
.pt-pills input {
  position: absolute; inset: 0; width: 100%; height: 100%; margin: 0; opacity: 0; cursor: pointer;
}
.pt-pills span {
  display: inline-flex; align-items: center; justify-content: center;
  min-height: 44px; min-width: 88px; padding: 0 var(--sp-4);
  border: 1.5px solid var(--pt-field); border-radius: 999px;
  background: var(--pt-surface); color: var(--pt-ink); font-weight: 600;
  transition: background-color .15s ease, color .15s ease, border-color .15s ease;
}
.pt-pills input:checked + span { background: var(--pt-ink); border-color: var(--pt-ink); color: var(--pt-surface); }
.pt-pills input:focus-visible + span { outline: 2px solid var(--pt-link); outline-offset: 2px; }
.pt-reveal { margin: var(--sp-2) 0 0; }

/* agree checkbox: the whole row is the label, 44px target */
.pt-check,
:is([data-shell=flow],[data-shell=portal]) label.pt-check {
  display: flex; align-items: flex-start; gap: var(--sp-2);
  min-height: 44px; padding: var(--sp-2) 0; margin: 0;
  font-size: var(--fs-body); font-weight: 400; color: var(--pt-ink); cursor: pointer;
}
.pt-check input { flex: none; width: 22px; height: 22px; margin: 2px 0 0; accent-color: var(--pt-ink); }

/* signature pad: full card width, 180px (160px on phones), baseline with ×, "Sign here",
   a status chip and Clear. Draw-only.
   <div class="pt-sig" data-state="wait|going|ok"><div class="pt-sig-head"><span>Signature must match: …</span>
     <span class="pt-chip" data-state="wait">Waiting for signature</span></div>
   <div class="pt-sig-pad"><canvas class="pt-sig-canvas"></canvas><span class="pt-sig-hint">Sign here</span>
     <span class="pt-sig-line"></span></div><button type=button class="pt-linkbtn">Clear</button></div> */
.pt-sig { margin: 0 0 var(--sp-3); }
.pt-sig-head {
  display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between;
  gap: var(--sp-1) var(--sp-2); margin: 0 0 var(--sp-2); font-weight: 600;
}
.pt-sig-pad {
  position: relative; height: 180px; touch-action: none;
  background: var(--pt-surface); border: 1.5px solid var(--pt-field); border-radius: var(--pt-radius);
}
.pt-sig-canvas { position: absolute; inset: 0; width: 100%; height: 100%; display: block; cursor: crosshair; touch-action: none; }
.pt-sig-hint {
  position: absolute; left: 0; right: 0; top: 38%; text-align: center; pointer-events: none;
  color: var(--pt-ink-3); font-size: var(--fs-body);
}
.pt-sig-line {
  position: absolute; left: var(--sp-5); right: var(--sp-3); bottom: 40px; pointer-events: none;
  border-top: 1.5px solid var(--pt-todo);
}
.pt-sig-line::before {
  content: "×"; position: absolute; left: calc(-1 * var(--sp-4)); bottom: 2px;
  color: var(--pt-ink-3); font-size: var(--fs-h3); line-height: 1;
}
.pt-sig[data-state="going"] .pt-sig-hint,
.pt-sig[data-state="ok"] .pt-sig-hint { display: none; }

/* status chip: wait (grey) · going (amber) · ok (green) */
.pt-chip {
  display: inline-flex; align-items: center; gap: 6px; padding: 2px 10px; border-radius: 999px;
  background: var(--pt-inset); color: var(--pt-ink-2); font-size: var(--fs-tiny); font-weight: 600;
  transition: background-color .15s ease, color .15s ease;
}
.pt-chip[data-state="going"] { background: var(--pt-due-soft); color: var(--pt-due); }
.pt-chip[data-state="ok"]    { background: var(--pt-done-soft); color: var(--pt-done); }

/* ─────────── folds ("More details", "What does this mean?", "Read the 4 documents") ─────────── */

.pt-fold { border-top: 1px solid var(--pt-line); margin: var(--sp-3) 0 0; }
.pt-fold > summary {
  display: flex; align-items: center; gap: var(--sp-2); min-height: 44px;
  cursor: pointer; list-style: none;
  color: var(--pt-link); font-size: var(--fs-small); font-weight: 600;
}
.pt-fold > summary::-webkit-details-marker { display: none; }
.pt-fold > summary::before {
  content: ""; flex: none; width: 7px; height: 7px; margin: 0 2px;
  border-right: 2px solid currentColor; border-bottom: 2px solid currentColor; transform: rotate(-45deg);
}
.pt-fold[open] > summary::before { transform: rotate(45deg); }
.pt-fold-body { padding: 0 0 var(--sp-3); }
.pt-fold-body > :last-child { margin-bottom: 0; }

/* ─────────── documents · history ─────────── */

.pt-docs, .pt-history { list-style: none; margin: 0; padding: 0; }
.pt-docs li {
  display: grid; grid-template-columns: auto 1fr auto auto; align-items: center;
  gap: var(--sp-1) var(--sp-3); padding: var(--sp-2) 0; margin: 0;
  border-bottom: 1px solid var(--pt-line);
}
.pt-docs li:last-child { border-bottom: 0; }
.pt-doc-name { font-weight: 600; min-width: 0; overflow-wrap: anywhere; }
.pt-form { font-weight: 400; color: var(--pt-ink-3); font-size: var(--fs-small); white-space: nowrap; }   /* "EXM-202" never splits at its hyphen */
.pt-doc-date { color: var(--pt-ink-3); font-size: var(--fs-small); font-variant-numeric: tabular-nums; white-space: nowrap; }
.pt-doc-dl { display: inline-flex; align-items: center; min-height: 44px; font-weight: 600; font-size: var(--fs-small); }
.pt-history li {
  display: grid; grid-template-columns: 7.5em 1fr; gap: var(--sp-3);
  padding: var(--sp-2) 0; margin: 0; border-bottom: 1px solid var(--pt-line);
}
.pt-history li:last-child { border-bottom: 0; }
.pt-history time { color: var(--pt-ink-3); font-size: var(--fs-small); font-variant-numeric: tabular-nums; }
.pt-ico { width: 20px; height: 20px; flex: none; fill: none; stroke: currentColor; stroke-width: 1.75;
          stroke-linecap: round; stroke-linejoin: round; color: var(--pt-ink-3); }

/* ─────────── result banner · fee block ─────────── */

.pt-result {
  background: var(--pt-done-soft); border-radius: var(--pt-radius-card);
  padding: var(--sp-4); margin: 0 0 var(--sp-3);
}
/* scoped so it also wins over the shell's main h2 / h3 rules when used on a heading (WP-2 does) */
.pt-result-title,
:is([data-shell=flow],[data-shell=portal]) .pt-result-title { margin: 0 0 var(--sp-2); font-size: var(--fs-h3); font-weight: 700; line-height: 1.35; color: var(--pt-ink); }
.pt-result-values { margin: 0 0 var(--sp-2); font-size: var(--fs-body); font-variant-numeric: tabular-nums; }
.pt-result-values .old { color: var(--c-roll); text-decoration: line-through; }
.pt-result-values .new { color: var(--c-market); font-weight: 700; }
.pt-result-amt {
  margin: 0; font-size: var(--fs-money); font-weight: 800; line-height: 1.05; letter-spacing: -.03em;
  color: var(--pt-done); font-family: var(--font-num); font-variant-numeric: tabular-nums;
}
.pt-result p:not([class]) { color: var(--pt-ink-2); margin: 0; }
.pt-fee { margin: 0 0 var(--sp-2); }
.pt-fee > div {
  display: flex; justify-content: space-between; align-items: baseline; gap: var(--sp-3);
  padding: var(--sp-1) 0;
}
.pt-fee dt { color: var(--pt-ink-2); }
.pt-fee dd { margin: 0; text-align: right; font-variant-numeric: tabular-nums; font-weight: 600; white-space: nowrap; }
.pt-fee > div.total { border-top: 1px solid var(--pt-line); margin-top: var(--sp-1); padding-top: var(--sp-2); }
.pt-fee > div.total :is(dt, dd) { color: var(--pt-ink); font-weight: 700; }
.pt-fee-note { margin: 0 0 var(--sp-3); font-size: var(--fs-small); color: var(--pt-ink-2); }

/* ─────────── done header · empty state · pinned summary ─────────── */

.pt-hero { display: flex; align-items: flex-start; gap: var(--sp-3); margin: 0 0 var(--sp-4); }
.pt-hero .pt-donemark {
  flex: none; position: relative; width: 40px; height: 40px; border-radius: 50%; background: var(--pt-done);
}
.pt-hero .pt-donemark::after {
  content: ""; position: absolute; left: 14px; top: 8px; width: 9px; height: 18px;
  border: solid var(--pt-surface); border-width: 0 3px 3px 0; transform: rotate(45deg);
}
.pt-hero h1,
:is([data-shell=flow],[data-shell=portal]) .pt-hero h1 { margin: 0; }
.pt-hero p { margin: var(--sp-1) 0 0; color: var(--pt-ink-2); }
.pt-empty { text-align: center; padding: var(--sp-5) var(--sp-3); }
.pt-empty p { margin: 0 0 var(--sp-3); color: var(--pt-ink-2); }
.pt-summary {
  display: flex; flex-wrap: wrap; gap: var(--sp-1) var(--sp-3); align-items: baseline;
  margin: 0 0 var(--sp-3); padding: var(--sp-2) var(--sp-3);
  background: var(--pt-surface); border-radius: var(--pt-radius);
  font-size: var(--fs-small); color: var(--pt-ink-2);
}
.pt-summary strong { color: var(--pt-ink); }
.pt-summary .save { color: var(--pt-done); font-weight: 700; }

/* ─────────── dark mode: borders instead of shadows ─────────── */

@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) :is([data-shell=flow],[data-shell=portal]) :is(.card, .pt-card) {
    box-shadow: none; border: 1px solid var(--pt-line);
  }
  :root:not([data-theme="light"]) .flowbar { border-bottom-color: var(--pt-line); }
}

/* ─────────── phones ─────────── */

@media (max-width: 640px) {
  :is([data-shell=flow],[data-shell=portal]) main { padding: var(--sp-3) var(--sp-3) var(--sp-5); }
  :is([data-shell=flow],[data-shell=portal]) .card,
  .pt-card { padding: var(--sp-3); }
  :is([data-shell=flow],[data-shell=portal]) .btn { width: 100%; margin-bottom: 0; }
  [data-shell=flow] .disclosure p.stat { line-height: 1.35; }
  :is([data-shell=flow],[data-shell=portal]) .disclosure-band { padding: var(--sp-2) var(--sp-2) 0; }
  :is([data-shell=flow],[data-shell=portal]) .disclosure-band .disclosure { padding: var(--sp-3); }
  /* the translation fold and the "California requires this notice on this page" line under the box: one
     compact block on phones - no rule between them, tighter spacing (WP-1: they cost 50-80px in es/ko).
     Sizes and the box itself do not change. */
  [data-shell=flow] .disclosure .gloss { margin-top: var(--sp-2); padding-top: 0; border-top: 0; }
  [data-shell=flow] .disclosure .gloss p { margin-top: var(--sp-1); }
  [data-shell=flow] .disclosure .cite { margin-top: var(--sp-1); }

  /* flow bar: one row. The wordmark hides (the otter stays); the step reads "2/3 · Details". */
  .bar-in { padding: 0 var(--sp-2); gap: var(--sp-1); }
  .flowbar .brand .wm { display: none; }
  .fb-step .long {                       /* still read by screen readers, just not shown */
    position: absolute; width: 1px; height: 1px; margin: -1px; padding: 0; overflow: hidden;
    clip: rect(0 0 0 0); clip-path: inset(50%); white-space: nowrap; border: 0;
  }
  .fb-step .short { display: inline; }

  /* portal bar: row 1 = otter · language · Create login / Sign out (right-aligned);
     row 2 = who ("Signed in as z***@…" / "Viewing case C26…, no login"), full width, never clipped;
     row 3 = tabs. The who line used to share row 1 and was squeezed to "Vi / e…" in case-number
     mode with a Sign out button, and cut to "Sesión iniciada como…" in Spanish at 360px. */
  .portalbar .bar-in { flex-wrap: wrap; row-gap: 0; }
  .portalbar .brand .wm { display: none; }
  .portalbar .langmenu { margin-left: auto; }
  .pt-barbtn,
  :is([data-shell=flow],[data-shell=portal]) .pt-barbtn { padding: 0 var(--sp-2); }
  .pt-tabs { order: 9; flex: 1 0 100%; margin: 0; border-top: 1px solid rgba(233, 237, 242, .12); }
  .pt-tabs a { flex: 1 1 0; justify-content: center; padding: 0 var(--sp-1); text-align: center; }
  .pt-who { order: 8; flex: 1 0 100%; margin: 0; padding: 0 0 var(--sp-2); }

  .pt-sig-pad { height: 160px; }
  /* document rows on phones: two lines, not three - icon | name over date | Download (44px, both rows) */
  .pt-docs li { grid-template-columns: auto 1fr auto; row-gap: 0; }
  .pt-docs .pt-ico { grid-row: 1 / span 2; align-self: start; margin-top: 2px; }
  .pt-docs .pt-doc-name { grid-column: 2; grid-row: 1; }
  .pt-docs .pt-doc-date { grid-column: 2; grid-row: 2; }
  .pt-docs .pt-doc-dl { grid-column: 3; grid-row: 1 / span 2; align-self: center; }
  .pt-history li { grid-template-columns: 1fr; gap: 0; }
  .pt-rows { grid-template-columns: 1fr; gap: 0; }
  .pt-rows dd { margin-bottom: var(--sp-2); }
}

@media (prefers-reduced-motion: reduce) {
  :is([data-shell=flow],[data-shell=portal]) * { transition: none !important; }
}

@media print {
  .flowbar, .portalbar { display: none; }
  :is([data-shell=flow],[data-shell=portal]) { background: #fff; }
}
