/* Forked from truenorth-onboarding-dev3-form.css for DEV6's chat attachment feature
   (2026-08-21). DEV3's resource file is untouched. Everything below this line is
   identical to DEV3's stylesheet except the "attachments" block near the composer
   rules - search for that heading. */
:root{
  /* ——— TrueNora tokens ——— */
  --ink:#1C2D4A;          /* brand navy — all text */
  --ink-soft:#5F6E82;     /* secondary */
  --ink-faint:#8D99A8;    /* tertiary / micro-labels */
  --paper:#F6F6F3;        /* app ground */
  --veil:#ECF0EC;         /* Nora surfaces, panels */
  --card:#FFFFFF;
  --teal:#2E9E8E;         /* brand accent — used sparingly */
  --teal-deep:#1E6C62;
  --line:rgba(28,45,74,.10);
  --line-soft:rgba(28,45,74,.06);

  --serif:"Newsreader",Georgia,"Times New Roman",serif;
  --sans:"Karla",-apple-system,BlinkMacSystemFont,"Segoe UI",sans-serif;

  --r-sm:8px; --r-md:14px; --r-lg:22px;
  --ease:cubic-bezier(.22,.61,.36,1);
}

*{box-sizing:border-box}
[hidden]{display:none!important}
html,body{margin:0;padding:0;height:100%}
body{
  background:var(--paper);overflow:hidden;
  color:var(--ink);
  font-family:var(--sans);
  -webkit-font-smoothing:antialiased;
  font-size:15px;
  line-height:1.5;
}
button{font-family:inherit;color:inherit;cursor:pointer;border:0;background:none}
input,textarea{font-family:inherit;font-size:inherit;color:inherit}
:focus-visible{outline:2px solid var(--teal);outline-offset:3px;border-radius:4px}

/* ——— shell: phone on desktop, full-bleed on mobile ——— */
.stage{min-height:100%;display:flex;align-items:center;justify-content:center;background:var(--paper)}
.app{
  position:relative;width:100%;max-width:100%;height:100vh;height:100dvh;
  background:var(--paper);color:var(--ink);overflow:hidden;display:flex;flex-direction:column;
  /* color set here (not just on body) so .app.incognito's scoped --ink override actually
     recomputes what descendants inherit - see the incognito block below for why. */
}
@media (min-width:760px){
  .stage{background:#E7E9E5;padding:34px 20px}
  .app{
    width:414px;height:min(860px,calc(100vh - 68px));
    border-radius:38px;box-shadow:0 1px 0 rgba(28,45,74,.10),0 30px 70px -24px rgba(28,45,74,.34);
    border:1px solid rgba(28,45,74,.10);
  }
  
}

/* ——— micro-label ——— */
.eyebrow{font-size:10.5px;font-weight:600;letter-spacing:.14em;text-transform:uppercase;color:var(--ink-faint)}

/* ——— screens ——— */
.screen{position:absolute;inset:0;display:none;flex-direction:column;background:var(--paper)}
.screen.on{display:flex}
.rise{animation:rise .55s var(--ease) both}
@keyframes rise{from{opacity:0;transform:translateY(7px)}to{opacity:1;transform:none}}

/* ——— top bar ——— */
.bar{
  flex:0 0 auto;display:flex;align-items:center;gap:10px;
  padding:max(14px,env(safe-area-inset-top)) 18px 12px;
}
.bar .mark{width:26px;height:26px;display:block}
.bar .name{font-family:var(--serif);font-size:17px;font-weight:500;letter-spacing:.01em}
.bar .spacer{flex:1}
/* Chat header role label (CSS CHANGE 2026-10-08, flagged per project convention) - "Person" /
   "Clinician" next to "Nora" (#chatRole, see updateChatRole() in the JS). A small pill in the
   same idiom as the onboarding page's .flow-indicator, sized down for the header; colours come
   from the tokens, so Incognito's theme applies to it too. On a phone the chat header is
   already full (five icons, the logo and the name), so there the label drops its pill and
   sits as a small line under "Nora" instead of beside it - measured: beside it, the icons
   shrink below 36px under ~450px wide and the bar overflows the card from 390px down. */
.bar .namewrap{display:flex;align-items:center;gap:8px}
.bar .rolelabel{flex:0 0 auto;padding:3px 9px;border:1px solid var(--line);border-radius:8px;background:var(--card);font-size:12px;font-weight:600;line-height:1.4;color:var(--ink-soft);letter-spacing:.01em;white-space:nowrap}
@media (max-width:480px){
  .bar .namewrap{flex-direction:column;align-items:flex-start;gap:1px}
  .bar .namewrap .name{line-height:1.15}
  .bar .rolelabel{padding:0;border:0;border-radius:0;background:none;font-size:11px;line-height:1.2}
}
.iconbtn{
  width:36px;height:36px;border-radius:50%;display:grid;place-items:center;
  color:var(--ink-soft);transition:background .2s var(--ease),color .2s var(--ease);
}
.iconbtn:hover{background:var(--veil);color:var(--ink)}
.iconbtn svg{width:19px;height:19px;fill:none;stroke:currentColor;stroke-width:1.6;stroke-linecap:round;stroke-linejoin:round}
/* CSS/design change, called out explicitly per project convention (see kaiProcess on the
   sibling MICROSVC_TRUENORTH_ONBOARDING_DEV_CHAT.xml). Added 2026-09-22 for #bookmarkToggle,
   which starts disabled (no session yet to bookmark on a fresh page load/"New chat" - see
   updateBookmarkUI() in the JS). No existing .iconbtn[disabled] rule was present before this,
   so a disabled icon button fell back to the plain hover/active look with no visual cue that
   it was inert; dimmed + no pointer/hover response fixes that for any future disabled iconbtn
   too, not just this one. */
.iconbtn[disabled]{opacity:.28;cursor:default;pointer-events:none}

/* ——— Incognito Mode toggle (top-right of the chat bar) ———
   CSS/design change, called out explicitly per project convention (see kaiProcess on the
   sibling MICROSVC_TRUENORTH_ONBOARDING_DEV_CHAT.xml). aria-pressed="true" is the on-state
   source of truth (set by toggleIncognito() in the JS) rather than a bespoke class, so it
   stays keyboard/screen-reader correct for free. The "on" look intentionally uses --teal
   (the existing brand accent) rather than a new colour, so it reads as "this app's own
   active-toggle style" instead of a foreign warning colour. The dark theme itself lives in
   .app.incognito below - redefining the SAME custom properties every other rule in this
   file already reads (--paper/--veil/--card/--ink/--ink-soft/--ink-faint/--line/--line-soft)
   is what makes one class flip the whole chat screen's colours with no other rule needing
   to know Incognito Mode exists. */
.iconbtn[aria-pressed="true"]{background:var(--veil);color:var(--teal)}
/* Bookmark toggle solid fill (#bookmarkToggle added 2026-09-22; historyBookmarkFilter joined
   2026-09-23 once its own icon switched from a star to the same ribbon path - see the HTML)
   - CSS/design change, called out explicitly per project convention. The generic rule above
   only recolours the circle background and the icon's stroke (currentColor) - still correct
   for Incognito's glasses icon, which isn't a closed shape meant to be filled solid. A
   bookmark ribbon reads far more clearly as "on" filled solid rather than merely recoloured
   (the same outline-vs-solid convention browsers and most apps use for a bookmark/favorite
   star), so this is scoped to the two ribbon-icon toggles specifically rather than widening
   the generic .iconbtn[aria-pressed="true"] rule to every toggle. Uses currentColor rather
   than repeating --teal, so it automatically tracks whatever colour the rule above already
   set - the two rules can never drift apart. */
#bookmarkToggle[aria-pressed="true"] svg,
#historyBookmarkFilter[aria-pressed="true"] svg{fill:currentColor}

.app.incognito{
  /* "Navy Grey" palette (option 4 of the second, lighter sample round) - replaces the
     earlier near-black "Charcoal" values. Also fixes a bug from that first pass: text
     was staying the light-mode navy because color was only ever set on body{}, and CSS
     inheritance copies an ancestor's already-computed value rather than re-evaluating
     var() per descendant - .app.incognito's --ink override never reached body's
     computed color. Adding color:var(--ink) on .app{} above (a descendant of body,
     ancestor of everything in the chat screen) is what makes this block's --ink
     override actually apply to text again. */
  --paper:#2A2F3A;        /* navy-grey ground, replacing the near-black --paper */
  --veil:#343A47;         /* Nora surfaces/panels on the navy-grey ground */
  --card:#2F3542;
  --ink:#E9ECF1;          /* body text - light on dark */
  --ink-soft:#AEB6C4;
  --ink-faint:#828B9C;
  --line:rgba(255,255,255,.10);
  --line-soft:rgba(255,255,255,.06);
}
/* Bug fix (Incognito send button unclear): .inputrow .send below fills itself with
   var(--ink) and draws a white (#fff) icon on top - fine in light mode, where --ink is
   the dark navy. But the palette swap above redefines --ink to a near-white #E9ECF1 for
   on-dark body text, so in Incognito the button became a near-white circle wearing a
   white icon on top of it - unclear, almost invisible. Locking the button to the brand
   teal here (a token .app.incognito does not touch) keeps it a filled, dark-enough
   circle with the white icon legible in both themes, without changing the light-mode
   look at all. */
.app.incognito .inputrow .send{background:var(--teal-deep)}

/* ——— scroll body ——— */
.flow{
  flex:1 1 auto;overflow-y:auto;padding:6px 22px 26px;
  -webkit-overflow-scrolling:touch;
}
.flow,.launch,.done,.sheet .card{
  overscroll-behavior:contain;
  scrollbar-width:thin;scrollbar-color:rgba(46,158,142,.42) transparent;
  scrollbar-gutter:stable;
}
.launch,.done{overflow-y:auto}
.flow::-webkit-scrollbar,.launch::-webkit-scrollbar,.done::-webkit-scrollbar,.sheet .card::-webkit-scrollbar{width:10px}
.flow::-webkit-scrollbar-track,.launch::-webkit-scrollbar-track,.done::-webkit-scrollbar-track,.sheet .card::-webkit-scrollbar-track{background:transparent}
.flow::-webkit-scrollbar-thumb,.launch::-webkit-scrollbar-thumb,.done::-webkit-scrollbar-thumb,.sheet .card::-webkit-scrollbar-thumb{
  min-height:44px;border:2px solid transparent;border-radius:10px;
  background:rgba(46,158,142,.42);background-clip:padding-box;
}
.flow::-webkit-scrollbar-thumb:hover,.launch::-webkit-scrollbar-thumb:hover,.done::-webkit-scrollbar-thumb:hover,.sheet .card::-webkit-scrollbar-thumb:hover{background:rgba(30,108,98,.68);background-clip:padding-box}

/* ——— launch ——— */
.launch{flex:1;display:flex;flex-direction:column;justify-content:center;padding:40px 34px calc(30px + env(safe-area-inset-bottom))}
.launch .bigmark{width:74px;height:74px;margin-bottom:30px}
.launch h1{
  font-family:var(--serif);font-weight:400;font-size:31px;line-height:1.24;
  letter-spacing:-.012em;margin:0 0 14px;max-width:15ch;
}
.launch h1 em{font-style:italic;color:var(--teal-deep)}
.launch p{color:var(--ink-soft);margin:0 0 auto;max-width:30ch;font-size:15px}
.launch .acts{margin-top:34px}
.btn{
  display:block;width:100%;padding:15px 18px;border-radius:var(--r-lg);
  background:var(--ink);color:#fff;font-weight:600;font-size:15px;text-align:center;
  transition:transform .2s var(--ease),opacity .2s var(--ease);
}
.btn:hover{opacity:.9}
.btn:active{transform:scale(.985)}
.btn.teal{background:var(--teal-deep)}
.btn.ghost{background:transparent;color:var(--ink);border:1px solid var(--line);font-weight:500}
.btn.small{padding:11px 16px;font-size:14px;border-radius:16px}
.linkline{margin-top:16px;text-align:center;font-size:13.5px;color:var(--ink-soft)}
.linkline button{text-decoration:underline;text-underline-offset:2px}

/* ——— consent (system voice — distinct from Nora) ——— */
.sysnote{
  background:var(--card);border:1px solid var(--line);border-radius:var(--r-md);
  padding:18px 18px 16px;margin:8px 0 20px;
}
.sysnote p{margin:10px 0 0;font-size:13.5px;line-height:1.62;color:var(--ink-soft)}
.sysnote a{color:var(--teal-deep)}

/* ——— conversation ——— */
.turn{margin:22px 0 0}
/* Nora's turn is one veil-background card (icon + text together), matching the
   "First Words" prototype's .nora block - not the plain, backgroundless text this
   used to be, and not the emoji-avatar/white-card skin that later overrode it. */
.turn.nora{
  display:grid;grid-template-columns:18px 1fr;gap:12px;align-items:start;
  background:var(--veil);border-radius:var(--r-md);padding:16px 18px;
}
.turn.nora .dot{width:16px;height:16px;margin-top:6px;opacity:.95}
.nora-body{font-family:var(--sans);font-size:14px;line-height:1.63;letter-spacing:.002em}
.nora-body p{margin:0 0 .78em}
.nora-body p:last-child{margin-bottom:0}
.nora-body strong{font-weight:700}
.nora-body ul{margin:0 0 .78em;padding-left:1.3em}
.nora-body li{margin:0 0 .35em}
.nora-body li:last-child{margin-bottom:0}
.nora-body code{font-family:ui-monospace,Consolas,monospace;font-size:.9em;
  background:var(--card);padding:.15em .4em;border-radius:5px}
.nora-body a{color:var(--teal-deep);text-decoration:underline;text-underline-offset:2px}
/* User's turn carries no icon (the 🙂 avatar this used to have is gone) - just the
   bubble, right-aligned, exactly as the prototype's .said. Stacked in a column
   (rather than a row) so that when attachments are present (.said-atts, appended
   before .said in myTurn() - see the JS), they sit above the message bubble
   instead of beside it; align-items keeps both right-aligned the way
   justify-content used to on its own, and gap replaces .said-atts's old
   margin-top since either child can now come first. */
.turn.me{display:flex;flex-direction:column;align-items:flex-end;gap:6px}
.turn.me .said{
  background:var(--card);border:1px solid var(--line);border-radius:18px 18px 6px 18px;
  padding:11px 15px;max-width:84%;font-size:14px;line-height:1.5;
}
.turn.sys{max-width:100%}

/* Utilities under a Nora turn - "Saved / Helpful / Not quite", always visible,
   plain text (no icons), matching the prototype exactly. They sit inside the same
   veil card as the message they belong to, so hover/on states use --card rather
   than --veil to stay visible against that background. */
.utils{display:flex;align-items:center;gap:4px;margin:12px 0 0 -6px}
.util{
  display:flex;align-items:center;padding:6px 10px;border-radius:14px;
  font-size:12px;font-weight:500;color:var(--ink-faint);transition:background .2s,color .2s;
}
.util:hover{background:var(--card);color:var(--ink)}
.util.on{color:var(--teal-deep)}
.util[data-act="save"].on::before{content:"◆ "}

.fbnote{margin:10px 0 0;background:var(--card);border:1px solid var(--line);border-radius:var(--r-md);padding:12px 13px}
.fbnote p{margin:0 0 8px;font-size:13px;color:var(--ink-soft)}
.fbnote textarea{
  width:100%;border:1px solid var(--line);border-radius:10px;background:var(--card);
  padding:9px 11px;font-size:13.5px;resize:none;height:60px;
}
.fbnote .row{display:flex;gap:8px;margin-top:8px}
.fbnote .row button{font-size:13px;font-weight:600;color:var(--teal-deep)}
.fbnote .row button.mute{color:var(--ink-faint);font-weight:500}

/* ——— SIGNATURE 1: the context band (numbers without dread) ——— */
.band{
  margin:16px 0;padding:15px 16px 13px;background:var(--veil);border-radius:var(--r-md);
  font-family:var(--sans);
}
.band .top{display:flex;justify-content:space-between;align-items:baseline;margin-bottom:12px}
.band .val{font-family:var(--serif);font-size:23px;font-weight:400;line-height:1}
.band .val span{font-size:12px;font-family:var(--sans);color:var(--ink-faint);margin-left:5px;letter-spacing:.02em}
.rail{position:relative;height:5px;border-radius:3px;background:rgba(28,45,74,.09);overflow:visible}
.rail .common{position:absolute;top:0;bottom:0;background:rgba(46,158,142,.26);border-radius:3px}
.rail .you{
  position:absolute;top:50%;width:11px;height:11px;border-radius:50%;
  background:var(--ink);border:2.5px solid var(--paper);transform:translate(-50%,-50%);
  transition:left 1.1s var(--ease);
}
.band .foot{display:flex;justify-content:space-between;margin-top:9px}
.band .foot span{font-size:11px;color:var(--ink-faint);letter-spacing:.02em}
.band .read{margin:11px 0 0;font-size:13.5px;line-height:1.55;color:var(--ink-soft)}

/* ——— SIGNATURE 2: the settle strip ——— */
.settle{
  display:flex;align-items:center;gap:10px;margin:15px 0;padding:12px 15px;
  background:var(--veil);border-left:2px solid var(--teal);border-radius:0 var(--r-md) var(--r-md) 0;
}
.settle svg{width:16px;height:16px;flex:0 0 auto;fill:none;stroke:var(--teal-deep);stroke-width:1.7;stroke-linecap:round;stroke-linejoin:round}
.settle span{font-family:var(--serif);font-style:italic;font-size:16px;color:var(--teal-deep)}

/* ——— thinking line (not bouncing dots) ——— */
.thinking{display:grid;grid-template-columns:22px 1fr;gap:12px;margin:22px 0 0}
.thinking .dot{width:16px;height:16px;margin-top:6px;opacity:.5}
.thinking .draw{height:2px;margin-top:12px;background:var(--line);border-radius:2px;overflow:hidden;max-width:180px}
.thinking .draw i{display:block;height:100%;width:34%;background:var(--teal);border-radius:2px;animation:draw 1.5s var(--ease) infinite}
@keyframes draw{0%{transform:translateX(-100%)}100%{transform:translateX(330%)}}

/* ——— composer ——— */
.composer{
  position:relative;
  flex:0 0 auto;padding:10px 16px calc(12px + env(safe-area-inset-bottom));
  background:linear-gradient(to top,var(--paper) 62%,rgba(246,246,243,0));
}
/* ——— "Ask Nora anything" suggestions rail (configData chat_starters) ———
   Horizontal scroll, baseline sits in normal flow just above the input row (not
   an overlay) - it opens on composer focus, filters as the user types, is capped
   at chat_starters_max_visible entries, and collapses to nothing (hidden) the
   moment a filter matches none. All matching entries live on one scrolling line;
   only three or four are visible before a fade hints there's more, and hovering
   within ~10% of either edge auto-scrolls the strip that way (see
   suggAutoScrollStep in the JS) - the "carousel" behaviour. */
.suggestions{
  position:relative;display:flex;gap:8px;overflow-x:auto;scrollbar-width:none;
  padding:2px 2px 10px;margin:0;
}
.suggestions::-webkit-scrollbar{display:none}
.suggestions::before,.suggestions::after{
  content:"";position:absolute;top:0;bottom:10px;width:28px;pointer-events:none;
  z-index:2;opacity:0;transition:opacity .2s;
}
.suggestions::before{left:0;background:linear-gradient(to right,var(--paper),rgba(246,246,243,0));}
.suggestions::after{right:0;background:linear-gradient(to left,var(--paper),rgba(246,246,243,0));}
.suggestions.fade-left::before{opacity:1}
.suggestions.fade-right::after{opacity:1}
.suggestion{
  display:flex;align-items:center;flex:0 0 auto;white-space:nowrap;
  padding:9px 15px;border-radius:999px;font-size:13.5px;color:var(--ink-soft);
  background:var(--card);border:1px solid var(--line);transition:background .15s,color .15s,border-color .15s;
}
.suggestion strong{font-weight:700;color:inherit}
.suggestion:hover,.suggestion:focus-visible,.suggestion.active{background:var(--veil);color:var(--ink);border-color:var(--line-soft)}
/* .inputrow is the visible bordered "message box" pill. It's a column now,
   not a single row: pending attachments (if any) render as a strip at its
   top, and .inputline - the actual attach-button/textarea/send-button row -
   sits below them, still inside the same border/background/radius. When
   there are no attachments, .pending-atts collapses to nothing (see
   :empty below) and .inputrow looks exactly as it did before this. */
.inputrow{display:flex;flex-direction:column;background:var(--card);border:1px solid var(--line);border-radius:24px;padding:6px 6px 6px 8px}
.inputline{display:flex;align-items:flex-end;gap:8px}
.inputrow textarea{
  flex:1;border:0;background:none;resize:none;height:36px;max-height:110px;
  padding:8px 4px;line-height:1.4;font-size:15px;
  /* Bug fix (messagebox scrollbar mismatch): unstyled, this textarea fell back to the
     OS/browser default scrollbar (silver on Windows/Chrome) once typed text grew past
     max-height - clashing with the teal scrollbar the rest of the app uses (see .flow
     etc. above). Same teal tint here, just a slimmer 6px vs. .flow's 10px since this
     box is much smaller. */
  scrollbar-width:thin;scrollbar-color:rgba(46,158,142,.42) transparent;
}
.inputrow textarea:focus{outline:none}
.inputrow textarea::-webkit-scrollbar{width:6px}
.inputrow textarea::-webkit-scrollbar-track{background:transparent}
.inputrow textarea::-webkit-scrollbar-thumb{background:rgba(46,158,142,.42);background-clip:padding-box;border-radius:10px}
.inputrow textarea::-webkit-scrollbar-thumb:hover{background:rgba(30,108,98,.68);background-clip:padding-box}
.inputrow .send{
  width:36px;height:36px;border-radius:50%;background:var(--ink);color:#fff;display:grid;place-items:center;
  transition:opacity .2s;flex:0 0 auto;
}
.inputrow .send[disabled]{opacity:.28;cursor:default}
.inputrow .send svg{width:17px;height:17px;fill:none;stroke:currentColor;stroke-width:1.9;stroke-linecap:round;stroke-linejoin:round}
.inputrow .attach{width:34px;height:34px;border-radius:50%;color:var(--ink-faint);display:grid;place-items:center;flex:0 0 auto}
.inputrow .attach:hover{background:var(--veil);color:var(--ink)}
.inputrow .attach svg{width:18px;height:18px;fill:none;stroke:currentColor;stroke-width:1.7;stroke-linecap:round}

/* ——— attachments (DEV6 only - + button and drag-and-drop, added on top of DEV3's composer) ———
   Lives inside .inputrow now (the bordered message box), as the top strip of
   that column - see the HTML and the .inputrow comment above. Each pending
   attachment is a fixed-size square: an actual image thumbnail for image
   files, a small extension chip ("PDF"/"TXT") for anything else. The remove
   control is an absolutely-positioned badge overlapping the top-right corner
   of that square, so .pending-att needs position:relative and the row needs
   enough top/right padding that the badge isn't clipped by the row's own
   horizontal scroll (overflow-x:auto forces overflow-y to behave like auto
   too, per the CSS overflow spec, so anything poking outside the row's
   padding box would otherwise be cut off). The right/top padding is on top
   clearance has to come from .pending-atts's own padding regardless of
   nesting - .inputrow doesn't set overflow, so its padding plays no part in
   what .pending-atts's own overflow-x:auto clips. */
.pending-atts{display:flex;gap:10px;overflow-x:auto;padding:8px 10px 8px 0;scrollbar-width:none}
.pending-atts:empty{padding:0}
.pending-atts::-webkit-scrollbar{display:none}
/* A hairline separates the attachment strip from the text line below it, but
   only when there's actually something to separate. */
.pending-atts:not(:empty)+.inputline{border-top:1px solid var(--line-soft);padding-top:6px;margin-top:2px}
.pending-att{
  position:relative;flex:0 0 auto;width:52px;height:52px;border-radius:12px;
  background:var(--card);border:1px solid var(--line);
}
.pending-att .thumb{width:100%;height:100%;border-radius:11px;object-fit:cover;display:block}
.pending-att .filechip{
  width:100%;height:100%;border-radius:11px;display:flex;flex-direction:column;
  align-items:center;justify-content:center;gap:3px;padding:4px;overflow:hidden;
}
.pending-att .fext{font-size:9.5px;font-weight:700;letter-spacing:.03em;color:var(--teal-deep)}
.pending-att .fname{
  font-size:8.5px;line-height:1.2;color:var(--ink-faint);max-width:100%;
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap;
}
.pending-att .removeatt{
  position:absolute;top:-6px;right:-6px;width:18px;height:18px;padding:0;border-radius:50%;
  display:grid;place-items:center;background:var(--card);border:1px solid var(--line);
  color:var(--ink-soft);box-shadow:0 1px 3px rgba(28,45,74,.18);
}
.pending-att .removeatt:hover{background:var(--ink);color:#fff;border-color:var(--ink)}
.pending-att .removeatt svg{width:10px;height:10px;fill:none;stroke:currentColor;stroke-width:2.2;stroke-linecap:round}

.said-atts{display:flex;flex-wrap:wrap;gap:6px;justify-content:flex-end}
.att-tag{
  font-size:11.5px;color:var(--ink-soft);background:var(--veil);border-radius:10px;
  padding:4px 9px;max-width:220px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;
}
/* An image attachment gets a small clickable thumbnail instead of a name-only
   tag, once the message has actually gone out (see myTurn() in the JS) - a
   real <button> wrapping the <img>, not the <img> alone, so it's reachable
   and operable by keyboard like every other data-act control in this file.
   Non-image attachments (PDF/text) keep the plain .att-tag above - there's
   nothing to enlarge for those. */
.att-thumb-btn{flex:0 0 auto;padding:0;border-radius:12px;line-height:0}
.att-thumb{
  width:52px;height:52px;border-radius:12px;object-fit:cover;display:block;
  border:1px solid var(--line);transition:opacity .15s;
}
.att-thumb-btn:hover .att-thumb,.att-thumb-btn:focus-visible .att-thumb{opacity:.82}

/* ——— attachment viewer modal (DEV6 only - enlarges a tapped sent photo) ———
   Same phone-shell-relative overlay pattern as .panel/.sheet below:
   position:absolute;inset:0 inside #app, which is what clips it to #app's own
   rounded corners via #app's overflow:hidden - never position:fixed, so it
   can never break out of the phone frame on desktop. z-index 35 sits above
   .sheet (30) and .panel (20) as a precaution, though today nothing opens the
   image viewer from inside either of those. */
.imgmodal{
  position:absolute;inset:0;z-index:35;display:none;
  align-items:center;justify-content:center;padding:20px;
  background:rgba(15,23,38,.88);
}
.imgmodal.on{display:flex}
.imgmodal-img{
  max-width:100%;max-height:100%;border-radius:var(--r-md);
  box-shadow:0 20px 60px -20px rgba(0,0,0,.6);object-fit:contain;
}
.imgmodal-close{
  position:absolute;top:max(16px,env(safe-area-inset-top));right:16px;
  width:36px;height:36px;border-radius:50%;display:grid;place-items:center;
  background:rgba(255,255,255,.14);color:#fff;border:1px solid rgba(255,255,255,.3);
  transition:background .2s;
}
.imgmodal-close:hover{background:rgba(255,255,255,.26)}
.imgmodal-close svg{width:16px;height:16px;fill:none;stroke:currentColor;stroke-width:2.2;stroke-linecap:round}

/* ——— remove-concern confirmation (added 2026-09-22) ———
   Shown before an "On your mind" concern chip's "x" actually removes anything - see
   askRemoveConcern()/closeConfirmRemove()/doRemoveConcern() in the JS. Same phone-shell-
   relative overlay convention as .sheet/.imgmodal (position:absolute;inset:0 inside #app,
   clipped to #app's own rounded corners, never position:fixed). Unlike .imgmodal it is
   deliberately NOT dismissed by a tap on the backdrop - only the two buttons in
   .confirmacts, or Escape, close it (see the keydown handler in the JS) - closer to
   .sheet's "explicit action only" behaviour, since this gates a DB write rather than just a
   view. z-index 36 sits above .imgmodal (35) so a stray leftover imgmodal.on state can never
   hide it, even though nothing opens both today. */
.confirmmodal{
  position:absolute;inset:0;z-index:36;display:none;
  align-items:center;justify-content:center;padding:24px;
  background:rgba(15,23,38,.5);
}
.confirmmodal.on{display:flex}
.confirmcard{
  background:var(--card);border-radius:var(--r-lg);padding:22px 20px;
  max-width:320px;width:100%;box-shadow:0 20px 60px -20px rgba(0,0,0,.5);
  animation:up .3s var(--ease) both;
}
.confirmcard h3{margin:0 0 8px;font-family:var(--serif);font-weight:400;font-size:19px;line-height:1.3}
.confirmcard p{margin:0 0 18px;font-size:13.5px;color:var(--ink-soft);line-height:1.5}
.confirmacts{display:flex;gap:10px}
.confirmacts .btn{width:auto;flex:1;padding:12px 14px;font-size:13.5px}

/* full-screen drop target: #s-chat is already position:absolute, so this overlay just
   needs to sit above the flow and composer while a file is dragged over the screen */
.dropveil{
  position:absolute;inset:0;display:none;align-items:center;justify-content:center;
  font-size:14px;color:var(--teal-deep);background:rgba(246,246,243,.9);
  border:2px dashed var(--teal);border-radius:16px;margin:8px;pointer-events:none;z-index:5;
}
#s-chat.dragover .dropveil{display:flex}

/* ——— onboarding answer affordances ——— */
.answerbox{margin:16px 0 0 34px}
.answerbox .field{
  display:flex;align-items:center;gap:8px;background:var(--card);border:1px solid var(--line);
  border-radius:22px;padding:5px 6px 5px 15px;
}
.answerbox input{flex:1;border:0;background:none;padding:10px 0;font-size:15px}
.answerbox input:focus{outline:none}
.answerbox .hint{margin:9px 0 0 4px;font-size:12.5px;color:var(--ink-faint)}
.optgrid{display:flex;flex-wrap:wrap;gap:8px}
.opt{
  padding:10px 14px;border-radius:16px;background:var(--card);border:1px solid var(--line);
  font-size:14px;color:var(--ink);transition:all .2s var(--ease);text-align:left;
}
.opt:hover{border-color:rgba(46,158,142,.5)}
.opt.sel{background:rgba(46,158,142,.10);border-color:var(--teal);color:var(--teal-deep);font-weight:500}
/* 2026-10-15: a chip that cannot be picked right now - an age range ruled out by the birth year,
   or a life stage that contradicts one already picked (the JS sets the disabled attribute).
   Dimmed, no hover, not-allowed cursor, the same treatment .formwrap .btn[disabled] gets. A
   picked chip is never disabled; the one the birth year locks stays selected-looking. */
.opt[disabled]{opacity:.38;cursor:not-allowed}
.opt[disabled]:hover{border-color:var(--line)}
.optlist{display:flex;flex-direction:column;gap:7px}
.optlist .opt{width:100%}
.doneline{display:flex;gap:10px;align-items:center;margin-top:14px}
.doneline .btn{width:auto;padding:12px 22px;font-size:14px}
.doneline .skip{font-size:13.5px;color:var(--ink-faint);text-decoration:underline;text-underline-offset:2px}

/* ——— panels (saved / profile) ——— */
.panel{
  position:absolute;inset:0;background:var(--paper);display:flex;flex-direction:column;
  transform:translateY(100%);transition:transform .42s var(--ease);z-index:20;
}
.panel.on{transform:none}
.panel .phead{
  display:flex;align-items:center;gap:12px;padding:max(16px,env(safe-area-inset-top)) 18px 14px;
}
.panel .phead h2{font-family:var(--serif);font-weight:500;font-size:19px;margin:0;flex:1}
.psub{padding:0 22px;color:var(--ink-soft);font-size:13.5px;margin:0 0 18px;max-width:34ch}

/* ——— HISTORY drawer (left-edge, chat stays visible behind it) ———
   Per explicit request: unlike SAVED/PROFILE above (full-screen .panel, slides up
   from the bottom, fully replaces the chat), History slides in from the LEFT and
   only partially covers the screen, dimmed-but-visible chat behind it via
   .drawer-backdrop - the usual off-canvas-drawer pattern. Same phone-shell-relative
   overlay convention as .panel/.sheet/.imgmodal (position:absolute;inset:0 inside
   #app, clipped to #app's own rounded corners by its overflow:hidden - never
   position:fixed). .panel.drawer only overrides the axis/width/shadow; it still
   inherits .panel's z-index (20), background, phead/psub/flow layout and the
   .panel.on{transform:none} open state (re-stated at .panel.drawer.on below purely
   to win the specificity tie against .panel.on - both are (0,2,0) selectors, so
   without this the source-order-later .panel.drawer{transform:translateX(-100%)}
   would otherwise keep winning even once "on" is applied). */
.panel.drawer{
  inset:0 auto 0 0;width:86%;max-width:336px;
  transform:translateX(-100%);
  box-shadow:6px 0 28px -6px rgba(28,45,74,.28);
}
.panel.drawer.on{transform:none}
/* Sibling, not a child, so the drawer's own translateX doesn't drag it along.
   z-index 19 - one below .panel's 20 - puts it above the chat screen underneath
   but below the drawer itself. Opacity/pointer-events only flip on while
   #p-history itself carries .on, so it never needs its own JS open/close call:
   openPanel()/closePanel() already toggle that class for every other panel. */
.drawer-backdrop{
  position:absolute;inset:0;z-index:19;
  background:rgba(15,23,38,.4);
  opacity:0;pointer-events:none;
  transition:opacity .42s var(--ease);
}
#p-history.on ~ .drawer-backdrop{opacity:1;pointer-events:auto}

.savedcard{
  background:var(--card);border:1px solid var(--line-soft);border-radius:var(--r-md);
  padding:16px 17px;margin:0 0 12px;
}
.savedcard .about{display:flex;justify-content:space-between;align-items:baseline;margin-bottom:9px;gap:10px}
.savedcard blockquote{
  margin:0;font-family:var(--serif);font-size:16.5px;line-height:1.55;
}
.savedcard .when{font-size:11px;color:var(--ink-faint);white-space:nowrap;letter-spacing:.03em}
.savedcard .open{margin-top:11px;font-size:12.5px;font-weight:600;color:var(--teal-deep)}
.empty{padding:30px 4px;text-align:left}
.empty p{font-family:var(--serif);font-size:17px;line-height:1.55;margin:0 0 8px;max-width:26ch}
.empty small{color:var(--ink-soft);font-size:13.5px;line-height:1.6;display:block;max-width:32ch}

/* ——— HISTORY panel — list rows, not cards, per user request ———
   session_title + date on a single line (message count removed, also per user
   request), plus a ⋮ "more" button opening a small dropdown whose only item is
   "Delete". That item still only archives the session (is_archived/archived_at) -
   never a hard delete - matching the DESIGN CHOICE already made and logged in this
   microservice's own kaiProcess when /sessions/archive was built. Only the visible
   wording changed here (and to a menu instead of an inline button); the underlying
   call in archiveSession() is unchanged. */
/* Row height/font sized down to roughly half the original per user request:
   14px top/bottom padding -> 6px, and an explicit line-height:1.2 on the text
   (rather than inheriting body's 1.5) so the smaller font actually shrinks the
   row instead of leaving tall inherited line-boxes around it. */
.histrow{
  display:flex;align-items:center;gap:8px;position:relative;z-index:0;
  padding:6px 4px;margin:0 -4px;border-radius:8px;
  border-bottom:1px solid var(--line-soft);
  transition:background .15s var(--ease);
  cursor:pointer;
}
.histrow:hover{background:var(--veil)}
.histrow:last-child{border-bottom:0}
/* paintHistory() re-renders every row's innerHTML (not just the toggled one) on
   every ⋮ open/close, which restarts the .rise entrance animation on ALL rows -
   and a running transform/opacity animation makes a row its own stacking context
   for as long as it's mid-animation. Without this, an open dropdown (position:
   absolute, z-index:5, but scoped to its OWN row's stacking context) can end up
   painted behind a later row that happens to be mid-animation at that instant,
   since later DOM siblings win ties within the shared .historyflow context. Explicit
   z-index here (2 vs the base 0 above) settles that ordering regardless of any
   sibling's animation state, so the open menu always renders above the list. */
.histrow.menu-open{z-index:2}
/* Rename mode (added 2026-09-22): the row is a text field, not a button, while this class
   is on - no pointer cursor, no hover veil, matching the base .histrow rule's own
   pointer/hover only making sense for the clickable (non-editing) state. */
.histrow.renaming{cursor:default}
.histrow.renaming:hover{background:transparent}
.histmain{flex:1 1 auto;min-width:0;display:flex;align-items:baseline;gap:7px;line-height:1.2}
/* CSS/design change, called out explicitly per project convention (see kaiProcess on the
   sibling MICROSVC_TRUENORTH_ONBOARDING_DEV_CHAT.xml). Added 2026-09-22: the small filled
   star paintHistory() renders inside .histmain (before .histtitle) when a row's
   is_bookmarked is "true". .histmain uses align-items:baseline (right, for the title text
   vs .when's timestamp), which has no baseline of its own to align an SVG to - explicit
   size + align-self:center keeps the star vertically centred against the title text instead
   of collapsing to the SVG's own bottom edge. fill:var(--teal) matches the same brand accent
   .iconbtn[aria-pressed="true"] already uses for every other "on" state in this file. */
.histbookmark{width:12px;height:12px;flex:0 0 auto;align-self:center;fill:var(--teal);stroke:none}
.histtitle{
  flex:1 1 auto;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;
  font-family:"Segoe UI",sans-serif;font-size:12px;font-weight:500;color:var(--ink);
}
/* Rename input - same font/size/weight/colour as .histtitle above so swapping one for
   the other doesn't shift the row's layout or look like a different control family. */
.histtitle-edit{
  flex:1 1 auto;min-width:0;width:100%;
  font-family:"Segoe UI",sans-serif;font-size:12px;font-weight:500;color:var(--ink);
  background:var(--paper);border:1px solid var(--line);border-radius:5px;
  padding:2px 6px;line-height:1.3;
}
.histtitle-edit:focus{outline:none;border-color:var(--teal)}
.histrow .when{flex:0 0 auto;font-size:9.5px;color:var(--ink-faint);white-space:nowrap;letter-spacing:.03em}

/* ⋮ "more" button + its dropdown. position:relative on the wrap anchors the
   absolutely positioned menu; it stays right-aligned under the button and never
   wider than the row, so .flow's own overflow (forced to overflow-x:auto by the
   spec once overflow-y:auto is set - see the .pending-atts comment above) never
   clips it. Shrunk to match the smaller row (22px, was 30px) - the base
   .iconbtn svg rule is 18px, so this needs its own svg override too or the icon
   would overflow its own button. */
/* align-self:stretch (overriding .histrow's own align-items:center just for this
   child) + its own internal centering makes the wrap's box span the FULL row
   height rather than just the button's small 22px box - otherwise, now that rows
   are short, "top:100%" below (measured from the wrap's own bottom) lands only a
   few px under the button instead of under the row, and the dropdown ends up
   overlapping this row's own text instead of sitting cleanly beneath it. */
.histmenu-wrap{position:relative;flex:0 0 auto;align-self:stretch;display:flex;align-items:center}
.histmore{width:22px;height:22px}
.histmore svg{width:13px;height:13px;fill:currentColor;stroke:none}
.histmenu{
  position:absolute;top:calc(100% + 4px);right:0;min-width:56px;z-index:5;
  background:var(--card);border:1px solid var(--line);border-radius:var(--r-sm);
  box-shadow:0 10px 24px -10px rgba(28,45,74,.3);padding:3px;display:none;
}
.histmenu.on{display:block}
/* Base style is now neutral (was hardcoded red when Delete was this menu's only item) -
   Rename, added 2026-09-22, is not a destructive action and uses this default; Delete
   opts back into the original red via .danger below, which is the only item that should
   ever carry it (flag any future addition to this menu to the same standard the project
   already applies to CSS changes). */
.histmenu-item{
  display:block;width:100%;text-align:left;padding:3.5px 4.5px;border-radius:4px;
  font-size:12px;font-weight:500;color:var(--ink);
}
.histmenu-item:hover{background:var(--veil)}
.histmenu-item.danger{color:#B3261E}
.histmenu-item.danger:hover{background:rgba(179,38,30,.08)}
/* Save (✓) / Cancel (✕) icon buttons that replace the ⋮ button while a row is being
   renamed - sized like .histmore (22px) but keep the base .iconbtn svg's stroke
   rendering (fill:none;stroke:currentColor) rather than .histmore's own fill-based
   override, since these are open check/X paths, not the kebab's filled dots. */
.histrename-save,.histrename-cancel{width:22px;height:22px}
.histrename-save svg,.histrename-cancel svg{width:13px;height:13px}
.histrename-save:hover{color:var(--teal)}

/* Belt-and-braces for "make sure the list scrolls as it grows": .flow (shared with
   savedflow/profileflow/chatflow) already sets flex:1 1 auto + overflow-y:auto,
   which is enough in every other panel here - but a flex item's default
   min-height:auto can let it grow past its container instead of scrolling
   ("flexbug #1"). This pins it down for #historyflow specifically, without
   touching the shared .flow rule every other panel still relies on. */
/* .flow's shared 22px left/right padding (meant for the taller Saved/Profile
   cards) reads as excess gutter now that rows are compact - cut to 10px here
   only, so the list sits closer to the panel edge without touching .flow itself. */
#historyflow{min-height:0;padding-left:10px;padding-right:10px}

.pgroup{margin:0 0 26px}
.pgroup h3{margin:0 0 12px;font-size:10.5px;font-weight:600;letter-spacing:.14em;text-transform:uppercase;color:var(--ink-faint)}
.krow{
  display:flex;justify-content:space-between;align-items:center;gap:14px;
  padding:13px 0;border-bottom:1px solid var(--line-soft);
}
.krow:last-child{border-bottom:0}
.krow .k{font-size:13.5px;color:var(--ink-soft)}
.krow .v{font-size:14.5px;text-align:right}
.krow .v em{font-style:normal;color:var(--ink-faint)}
/* "Starting context" pills in the "What Nora knows" panel (.krow .v holding renderStartingContext()'s
   output). Deliberately the same rounded/teal "selected" look these topics had as round buttons
   during registration's details-mode intake step (see .details-mode .chks .chk.on above) - these
   are the topics that WERE selected, just shown read-only here. Plain <span>s, not <button>s: no
   data-act, no click handler, cursor left at its default (not pointer), so they read as static
   information rather than a control. */
.startpills{display:flex;flex-wrap:wrap;gap:6px;justify-content:flex-end}
.startpill{
  display:inline-flex;align-items:center;padding:9px 13px;border-radius:18px;
  font-size:13px;line-height:1.3;font-weight:500;
  background:rgba(46,158,142,.09);border:1px solid var(--teal-deep);color:var(--teal-deep);
}
/* The "+N more"/"Show less" toggle at the end of the "On your mind" row (see
   renderOnYourMind() - redesigned 2026-09-22 to render concern chips as INTERACTIVE .tag
   pills, the same markup "Just exploring" always used, not the read-only .startpill look
   this used to reuse) - deliberately NOT a .tag itself
   (those are static and non-clickable by design; this one has to invite a click), so it gets
   its own dashed, muted style plus a pointer cursor to read as the row's one interactive
   element. */
.morechip{
  display:inline-flex;align-items:center;padding:9px 13px;border-radius:18px;
  font-size:13px;line-height:1.3;font-weight:500;cursor:pointer;
  background:var(--veil);border:1px dashed var(--line);color:var(--ink-soft);
  transition:border-color .18s,color .18s;
}
.morechip:hover{border-color:rgba(46,158,142,.5);color:var(--ink)}
.tags{display:flex;flex-wrap:wrap;gap:7px}
.tag{
  display:flex;align-items:center;gap:7px;padding:7px 11px;border-radius:14px;
  background:var(--veil);font-size:13px;
}
.tag button{color:var(--ink-faint);display:grid;place-items:center}
.tag svg{width:12px;height:12px;stroke:currentColor;stroke-width:2;fill:none;stroke-linecap:round}
.noticed{background:var(--veil);border-radius:var(--r-md);padding:15px 16px}
.noticed p{margin:0;font-family:var(--serif);font-size:16px;line-height:1.58}
.noticed small{display:block;margin-top:10px;font-size:12px;color:var(--ink-faint);line-height:1.5}
.promises{display:flex;flex-direction:column;gap:11px}
.promise{display:flex;gap:11px;font-size:13.5px;color:var(--ink-soft);line-height:1.5}
.promise svg{width:15px;height:15px;flex:0 0 auto;margin-top:3px;fill:none;stroke:var(--teal);stroke-width:1.8;stroke-linecap:round;stroke-linejoin:round}

/* ——— trial sheet ——— */
.sheet{
  position:absolute;inset:0;z-index:30;display:none;
  background:rgba(28,45,74,.28);backdrop-filter:blur(2px);
}
.sheet.on{display:block}
.sheet .card{
  position:absolute;left:0;right:0;bottom:0;background:var(--paper);
  border-radius:26px 26px 0 0;padding:26px 22px calc(22px + env(safe-area-inset-bottom));
  max-height:94%;overflow-y:auto;animation:up .42s var(--ease) both;
}
@keyframes up{from{transform:translateY(14px);opacity:.6}to{transform:none;opacity:1}}
.sheet h2{font-family:var(--serif);font-weight:400;font-size:24px;line-height:1.28;margin:0 0 10px;max-width:22ch}
.sheet .lede{color:var(--ink-soft);font-size:14px;margin:0 0 20px;max-width:36ch}
.plan{
  display:flex;justify-content:space-between;align-items:flex-start;gap:12px;
  background:var(--card);border:1px solid var(--line);border-radius:var(--r-md);
  padding:15px 16px;margin-bottom:10px;width:100%;text-align:left;transition:border-color .2s;
}
.plan:hover{border-color:rgba(46,158,142,.5)}
.plan.sel{border-color:var(--teal);background:rgba(46,158,142,.06)}
.plan .pname{font-weight:600;font-size:14.5px;display:flex;align-items:center;gap:8px}
.plan .pdesc{font-size:12.5px;color:var(--ink-soft);margin-top:4px;line-height:1.45}
.plan .price{font-family:var(--serif);font-size:19px;white-space:nowrap}
.plan .price small{font-family:var(--sans);font-size:11px;color:var(--ink-faint);display:block;text-align:right;margin-top:2px}
/* ——— Onboarding "Your plan." step (#s-plan) - Pro / Pro+ cards ———
   Content, layout, fonts and sizes ported from the reference prototype's own
   "6. Plan" screen (title, price, short bullet list stacked inside each card),
   replacing DEV6's earlier pname/pdesc/price row layout above. That row layout
   stays exactly as it was for the unrelated post-trial "Day 14" upsell sheet
   (#p-trial), which also uses .plan - these overrides are scoped to #s-plan so
   that sheet is untouched. The cards stay real <button data-act="pickPlan">
   elements (the prototype's are inert <div>s) so picking one still enables
   Start My Trial via the existing pickPlan()/startTrial() JS, unchanged here -
   that's the one behaviour kept on top of the prototype's layout. A plain "•"
   prefix stands in for the prototype's <ul><li> bullets, since <ul>/<li> aren't
   valid content inside a <button> (this file keeps buttons to phrasing content
   throughout, e.g. the channel/role .choice buttons). */
#s-plan .plan{display:block;background:var(--card);padding:18px 20px;margin-bottom:0;transition:border-color .2s,box-shadow .2s,opacity .2s}
/* Once either card is picked, dim whichever one is NOT selected so the chosen card
   reads as the clear focus. :has() lets this react to a sibling's state in pure CSS -
   no JS class-toggling needed. Before anything is picked, no card has .sel yet, so
   :has(.plan.sel) matches nothing and both cards stay at full opacity as today. */
#s-plan .two:has(.plan.sel) .plan:not(.sel){opacity:.6}
/* Pro+ gets the reference prototype's own veil/teal-border treatment as its permanent
   look (matching the prototype's .plan.open example - var(--veil) + a teal-tinted
   border), so it reads as the premium tier sitting next to Pro's plain white card.
   Unlike an earlier version of this rule, it is NOT scoped with :not(.sel): each
   card's own background stays fixed whether or not it's selected - see .sel below,
   which only ever changes the border and adds the glow, never the fill color. */
#s-plan .plan[data-arg="pro_plus"]{background:var(--veil);border-color:rgba(46,158,142,.35)}
#s-plan .plan[data-arg="pro_plus"]:hover{border-color:rgba(46,158,142,.55)}
/* Selecting a card only adds a border + glow on top of whatever background it already
   had (white for Pro, veil for Pro+) - it must never change that card's fill color. */
#s-plan .plan.sel{border-color:var(--teal-deep);box-shadow:0 0 0 3px rgba(46,158,142,.16),0 6px 20px -4px rgba(46,158,142,.35)}
#s-plan .plan .pt{display:block;font-family:var(--serif);font-size:18px;margin:0 0 3px}
#s-plan .plan .pp{display:block;font-size:22px;font-family:var(--serif);color:var(--teal-deep)}
#s-plan .plan .pp small{font-size:12.5px;color:var(--ink-faint);font-family:var(--sans)}
#s-plan .plan .planlist{display:block;margin:10px 0 0;padding-left:18px;font-size:13px;color:var(--ink-soft);line-height:1.7}
#s-plan .plan .planline{display:block}
/* ——— clinician variant of the plan step (2026-09-25) ———
   A clinician sees Pro+ on its own: the Pro card carries .person-only, so setRole() sets
   its hidden attribute and [hidden]{display:none!important} takes it out of the grid. On
   the wide layout .two is two equal columns, which would leave the surviving card in the
   left half with dead space beside it - collapse to a single column whenever one of the
   cards is hidden. Scoped to #s-plan so the post-trial sheet (#p-trial), which also uses
   .plan, is untouched, and specific enough to win over the plain .two rule either way. */
#s-plan .two:has(> .plan[hidden]){grid-template-columns:minmax(0,1fr)}
/* The "First month free" badge sits inline after the tier name inside .pt, which is
   display:block rather than a flex row, so it needs its own spacing. */
#s-plan .plan .pt .badge{margin-left:9px;vertical-align:2px}
/* The one-time profile-fee line used to sit between the cards and the start button and was
   what separated them; it was removed from both paths on 2026-09-25, so the gap under the
   cards is set here instead of relying on that paragraph's margins. */
#s-plan .two{margin-bottom:22px}
.badge{font-size:9.5px;font-weight:600;letter-spacing:.1em;text-transform:uppercase;color:var(--teal-deep);background:rgba(46,158,142,.13);padding:3px 7px;border-radius:6px}
.waived{display:flex;justify-content:space-between;font-size:13px;color:var(--ink-soft);padding:13px 2px 4px}
.waived s{color:var(--ink-faint)}
.sheet .fine{font-size:11.5px;color:var(--ink-faint);text-align:center;margin:12px 0 0;line-height:1.5}

@media (prefers-reduced-motion:reduce){
  *{animation-duration:.001s!important;transition-duration:.001s!important}
}

/* ——— single-page onboarding form (screen 1) ——— */
.formwrap{padding:4px 4px 10px}
.formwrap h1{font-family:var(--serif);font-weight:400;font-size:26px;line-height:1.26;letter-spacing:-.012em;margin:6px 0 10px;max-width:18ch}
.formwrap .stand{color:var(--ink-soft);font-size:14.5px;margin:0 0 22px;max-width:34ch}
.formwrap .rule{border:0;border-top:1px solid var(--line);margin:24px 0 18px}
.formwrap .sub{font-family:var(--serif);font-size:18px;margin:0 0 6px}
.formwrap .subhint{color:var(--ink-soft);font-size:13px;margin:0 0 14px;max-width:34ch}
.fld{margin-bottom:16px}
.fld label{display:block;font-size:13px;font-weight:600;margin-bottom:7px}
.fld .req,.fld .opt{font-size:9.5px;font-weight:600;letter-spacing:.1em;text-transform:uppercase;margin-left:6px}
.fld .req{color:var(--teal-deep)}
.fld label .opt{
  display:inline;padding:0;border:0;border-radius:0;background:none;
  color:var(--ink-faint);font-size:9.5px;font-weight:600;
  letter-spacing:.1em;text-transform:uppercase;margin-left:6px;
}
.section-status{
  color:var(--ink-faint);font-family:var(--sans);font-size:9.5px;
  font-weight:600;letter-spacing:.1em;text-transform:uppercase;margin-left:6px;
  vertical-align:middle;
}
/* textarea joins this rule (added for the life-context free-text fields: sleep &
   energy, daily constraints, meds/supplements/conditions) so a multi-line answer
   sits in the SAME box as every single-line field above it rather than falling back
   to the browser default. Only the three properties a textarea needs and an input
   does not are set separately below - everything else is shared, so the two field
   types cannot drift apart visually. */
.fld input[type=text],.fld input[type=email],.fld select,.fld textarea{
  width:100%;padding:12px 14px;font-size:15px;color:var(--ink);background:var(--card);
  border:1px solid var(--line);border-radius:var(--r-md);transition:border-color .2s var(--ease),box-shadow .2s var(--ease);
}
.fld textarea{
  display:block;min-height:76px;line-height:1.5;resize:vertical;
}
.fld input:hover,.fld select:hover,.fld textarea:hover{border-color:rgba(28,45,74,.22)}
.fld input:focus,.fld select:focus,.fld textarea:focus{outline:none;border-color:var(--teal);box-shadow:0 0 0 3px rgba(46,158,142,.14)}
.fld textarea::placeholder{color:var(--ink-faint)}
.fld .hint{margin:7px 0 0;font-size:12.5px;color:var(--ink-faint);line-height:1.5}
.err{margin:7px 0 0;font-size:12.5px;color:#B3261E}
.chk{
  display:flex;gap:11px;align-items:flex-start;width:100%;text-align:left;
  background:var(--card);border:1px solid var(--line);border-radius:var(--r-md);
  padding:13px 15px;margin-bottom:8px;font-size:14px;line-height:1.5;
  transition:background .2s var(--ease),border-color .2s var(--ease);
}
.chk:hover{border-color:rgba(46,158,142,.5)}
.chk.on{background:rgba(46,158,142,.09);border-color:var(--teal)}
.chk .box{
  width:17px;height:17px;min-width:17px;margin-top:1px;border-radius:5px;
  border:1.5px solid rgba(28,45,74,.28);display:grid;place-items:center;
}
.chk.on .box{border-color:var(--teal);background:var(--teal)}
.chk .box svg{width:10px;height:10px;fill:none;stroke:#fff;stroke-width:2.4;stroke-linecap:round;stroke-linejoin:round;opacity:0}
.chk.on .box svg{opacity:1}
.chks{display:flex;flex-direction:column;gap:7px}
.consent{margin-top:16px}
.consent a{color:var(--teal-deep);text-decoration:underline;text-underline-offset:2px}
/* Without this, consentCareTeam's inline "optional" tag falls through to the bare .opt
   rule above (the selectable-option PILL style - padding/border/background), which is
   why it was rendering as a floating button instead of plain text. Scope it the same way
   .fld label .opt already is, so it reads as a small uppercase inline label instead. */
.consent .opt{
  display:inline;padding:0;border:0;border-radius:0;background:none;
  color:var(--ink-faint);font-size:9.5px;font-weight:600;
  letter-spacing:.1em;text-transform:uppercase;margin-left:6px;
  vertical-align:middle;
}
.formwrap .btn[disabled]{opacity:.34;cursor:not-allowed}
.why{font-size:12.5px;color:var(--ink-faint);margin:14px 0 0;line-height:1.55}

/* ——— channel choice (screen 2) ——— */
.choice{
  display:flex;gap:13px;align-items:flex-start;width:100%;text-align:left;
  background:var(--card);border:1px solid var(--line);border-radius:var(--r-md);
  padding:16px 17px;margin-bottom:11px;transition:border-color .2s var(--ease),background .2s var(--ease);
}
.choice:hover{border-color:rgba(46,158,142,.55)}
.choice.sel{border-color:var(--teal);background:rgba(46,158,142,.07)}
.choice .ico{width:34px;height:34px;flex:0 0 auto;border-radius:50%;background:var(--veil);display:grid;place-items:center}
.choice .ico svg{width:18px;height:18px;fill:none;stroke:var(--teal-deep);stroke-width:1.7;stroke-linecap:round;stroke-linejoin:round}
.choice .body{flex:1 1 auto;min-width:0}
.choice .ctitle{display:block;font-weight:600;font-size:14.5px}
.choice .cdesc{display:block;font-size:12.5px;color:var(--ink-soft);margin-top:3px;line-height:1.45}

/* ——— verification code input ——— */
.codeinput{
  font-family:var(--serif);font-size:26px!important;letter-spacing:.34em;text-align:center;
  padding:14px 12px!important;
}
.codeinput::placeholder{letter-spacing:.34em;color:var(--ink-faint);opacity:.5}
.linkline button[disabled]{opacity:.45;cursor:default;text-decoration:none}

/* Account step: email + code (CSS CHANGE 2026-10-15, flagged per project convention). Once a
   code is sent the email is locked (readonly - see setAccountState() in the JS) and reads as
   settled rather than editable: Nora's surface colour, softer text (4.5:1 on --veil), no
   hover cue - the focus ring stays. The code box opens under it after a hairline, so it reads
   as the next part of the same step rather than a new screen. */
.fld input[type=email][readonly]{background:var(--veil);color:var(--ink-soft);cursor:default}
.fld input[type=email][readonly]:hover{border-color:var(--line)}
.code-step{margin-top:22px;padding-top:20px;border-top:1px solid var(--line-soft)}
.code-step .stand{margin-bottom:16px}

/* ——— done / handoff (screen 4) ——— */
.done{flex:1;display:flex;flex-direction:column;justify-content:center;padding:34px 30px calc(30px + env(safe-area-inset-bottom))}
.done h1{font-family:var(--serif);font-weight:400;font-size:28px;line-height:1.26;margin:10px 0 12px;max-width:16ch}
.done p{color:var(--ink-soft);margin:0 0 22px;max-width:32ch;font-size:14.5px}

/* DEV6 desktop frame and onboarding navigation, adapted from the supplied UI. */
.shell{display:flex;flex-direction:column;width:min(100%,2560px);height:100dvh;margin:0 auto;padding:clamp(20px,2.2vw,44px) clamp(24px,3vw,72px) clamp(20px,2.2vw,44px)}
.top{display:flex;align-items:center;gap:12px;min-height:32px;margin-bottom:18px}
.brand{display:flex;align-items:center;gap:10px}
.brand img{width:26px;height:26px}
.brand .nm{font-family:var(--serif);font-size:17px;font-weight:500}
.brand .sep{color:var(--ink-faint)}
.brand .ctx{font-size:14px;color:var(--ink-soft)}
.flow-indicator{margin-left:auto;padding:7px 14px;border:1px solid var(--line);border-radius:10px;background:var(--card);font-size:13px;font-weight:600;color:var(--ink);letter-spacing:.01em}
/* Logout (CSS CHANGE 2026-10-08, flagged per project convention) - top right of the page on
   the chat screen only (#logoutBtn, shown by renderFlowChrome() in the JS). Same pill as
   .flow-indicator, which is hidden on that screen, so the two never sit side by side; the
   hover matches button.pip.is-done. min-height keeps a comfortable touch target. */
.logout{margin-left:auto;min-height:36px;padding:7px 14px;border:1px solid var(--line);border-radius:10px;background:var(--card);font-size:13px;font-weight:600;color:var(--ink);letter-spacing:.01em;transition:border-color .18s,background .18s}
.logout:hover{border-color:rgba(46,158,142,.55);background:rgba(46,158,142,.07)}
/* Settings (CSS CHANGE 2026-10-15, flagged per project convention). The gear (#settingsBtn) sits
   just before Logout on the chat screen and is the same pill as .logout - border, radius, card
   background, hover - squared to the 36px touch target, so the two read as one pair. It takes over
   Logout's margin-left:auto (pushing both to the right edge) and Logout drops its own while the gear
   shows. aria-expanded marks it while the Settings page is open. */
.settings-btn{margin-left:auto;width:36px;height:36px;flex:0 0 36px;display:grid;place-items:center;border:1px solid var(--line);border-radius:10px;background:var(--card);color:var(--ink);transition:border-color .18s,background .18s,color .18s}
.settings-btn:hover{border-color:rgba(46,158,142,.55);background:rgba(46,158,142,.07)}
.settings-btn[aria-expanded="true"]{border-color:rgba(46,158,142,.55);background:var(--veil);color:var(--teal-deep)}
.settings-btn svg{width:18px;height:18px;fill:none;stroke:currentColor;stroke-width:1.6;stroke-linecap:round;stroke-linejoin:round}
.settings-btn:not([hidden])+.logout{margin-left:0}
.rail{position:static;display:flex;height:auto;gap:5px;flex-wrap:wrap;margin-bottom:20px;border-radius:0;background:transparent;overflow:visible}
.pip{display:flex;align-items:center;justify-content:center;gap:5px;width:122px;min-height:34px;padding:7px 8px;border-radius:20px;background:var(--card);border:1px solid var(--line);font-size:12.5px;line-height:1;color:var(--ink-soft);white-space:nowrap}
.pip.on{background:var(--veil);border-color:rgba(46,158,142,.4);color:var(--ink)}
.pip.is-done{color:var(--teal-deep)}
button.pip.is-done:hover{border-color:rgba(46,158,142,.55);background:rgba(46,158,142,.07)}
.pip .pip-mark{display:grid;place-items:center;width:18px;height:18px;flex:0 0 18px;border-radius:50%;font-weight:600;line-height:1}
.pip.is-done .pip-mark{background:var(--teal);color:#fff}
.pip .pip-mark svg{width:12px;height:12px;fill:none;stroke:currentColor;stroke-width:2.2;stroke-linecap:round;stroke-linejoin:round}

/* Rail reveal (CSS CHANGE 2026-10-15, reworked 2026-10-16 - flagged per project convention) -
   replaces the slow .pip-exit slide-out collapse, which is gone: chips leaving the rail now
   simply disappear. Chips JOINING the rail come in one at a time: each rises from behind the
   page card's top edge (#app sits just below the rail and is drawn over it), grows up from its
   base, pops a little above its place, rocks on its base like a bubble and settles. The turning
   point is the bottom middle of the chip (transform-origin). renderFlowChrome() in the JS puts
   .pip-in on the joining chips only and starts each one as the one before it settles (an
   inline animation-delay). The 800ms must match PIP_BUBBLE_MS in the JS. "backwards" holds the
   hidden start state through that delay - a chip waiting its turn keeps its place, invisible,
   so nothing shifts - and leaves nothing applied once it ends. Tablets and larger only: the JS
   adds .pip-in only when RAIL_ANIMATES, so on a phone joining chips simply appear. */
.pip.pip-in{animation:pip-rise-wobble 800ms ease-in-out backwards;transform-origin:50% 100%}
@keyframes pip-rise-wobble{
  0%  {opacity:0;transform:translateY(46px) scale(.5);animation-timing-function:cubic-bezier(.2,.75,.3,1)}
  14% {opacity:1}
  38% {opacity:1;transform:translateY(-6px) scale(1.1)}
  48% {transform:translateY(0) scale(.97) rotate(-6deg)}
  60% {transform:scale(1.03) rotate(5deg)}
  71% {transform:rotate(-3.5deg)}
  82% {transform:rotate(2deg)}
  92% {transform:rotate(-.8deg)}
  100%{opacity:1;transform:none}
}
@media (prefers-reduced-motion:reduce){
  /* Owner's decision 2026-10-15: on a tablet or larger the chips animate even with the
     device's reduce-motion setting on. This undoes the page-wide rule above for these chips
     only; everything else on the page still respects the setting. */
  .pip.pip-in{animation-duration:800ms!important}
}

.stage{display:contents}
.app{flex:1 1 auto;width:100%;max-width:none;max-height:none;height:auto;min-height:0;border:1px solid var(--line);border-radius:clamp(22px,2vw,32px);box-shadow:0 22px 50px -24px rgba(28,45,74,.3);overflow:hidden}
.screen{border-radius:inherit}
.bar{padding-left:clamp(22px,4vw,54px);padding-right:clamp(22px,4vw,54px)}
.flow{padding:8px clamp(22px,4vw,54px) 34px}
.formwrap{width:min(100%,760px);margin:0 auto}
.disclaimer-wrap{padding-top:clamp(14px,3vw,36px)}
.formwrap h1{font-size:clamp(26px,2.4vw,34px);max-width:none}
.formwrap h1 em{font-style:italic;color:var(--teal-deep)}
.formwrap .stand{max-width:64ch;line-height:1.65}
.launch{padding:clamp(34px,5vw,72px);align-items:flex-start}
.launch h1{font-size:clamp(38px,5vw,66px);max-width:18ch}
.launch p{max-width:48ch;font-size:16px}
.launch .acts{width:min(100%,420px);align-self:center}
.role-form{padding-top:clamp(16px,3vw,40px)}
.details-mode .account-only{display:none!important}
.details-mode #restOfForm{padding-top:clamp(8px,2vw,24px)}
.role-choice{max-width:720px;margin-left:auto;margin-right:auto;padding:15px 17px;border-radius:13px}
.two{display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1fr);gap:14px}
.chipwrap{display:flex;flex-wrap:wrap;gap:8px;margin:2px 0 8px}
.chip{padding:9px 13px;border-radius:18px;background:var(--card);border:1px solid var(--line);font-size:13px;color:var(--ink-soft);transition:border-color .18s,background .18s,color .18s}
.chip:hover{border-color:rgba(46,158,142,.42)}
.chip.on{background:var(--veil);border-color:var(--teal-deep);color:var(--teal-deep);font-weight:500}
/* ——— Clinician practice screens (2026-10-14) - #s-practice / #s-workwith / #s-howpractice /
   #s-howwework. Additions only; nothing above is changed. The text box an "Other" choice
   reveals under its select, the two license inputs side by side (stacking on a narrow phone),
   and the two left-ruled "For your patients" / "For yourself" panels on "How we'll work". */
.fld .other-in{margin-top:9px}
.pair{display:flex;flex-wrap:wrap;gap:11px}
.pair>input{flex:1 1 170px;min-width:0}
.waypanel{border-left:2px solid rgba(46,158,142,.35);padding:2px 0 2px 15px;margin:0 0 20px}
.waypanel h2{margin:0 0 5px;font-family:var(--sans);font-size:14.5px;font-weight:600;color:var(--ink)}
.waypanel p{margin:0 0 9px;font-size:14px;line-height:1.6;color:var(--ink-soft);max-width:64ch}
.waypanel p:last-child{margin-bottom:0}
.waypanel em{color:var(--ink)}
/* The two longest new rail labels outgrow the fixed 122px pip once a completed pip adds its
   check mark ("Who you work with", "How you practice"); only these two may grow. */
.pip[data-step="workwith"],.pip[data-step="howpractice"]{width:auto;min-width:122px}
.gate-label{margin:10px 0 14px}
.sys-strong{color:var(--ink);font-weight:600}
.details-name{margin-top:22px}
.emergency{color:var(--ink);font-weight:500}
.consent-submit{margin-top:18px}
.telegram-submit{margin-top:6px}
.button-link{text-decoration:none}
.done-help{margin-top:20px!important}
.text-link{color:var(--teal-deep)}
.trial-label{margin-bottom:12px}
.trial-promises{margin:18px 0 20px}
#toast{position:fixed;left:50%;bottom:34px;transform:translate(-50%,14px);background:var(--ink);color:#fff;font-size:13px;padding:10px 16px;border-radius:16px;opacity:0;transition:all .3s var(--ease);pointer-events:none;z-index:99;max-width:80%;text-align:center}
.details-mode .chks{flex-direction:row;flex-wrap:wrap;gap:8px}
.details-mode .chks .chk{width:auto;border-radius:18px;padding:9px 13px;font-size:13px;color:var(--ink-soft)}
.details-mode .chks .chk .box{display:none}
.details-mode .chks .chk.on{color:var(--teal-deep);border-color:var(--teal-deep);font-weight:500}

@media (max-width:760px){
  .shell{padding:18px 16px 18px}
  .top{margin-bottom:15px}
  .rail{flex-wrap:nowrap;overflow-x:auto;padding-bottom:5px;margin-bottom:15px;scrollbar-width:none}
  .rail::-webkit-scrollbar{display:none}
  .pip{flex:0 0 auto}
  .app{height:auto;min-height:0;border-radius:22px}
  .two{grid-template-columns:1fr;gap:0}
  .launch h1{font-size:38px}
}
@media (max-width:430px){
  .shell{padding:12px 12px 12px}
  .brand .sep,.brand .ctx{display:none}
  .flow-indicator{padding:6px 11px;font-size:12px}
  .logout{padding:6px 11px;font-size:12px}
  .app{height:auto;min-height:0;border-radius:18px}
  .bar{padding-left:18px;padding-right:18px}
  .flow{padding-left:16px;padding-right:16px}
  .launch{padding:30px 24px}
  .launch h1{font-size:34px}
}

/* Every screen fills the available viewport height (CSS CHANGE 2026-10-15, flagged per
   project convention). The chat screen got this first, as a .chat-mode override: the card's
   760px cap lifted and the shell's bottom padding reduced to match its top padding, so the
   card runs down to just above the viewport edge instead of stopping short and leaving a
   band of empty page below it. Every onboarding screen now does the same, so the override
   is folded into the base rules above - .app max-height:none, and the .shell bottom padding
   equal to its top padding at each breakpoint (clamp(20px,2.2vw,44px) / 18px / 12px, were
   clamp(44px,5vw,96px) / 44px / 30px) - and the .chat-mode rules that used to live here are
   gone. renderFlowChrome() still toggles .chat-mode on #app; nothing in this file keys on it
   any more. */

/* Settings page (CSS CHANGE 2026-10-15, flagged per project convention) - #p-settings, a .panel like
   Saved and Profile holding the onboarding form's own .formwrap/.fld/.optgrid/.chk/.chip markup, so
   almost everything is inherited. Additions only: it sits above the context picker and the other
   overlays (z-index 37 > .confirmmodal's 36), since the gear that opens it is outside #app and can
   be pressed while one of those is up; its read-only fields (email, role, care team) get the same
   settled look as the locked email on the Account step; and the topic checkboxes get the same chip
   look .details-mode gives them on "About you" (#app is never in details-mode on the chat screen). */
#p-settings{z-index:37}
#p-settings .formwrap{padding-bottom:28px}
#p-settings .fld input[readonly],#p-settings .fld textarea[readonly]{background:var(--veil);color:var(--ink-soft);cursor:default;resize:none}
#p-settings .fld input[readonly]:hover,#p-settings .fld textarea[readonly]:hover{border-color:var(--line)}
#p-settings .fld input[readonly]::placeholder,#p-settings .fld textarea[readonly]::placeholder{color:var(--ink-soft)}
#p-settings .chks{flex-direction:row;flex-wrap:wrap;gap:8px}
#p-settings .chks .chk{width:auto;border-radius:18px;padding:9px 13px;font-size:13px;color:var(--ink-soft)}
#p-settings .chks .chk .box{display:none}
#p-settings .chks .chk.on{color:var(--teal-deep);border-color:var(--teal-deep);font-weight:500}
#p-settings .sub:first-child{margin-top:4px}
.stload{color:var(--ink-soft);font-size:14px;margin:6px 0 0}

/* Standalone Terms of Use and Privacy Policy pages. */
body.legal-body{height:auto;min-height:100%;overflow-y:auto;background:#E9EBE7}
.legal-shell{width:min(100% - 32px,880px);margin:0 auto;padding:40px 0 72px}
.legal-back{display:inline-block;margin-bottom:18px;color:var(--teal-deep);font-size:13px;font-weight:600;text-decoration:none}
.legal-back:hover{text-decoration:underline;text-underline-offset:3px}
.legal-page{background:var(--paper);border:1px solid var(--line);border-radius:24px;padding:clamp(28px,5vw,58px);box-shadow:0 22px 50px -28px rgba(28,45,74,.28)}
.legal-page h1{font-family:var(--serif);font-size:clamp(36px,5vw,54px);font-weight:400;line-height:1.08;letter-spacing:-.02em;margin:6px 0 8px}
.legal-page h2{font-family:var(--serif);font-size:22px;font-weight:500;line-height:1.3;margin:0 0 8px}
.legal-page section{padding-top:24px;margin-top:24px;border-top:1px solid var(--line)}
.legal-page p{color:var(--ink-soft);line-height:1.72;margin:0}
.legal-page a{color:var(--teal-deep)}
.legal-badge{color:var(--teal-deep)!important;font-size:10.5px!important;font-weight:600;letter-spacing:.13em;text-transform:uppercase}
.legal-effective{font-size:13px;margin-bottom:22px!important}
.legal-warning{margin:24px 0 4px;padding:15px 17px;border:1px solid rgba(46,158,142,.24);border-radius:12px;background:var(--veil);color:var(--ink-soft);font-size:13.5px;line-height:1.6}
.legal-warning strong{color:var(--ink)}
.legal-page p+p,.legal-page p+.legal-table,.legal-page .legal-table+p{margin-top:12px}
.legal-page h3{font-size:15px;font-weight:700;line-height:1.4;color:var(--ink);margin:18px 0 4px}
.legal-page h2+h3{margin-top:10px}
.legal-page strong{color:var(--ink);font-weight:700}
.legal-callout{margin:24px 0 0;padding:20px 22px;border:1px solid rgba(46,158,142,.24);border-radius:14px;background:var(--veil)}
.legal-page .legal-callout h3{font-family:var(--serif);font-size:21px;font-weight:500;margin:0 0 10px}
.legal-callout ul{margin:0;padding-left:20px;color:var(--ink-soft);line-height:1.65}
.legal-callout li+li{margin-top:6px}
.legal-callout li::marker{color:var(--teal)}
.legal-table{width:100%;border-collapse:collapse;margin:14px 0 0;font-size:14.5px;line-height:1.6}
.legal-table th{text-align:left;padding:0 14px 8px 0;border-bottom:1px solid var(--line);color:var(--ink-faint);font-size:11px;font-weight:600;letter-spacing:.13em;text-transform:uppercase}
.legal-table td{padding:12px 14px 12px 0;border-bottom:1px solid var(--line);color:var(--ink-soft);vertical-align:top}
.legal-table td:first-child{width:32%;color:var(--ink);font-weight:600}
.legal-foot p{font-size:12.5px;color:var(--ink-faint)}
@media (max-width:560px){
  .legal-table tr:first-child{display:none}
  .legal-table tr,.legal-table td{display:block}
  .legal-table tr{padding:12px 0;border-bottom:1px solid var(--line)}
  .legal-table td,.legal-table td:first-child{width:auto;border:0;padding:2px 0}
}
@media (max-width:560px){
  .legal-shell{width:min(100% - 20px,880px);padding:22px 0 44px}
  .legal-page{border-radius:18px;padding:24px 20px}
}
/* ——— hidden DEBUG PANEL (added 2026-10-07) ———
   See DEBUG PANEL in truenorth-onboarding-dev6-form.js. #p-debug reuses .panel/.phead/.psub/.flow
   as they are; everything below is new and scoped to the debug panel, its code field and the
   logo it is unlocked from, so nothing that already exists changes. */
#m4{touch-action:manipulation;-webkit-user-select:none;user-select:none;-webkit-touch-callout:none}
.dbgcode{width:96px;min-width:0;height:30px;padding:0 10px;border:1px solid var(--line);border-radius:var(--r-sm);
  background:var(--card);color:var(--ink);font:inherit;font-size:14px}
.dbgcode:focus{outline:2px solid var(--teal);outline-offset:1px}
.bar.dbg-armed .name{display:none}
.bar.dbg-armed .namewrap{display:none}   /* room for the code field - the role label goes with the name */
.dbgpsub{max-width:none}
#debugflow{min-height:0;font-size:13px;line-height:1.45}
.dbgsumbox,.dbggroup{background:var(--card);border:1px solid var(--line);border-radius:var(--r-md);padding:10px 12px;margin:0 0 12px}
.dbggroup-h{display:flex;align-items:center;gap:8px;font-weight:700;color:var(--ink);overflow-wrap:anywhere;margin:0 0 6px}
.dbgrow{display:flex;align-items:baseline;gap:8px;padding:3px 0;border-bottom:1px solid var(--line-soft)}
.dbgk{flex:0 0 38%;color:var(--ink-soft)}
.dbgv{flex:1 1 auto;min-width:0;color:var(--ink);overflow-wrap:anywhere;font-family:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;font-size:12px}
.dbgnote{margin:8px 0 0;color:var(--ink-soft)}
.dbgwarn{margin:8px 0;padding:6px 8px;border-radius:var(--r-sm);background:rgba(200,80,60,.10);color:var(--ink)}
.dbgcard{border-top:1px solid var(--line);padding:6px 0 2px}
.dbgcard>summary{display:flex;align-items:center;flex-wrap:wrap;gap:6px;cursor:pointer;padding:6px 0;color:var(--ink);font-weight:600}
.dbgtitle{flex:1 1 auto;min-width:0}
.dbgbadge{font-size:11px;font-weight:600;padding:1px 8px;border-radius:999px;background:var(--teal-deep);color:#fff}
.dbgbadge.alt{background:var(--veil);color:var(--ink-soft);border:1px solid var(--line)}
.dbgbadge.err{background:#B5473A;color:#fff}
.dbgbody{padding:2px 0 8px}
.dbgh{display:flex;align-items:center;gap:8px;margin:10px 0 4px;font-weight:700;color:var(--ink)}
.dbgpart{margin:0 0 6px;border-left:3px solid var(--teal);padding-left:8px}
.dbgpart-h{color:var(--ink-soft);font-size:12px;margin:0 0 2px}
.dbgpre{margin:0;max-height:260px;overflow:auto;white-space:pre-wrap;word-break:break-word;padding:8px;
  border-radius:var(--r-sm);background:var(--veil);color:var(--ink);font-family:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;font-size:12px}
.dbgnotes{margin:8px 0 0;padding-left:18px;color:var(--ink-soft);font-size:12px}
.dbgfoot{display:flex;justify-content:flex-end;gap:8px;margin-top:8px}
.dbgcopy{flex:0 0 auto;padding:2px 10px;border:1px solid var(--line);border-radius:999px;background:var(--card);color:var(--teal-deep);font:inherit;font-size:12px;cursor:pointer}
.dbgcopy:hover{background:var(--veil)}
/* Incognito's dark palette keeps --teal-deep, which is too dark on its --card - use its soft ink instead */
.app.incognito .dbgcopy{color:var(--ink-soft)}

/* ——— CLINICIAN PATIENT FOLDERS (added 2026-10-08) ———
   CSS/design change, called out explicitly per project convention (see kaiProcess on the
   sibling MICROSVC_TRUENORTH_ONBOARDING_DEV_CHAT.xml, 2026-10-08). New rules only - nothing
   above is changed. Three pieces, all clinician-only (hidden for everyone else):
   - .ctxstrip: a slim line under the chat bar naming the context the next message goes to
     (General, or one patient folder), with Change. A folder gets the brand teal so it reads
     as "you are inside a patient's record"; General stays neutral.
   - .ctxcard: the context picker, reusing .confirmmodal/.confirmcard (overlay, card, z-index)
     and .fld (labels, select and text input) - only the close button, the stacked layout
     and the select/input + button rows are new.
   - .histgroup*: History grouped into General + one collapsible group per patient folder,
     whose rows are the existing .histrow, indented under their group; .histnew* is the
     "+ New patient folder" button/field at the top, sized like the rename field.
     2026-10-09: .histgrouprow puts the (unchanged) header button and .histgroupnew - a round,
     bordered "+" that starts a new chat in that group - side by side. */
.ctxstrip{
  flex:0 0 auto;display:flex;align-items:center;gap:8px;
  margin:0 18px 6px;padding:6px 6px 6px 10px;border-radius:var(--r-sm);
  background:var(--veil);border:1px solid var(--line-soft);font-size:12.5px;line-height:1.3;
}
.ctxicon{width:15px;height:15px;flex:0 0 auto;fill:none;stroke:var(--ink-faint);stroke-width:1.6;stroke-linejoin:round}
.ctxlabel{font-weight:600;color:var(--ink);min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.ctxnote{color:var(--ink-faint);font-size:11.5px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;min-width:0;flex:1 1 auto}
.ctxchange{flex:0 0 auto;padding:4px 10px;border-radius:999px;font-size:12px;font-weight:600;color:var(--teal-deep)}
.ctxchange:hover{background:var(--card)}
.ctxstrip.infolder{background:rgba(46,158,142,.10);border-color:rgba(46,158,142,.35)}
.ctxstrip.infolder .ctxicon{stroke:var(--teal-deep)}
.ctxstrip.infolder .ctxnote{color:var(--teal-deep)}
.app.incognito .ctxchange,.app.incognito .ctxstrip.infolder .ctxnote{color:var(--ink-soft)}
@media (min-width:760px){.ctxstrip{margin-left:clamp(22px,4vw,54px);margin-right:clamp(22px,4vw,54px)}}

.ctxcard{position:relative;max-width:360px}
.ctxclose{position:absolute;top:8px;right:8px;width:30px;height:30px}
.ctxclose svg{width:15px;height:15px}
.ctxcard h3{padding-right:28px}
.ctxcard .ctxgeneral{margin:0 0 16px}
.ctxcard .fld{margin-bottom:12px}
.ctxcard .fld:last-child{margin-bottom:0}
.ctxrow{display:flex;gap:8px;align-items:stretch}
.ctxrow select,.ctxrow input[type=text]{flex:1 1 auto;min-width:0}
.ctxrow .btn{width:auto;flex:0 0 auto;padding:10px 14px}
.ctxrow .btn[disabled]{opacity:.34;cursor:not-allowed}
.ctxcard .hint{margin:7px 0 0;font-size:12px;color:var(--ink-faint);line-height:1.5}
.ctxcard .err{margin:6px 0 0}

.histnewbtn{
  display:flex;align-items:center;gap:6px;width:100%;margin:0 0 8px;padding:7px 8px;
  border:1px dashed var(--line);border-radius:8px;font-size:12px;font-weight:600;color:var(--teal-deep);
}
.histnewbtn:hover{background:var(--veil)}
.histnewbtn svg{width:13px;height:13px;fill:none;stroke:currentColor;stroke-width:2;stroke-linecap:round}
.histnewrow{display:flex;align-items:center;gap:4px;margin:0 0 4px}
.histnewinput{
  flex:1 1 auto;min-width:0;font-family:"Segoe UI",sans-serif;font-size:12px;font-weight:500;color:var(--ink);
  background:var(--paper);border:1px solid var(--line);border-radius:5px;padding:4px 6px;line-height:1.3;
}
.histnewinput:focus{outline:none;border-color:var(--teal)}
.histnewhint{margin:0 0 8px;font-size:11px;color:var(--ink-faint)}
.histnewerr{margin:-4px 0 8px;font-size:11.5px}
.histgroup{border-bottom:1px solid var(--line-soft)}
.histgroup:last-child{border-bottom:0}
.histgrouphead{
  display:flex;align-items:center;gap:6px;width:100%;padding:8px 4px;margin:0 -4px;border-radius:8px;
  text-align:left;font-size:12.5px;font-weight:600;color:var(--ink);
}
.histgrouphead:hover{background:var(--veil)}
.histchev{width:13px;height:13px;flex:0 0 auto;fill:none;stroke:var(--ink-faint);stroke-width:2;stroke-linecap:round;stroke-linejoin:round;transition:transform .15s var(--ease)}
.histgroup.open .histchev{transform:rotate(90deg)}
.histgroupicon{width:15px;height:15px;flex:0 0 auto;fill:none;stroke:var(--ink-soft);stroke-width:1.6;stroke-linejoin:round}
.histgroupname{flex:1 1 auto;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.histgroupnow{flex:0 0 auto;font-size:9.5px;font-weight:600;letter-spacing:.06em;text-transform:uppercase;color:var(--teal-deep)}
.histgroup.current .histgroupicon{stroke:var(--teal-deep)}
.histgroupbody{padding:0 0 6px 19px}
.histgroupmsg{margin:2px 0 6px;font-size:12px;color:var(--ink-faint)}
.histgrouprow{display:flex;align-items:center;gap:4px}
.histgrouprow .histgrouphead{flex:1 1 auto;min-width:0;width:auto;margin-right:0}
.histgroupnew{
  flex:0 0 auto;display:grid;place-items:center;width:24px;height:24px;padding:0;
  border:1px solid var(--line);border-radius:50%;color:var(--teal-deep);
  transition:background .15s var(--ease),border-color .15s var(--ease);
}
.histgroupnew:hover{background:var(--veil);border-color:var(--teal)}
.histgroupnew svg{width:12px;height:12px;fill:none;stroke:currentColor;stroke-width:2;stroke-linecap:round}
.app.incognito .histgroupnew{color:var(--ink-soft)}
.app.incognito .histnewbtn,.app.incognito .histgroupnow{color:var(--ink-soft)}

/* ——— Tom Select pickers - Timezone and Licensure (CSS CHANGE 2026-10-15, flagged per project
   convention). Additions only. Tom Select's own stylesheet (/tom-select.css) loads before this
   file; these rules make its control look like every other .fld input on the page (same
   border, radius, padding, type and focus ring) and its dropdown like the page's cards. The
   search box Tom Select puts INSIDE the control is an input[type=text], so it is explicitly
   reset here - otherwise the .fld input[type=text] rules above would draw a second box inside
   the first. ——— */
.fld .ts-wrapper{width:100%}
.fld .ts-wrapper .ts-control,.fld .ts-wrapper.single .ts-control{
  padding:12px 38px 12px 14px;min-height:0;align-items:center;
  font-family:inherit;font-size:15px;line-height:normal;color:var(--ink);
  background:var(--card);border:1px solid var(--line);border-radius:var(--r-md);box-shadow:none;
  transition:border-color .2s var(--ease),box-shadow .2s var(--ease);
}
.fld .ts-wrapper .ts-control:hover{border-color:rgba(28,45,74,.22)}
.fld .ts-wrapper.focus .ts-control{border-color:var(--teal);box-shadow:0 0 0 3px rgba(46,158,142,.14)}
.fld .ts-wrapper.dropdown-active .ts-control{border-radius:var(--r-md)}
.fld .ts-wrapper .ts-control>.item{color:var(--ink)}
.fld .ts-wrapper.single.ts-typing .ts-control>.item,
.fld .ts-wrapper.single.ts-editing .ts-control>.item{display:none}
.fld .ts-wrapper .ts-control input[type=text],
.fld .ts-wrapper .ts-control input[type=text]:hover,
.fld .ts-wrapper .ts-control input[type=text]:focus{
  width:auto;min-height:0;padding:0;margin:0;border:0;border-radius:0;background:none;box-shadow:none;
  font-family:inherit;font-size:15px;line-height:normal;color:var(--ink);
}
.fld .ts-wrapper .ts-control input[type=text]::placeholder{color:var(--ink-faint)}
.fld .ts-wrapper.single .ts-control:not(.rtl):after{right:16px}
.fld .ts-wrapper.single .ts-control:after{border-color:var(--ink-soft) transparent transparent}
.fld .ts-wrapper.single.dropdown-active .ts-control:after{border-color:transparent transparent var(--ink-soft)}
.fld .ts-dropdown{
  margin-top:6px;border:1px solid var(--line);border-radius:var(--r-md);background:var(--card);
  box-shadow:0 14px 34px -14px rgba(28,45,74,.32);overflow:hidden;z-index:30;
  font-family:inherit;font-size:14px;line-height:1.4;color:var(--ink);
}
.fld .ts-dropdown .ts-dropdown-content{max-height:264px}
.fld .ts-dropdown .option,.fld .ts-dropdown .no-results,.fld .ts-dropdown .create{padding:9px 14px}
.fld .ts-dropdown .create{color:var(--ink-soft)}
.fld .ts-dropdown .create strong{color:var(--ink);font-weight:600}
.fld .ts-dropdown .no-results{color:var(--ink-faint)}
.fld .ts-dropdown .active{background:var(--veil);color:var(--ink)}
.fld .ts-dropdown .option.selected{color:var(--teal-deep);font-weight:600}
.fld .ts-dropdown .optgroup-header{
  padding:12px 14px 5px;background:var(--card);font-size:10.5px;font-weight:600;
  letter-spacing:.14em;text-transform:uppercase;color:var(--ink-faint);
}
.fld .ts-dropdown .optgroup:before{display:none}
.fld .ts-dropdown .highlight{background:rgba(46,158,142,.2);border-radius:2px}
/* ——— MEMBERSHIP (2026-10-18) ———
   New rules only; nothing above was changed. The trial-ending / payment-problem banner above the
   conversation (same placement as .ctxstrip), the note that replaces the message box when there is
   no access (.composer.locked), the two ticks on the paywall sheet, and Settings › Subscription. */
.subbanner{
  flex:0 0 auto;display:flex;align-items:center;gap:8px;
  margin:0 18px 6px;padding:7px 6px 7px 12px;border-radius:var(--r-sm);
  background:rgba(46,158,142,.10);border:1px solid rgba(46,158,142,.35);
  font-size:12.5px;line-height:1.4;color:var(--ink);
}
.subbannertext{flex:1 1 auto;min-width:0}
.subbannerbtn{
  flex:0 0 auto;padding:6px 12px;border-radius:999px;font-size:12px;font-weight:600;
  color:var(--teal-deep);background:var(--card);border:1px solid rgba(46,158,142,.35);
}
.subbannerclose{flex:0 0 auto}
@media (min-width:760px){.subbanner{margin-left:clamp(22px,4vw,54px);margin-right:clamp(22px,4vw,54px)}}
.composer.locked .inputrow,.composer.locked .suggestions{display:none}
.paywallbar{
  display:flex;align-items:center;gap:12px;flex-wrap:wrap;
  background:var(--card);border:1px solid var(--line);border-radius:var(--r-md);padding:12px 12px 12px 16px;
}
.paywallbartext{flex:1 1 180px;font-size:13.5px;line-height:1.45;color:var(--ink-soft)}
.paywallbar .btn{width:auto;flex:0 0 auto;padding:11px 16px;font-size:13.5px}
.payconsents{margin:14px 0 8px}
.payconsents .consent{margin-top:0}
#payErr{margin:0 0 10px}
.stsub{margin-top:6px}
.stsub .krow .btn{width:auto}
/* ——— HELP & LEGAL LINKS (CSS CHANGE 2026-10-21, flagged per project convention) ———
   New rules only; nothing above was changed. The public website (TRUENORA_WEBSITE) holds the only
   copy of How to use Nora, the FAQ, the Terms of Use and the Privacy Policy; the page links to them,
   each in a new tab, from four places: the Help "?" before the Settings gear on the chat screen
   (#helpBtn - the same 36px pill as .settings-btn) and its dropdown (#helpMenu - styled like the
   History row's menu, with 40px rows for touch, and above every panel: z-index 40 > #p-settings' 37,
   because it hangs from the top bar over #app); a line of links under "Sign in" on the launch screen;
   a sentence on the disclaimer gate (plain .sysnote links - no new rule); and Settings › Help & legal.
   The Help pill takes over the gear's margin-left:auto, the way the gear takes Logout's. */
.help-wrap{position:relative;z-index:40;flex:0 0 auto;display:flex;margin-left:auto}
.help-wrap:not([hidden]) ~ .settings-btn,.help-wrap:not([hidden]) ~ .logout{margin-left:0}
.help-btn{width:36px;height:36px;display:grid;place-items:center;border:1px solid var(--line);border-radius:10px;background:var(--card);color:var(--ink);transition:border-color .18s,background .18s,color .18s}
.help-btn:hover{border-color:rgba(46,158,142,.55);background:rgba(46,158,142,.07)}
.help-btn[aria-expanded="true"]{border-color:rgba(46,158,142,.55);background:var(--veil);color:var(--teal-deep)}
.help-btn svg{width:18px;height:18px;fill:none;stroke:currentColor;stroke-width:1.6;stroke-linecap:round;stroke-linejoin:round}
.help-menu{
  position:absolute;top:calc(100% + 6px);right:0;min-width:190px;padding:4px;display:flex;flex-direction:column;
  background:var(--card);border:1px solid var(--line);border-radius:var(--r-sm);box-shadow:0 10px 24px -10px rgba(28,45,74,.3);
}
.help-menu a{display:flex;align-items:center;min-height:40px;padding:8px 12px;border-radius:6px;font-size:13.5px;font-weight:500;color:var(--ink);text-decoration:none;white-space:nowrap}
.help-menu a:hover,.help-menu a:focus-visible{background:var(--veil);color:var(--teal-deep)}
.launch-links{margin-top:18px;text-align:center;font-size:12.5px;line-height:2;color:var(--ink-faint)}
.launch-links a{color:var(--ink-soft);text-decoration:underline;text-underline-offset:2px}
.launch-links a:hover{color:var(--teal-deep)}
.sthelp{margin-top:6px}
.helplinks{list-style:none;margin:0;padding:0}
.helplinks a{display:inline-flex;align-items:center;min-height:40px;font-size:14px;color:var(--teal-deep);text-underline-offset:2px}
