:root {
  color-scheme: light;
  --bg: #f7f7f5;
  --panel: #ffffff;
  --ink: #202322;
  --muted: #6d746f;
  --line: #d9ded8;
  --accent: #0f766e;
  --accent-dark: #0b4f4a;
  --warn: #8a3b12;
  --soft: #eef4f2;
  /* Promoted from hard-coded values so dark mode is a pure variable swap. */
  --surface: #fbfbfa;      /* subtle off-white panels (subsections, repeat rows) */
  --field-border: #cbd2cc; /* input / toggle borders */
  --label: #303632;        /* field label text */
  --toggle-off: #b9c2bd;   /* toggle track when off */
  --drag: #eef3ff;         /* drag-over highlight */
  --locked-bg: #eef1ed;    /* read-only field background */
  --locked-ink: #59615c;   /* read-only field text */
  --on-accent: #ffffff;    /* text/icons sitting on an accent fill */
  --input-bg: #f5f6f4;         /* field fill, a shade off the card behind it */
  --field-border-strong: #b3bcb6; /* field border on hover */
  --focus-ring: rgba(15, 118, 110, 0.16);
  --card-head: #f0f1ee;    /* the tinted strip across the top of a card */
}

[data-theme="dark"] {
  color-scheme: dark;
  --bg: #15181a;
  --panel: #1e2225;
  --ink: #e7eae8;
  --muted: #9aa3a0;
  --line: #333b39;
  --accent: #2dd4bf;
  --accent-dark: #14b8a6;
  --warn: #f0a868;
  --soft: #243330;
  --surface: #23282b;
  --field-border: #3a4340;
  --label: #c9d2ce;
  --toggle-off: #4a534f;
  --drag: #243a44;
  --locked-bg: #2a2f2d;
  --locked-ink: #8a938f;
  --on-accent: #07201d;
  --input-bg: #191d1f;
  --field-border-strong: #55605c;
  --focus-ring: rgba(45, 212, 191, 0.22);
  --card-head: #262b2e;
}

* {
  box-sizing: border-box;
}

/* Lets `height` animate to and from `auto` for the expanding sections below.
   Browsers without it ignore the declaration and those sections just snap. */
:root {
  interpolate-size: allow-keywords;
}


/* No rubber-band bounce when the page is scrolled past its top or bottom (the
   macOS elastic overscroll). Set on both, because which of the two is the page's
   scroller differs between Safari and Chrome. */
html,
body {
  overscroll-behavior: none;
}

body {
  margin: 0;
  background: var(--bg);
  color: var(--ink);
  font-family: Inter, ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
  letter-spacing: 0;
}

button,
input,
select,
textarea {
  font: inherit;
}

.workspace {
  display: block;
  min-height: 100vh;
  background: var(--bg);
}

/* App chrome: brand + deed picker on the left, document actions on the right.
   Sticky, so the Download button stays reachable however far down the columns
   the user has scrolled. */
.appbar {
  position: sticky;
  top: 0;
  z-index: 20;
  /* Content on the left, document actions hard right. This was a 1fr|auto|1fr
     grid built around an emblem in the centre column; with the emblem gone that
     left the actions stranded in the middle with an empty column beside them. */
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  align-items: center;
  gap: 18px;
  padding: 8px 24px;
  /* The bottom edge is drawn in the button colour with a soft wash bleeding up
     from it into the bar -- the same treatment as the SolPros navbar. The wash
     is a separate background-image so a browser without color-mix() just drops
     it and keeps the plain panel. */
  background-color: var(--panel);
  background-image: linear-gradient(to top, color-mix(in srgb, var(--accent) 12%, transparent), transparent 50%);
  border-bottom: 1px solid var(--accent);
}

.appbar-left {
  display: flex;
  align-items: center;
  gap: 18px;
  min-width: 0;
  /* Wrap rather than overflow. The picker keeps a readable minimum width, so
     when the bar runs out of room it drops to a second line instead of running
     underneath the toggles -- which is what an overflowing flex child does. */
  flex-wrap: wrap;
  row-gap: 8px;
}

.brand {
  display: flex;
  gap: 10px;
  align-items: center;
  padding-right: 18px;
  border-right: 1px solid var(--line);
  flex: 0 0 auto;
}

.brand-text {
  min-width: 0;
}

.appbar-title {
  /* The document's name earns its space before the picker does: a truncated
     template name is worse than a slightly narrower client list, and on a deed
     the bar also carries two toggles. */
  min-width: 200px;
  flex: 1 1 auto;
}

.brand-mark {
  display: grid;
  width: 32px;
  height: 32px;
  place-items: center;
  border-radius: 8px;
  background: var(--accent);
  color: var(--on-accent);
  font-weight: 800;
}

.brand-name {
  font-weight: 800;
  line-height: 1.1;
}

.template-name {
  margin-top: 2px;
  color: var(--muted);
  font-size: 12px;
}

.brand .select {
  margin-top: 3px;
  max-width: 220px;
}

.content {
  min-width: 0;
  padding: 18px 24px 32px;
}

.appbar-title h1 {
  margin: 0;
  font-size: 18px;
  line-height: 1.15;
  /* Wrap rather than truncate. A HotDocs template title runs long
     ("Warranty/Quitclaim/Correction Deed" wants 543px at this size) and the bar
     also carries the template selector, the answer picker and two toggles, so
     there is no width at which it fits on one line. The document's own name is
     the worst thing on the bar to lose, so it takes a second line -- breaking at
     its slashes, where templateHeading() puts the opportunities. */
  overflow-wrap: break-word;
}

.appbar-title p {
  margin: 2px 0 0;
  color: var(--muted);
  font-size: 12px;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* Each top-level dialog is its own card. The card *is* the boundary, which is
   what lets the fields inside drop their own borders: one box per section
   instead of a box around every question. */
.section {
  min-width: 0;
  margin-top: 16px;
  padding: 0 24px 24px;
  border: 1px solid var(--line);
  border-radius: 14px;
  background: var(--panel);
}

/* Card header: the section name centred on a tinted strip across the top of the
   card. The negative margins pull the strip out to the card's edges. */
.section > .section-heading,
.intake-card > h2 {
  position: relative;
  display: block;
  margin: 0 -24px 20px;
  /* 12px + the title's pinned 19.5px line = the strip's original 44.5px. The
     title grew from 15px to 17px; the strip did not. */
  padding: 12px 24px;
  text-align: center;
  background: var(--card-head);
  border-bottom: 1px solid var(--line);
  border-radius: 13px 13px 0 0;
}

/* A nested dialog -- and every add/remove-row group -- is a tinted band across
   the card rather than a box sitting inside it. Full-bleed to the card's edges
   with the card's own padding put back, so the fields in the group line up with
   every other field instead of stepping in. Its heading is deliberately unlike
   the card's: small, muted and left-aligned, so a group never reads as a
   section. */
.subsection {
  margin: 22px -24px 22px;
  padding: 13px 24px 18px;
  border-top: 1px solid var(--line);
  border-bottom: 1px solid var(--line);
  background: var(--card-head);
}

/* A group inside a group is already inside the band: it must not bleed out a
   second time, and a second tint on top of the first would just muddy it. */
.subsection .subsection {
  margin: 18px 0 0;
  padding: 13px 0 0;
  border-bottom: 0;
  background: none;
}

.subsection > .section-heading {
  margin: 0 0 12px;
  padding: 0;
  background: none;
  border: 0;
  border-radius: 0;
}

/* A tinted band's own fields sit on the card colour to stay legible against it.
   A flat group is on the card already, so its fields keep the normal fill. */
.subsection:not(.subsection-flat) .field input[type="text"],
.subsection:not(.subsection-flat) .field textarea,
.subsection:not(.subsection-flat) .select-trigger {
  background: var(--panel);
}

/* Order matters below: a flat group's child takes the full band treatment, so
   its rule has to come after the generic "nested groups don't bleed" one. */
.subsection-flat {
  margin: 0;
  padding: 0;
  border: 0;
  background: none;
}

.section > .subsection:last-child,
.subsection-flat > .subsection:last-child {
  margin-bottom: 0;
}

.subsection-flat > .section-heading {
  margin-bottom: 14px;
}

.subsection-flat > .subsection {
  margin: 22px -24px 22px;
  padding: 13px 24px 18px;
  border-top: 1px solid var(--line);
  border-bottom: 1px solid var(--line);
  background: var(--card-head);
}

.section-heading {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  margin-bottom: 12px;
}

.section h2 {
  margin: 0;
  font-size: 17px;
  /* Pinned rather than "normal", which varies by font (and so by OS): the
     strip's height is set by this plus its padding, and must not grow. */
  line-height: 19.5px;
  font-weight: 700;
  letter-spacing: 0.01em;
}

.subsection h3 {
  margin: 0;
  font-size: 12px;
  font-weight: 700;
  letter-spacing: 0.02em;
  color: var(--muted);
}

/* Compact enough to sit in the header strip without setting its height. */
.subsection > .section-heading .secondary-button {
  min-height: 26px;
  padding: 4px 10px;
  border-radius: 6px;
  font-size: 12px;
}

/* Fields are laid out at the width they actually need (set per field by
   app.js from the component's own metadata) rather than in equal columns, so a
   "Year" box stops eating a fifth of the card. Rows are bottom-aligned: labels
   and hints grow upward, which keeps every control on one baseline across the
   row -- including toggles, which have no label at all. */
.field-grid {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  gap: 22px 20px;
}

/* The interview hides a field by setting its `hidden` attribute, and the
   author-level `display` below would otherwise beat the UA's [hidden] rule and
   show it anyway. Specificity does the work rather than !important, so the
   discrete `display` transition further down can still hold the field on screen
   while it fades out. */
.field[hidden] {
  display: none;
}

.field {
  display: flex;
  flex-direction: column;
  min-width: 0;
  /* Grow a little to take up the slack at the end of a row, but never balloon
     to the full card width. */
  flex: 1 1 var(--field-w, 20ch);
  max-width: calc(var(--field-w, 20ch) + 8ch);
}

/* A toggle is just a switch and its question, so it takes exactly the room it
   needs. */
.field-trueFalse {
  flex: 0 0 auto;
  max-width: 100%;
}

/* A multi-line box gets more slack than the +8ch a single-line field gets, so
   it can use the room left at the end of a row -- but it is still capped, or a
   two-word trust name ends up in a box the width of the card. app.js decides
   which ones are long-form enough to ask for a full row in the first place. */
.field:has(textarea) {
  max-width: calc(var(--field-w, 20ch) + 24ch);
}

/* Label, then control. */
.field label:not(.toggle) { order: 1; }
.field input,
.field .select,
.field textarea { order: 2; }
.field .choice-other { order: 3; }

.field label:not(.toggle) {
  display: block;
  margin-bottom: 6px;
  color: var(--muted);
  font-size: 12px;
  font-weight: 600;
  line-height: 1.3;
}

/* The section card carries the section's boundary, so a field needs only enough
   of its own surface to read as somewhere you can type: a soft fill and a
   hairline, no heavy box. */
.field input[type="text"],
.field textarea {
  width: 100%;
  min-height: 34px;
  border: 1px solid var(--field-border);
  border-radius: 8px;
  background: var(--input-bg);
  color: var(--ink);
  padding: 7px 10px;
  font-size: 14px;
  outline: none;
  transition: border-color 120ms ease, box-shadow 120ms ease, background 120ms ease;
}

.field input[type="text"]:hover,
.field textarea:hover {
  border-color: var(--field-border-strong);
}


.field textarea {
  min-height: 74px;
  resize: vertical;
  line-height: 1.5;
}

/* The free-text box a select falls back to for "Other..." sits under it. */
.field .choice-other {
  margin-top: 8px;
}

.field input[type="text"]:focus,
.field textarea:focus {
  border-color: var(--accent);
  background: var(--panel);
  box-shadow: 0 0 0 3px var(--focus-ring);
}

.field input[type="text"]::placeholder,
.field textarea::placeholder {
  color: var(--muted);
}

.field-locked {
  opacity: 0.72;
}

.field-locked input,
.field-locked textarea,
.field-locked .select-trigger {
  background: var(--locked-bg);
  color: var(--locked-ink);
}

/* Guidance marker: the prompt's own help text, on hover. A native title
   tooltip on purpose -- it costs the row no height, and unlike a styled popover
   it can't be clipped by the overflow the expanding sections need. */
.field-help {
  display: inline-grid;
  place-items: center;
  width: 13px;
  height: 13px;
  margin-left: 5px;
  border: 1px solid var(--field-border);
  border-radius: 50%;
  background: transparent;
  color: var(--muted);
  font-size: 9px;
  font-weight: 800;
  font-style: normal;
  line-height: 1;
  vertical-align: 1px;
  cursor: help;
  transition: background 120ms ease, color 120ms ease, border-color 120ms ease;
}

.field-help:hover,
.field-help:focus-visible {
  border-color: var(--accent);
  background: var(--accent);
  color: var(--on-accent);
  outline: none;
}

/* The guidance itself. A popover, so it draws in the top layer and can't be
   clipped by the overflow the expanding bands and repeat sections need. */
.field-help-bubble {
  position: fixed;
  inset: auto;
  margin: 0;
  padding: 9px 11px;
  width: max-content;
  border: 1px solid var(--line);
  border-radius: 8px;
  background: var(--panel);
  box-shadow: 0 10px 28px rgba(0, 0, 0, 0.16), 0 2px 5px rgba(0, 0, 0, 0.06);
  color: var(--ink);
  font-size: 12px;
  font-weight: 400;
  line-height: 1.45;
  text-align: left;
  white-space: pre-line;
}

.field-help-bubble:not(:popover-open) {
  display: none;
}

.toggle {
  display: flex;
  min-height: 34px;
  align-items: center;
  gap: 10px;
  color: var(--ink);
  font-size: 13px;
  font-weight: 600;
  line-height: 1.3;
  cursor: pointer;
}

.toggle:hover .toggle-track {
  box-shadow: 0 0 0 3px var(--soft);
}

.toggle input {
  position: absolute;
  opacity: 0;
  pointer-events: none;
}

.toggle-track {
  position: relative;
  width: 38px;
  height: 22px;
  border-radius: 999px;
  background: var(--toggle-off);
  flex: 0 0 auto;
}

.toggle-track::after {
  position: absolute;
  top: 3px;
  left: 3px;
  width: 16px;
  height: 16px;
  border-radius: 999px;
  background: #fff;
  content: "";
  transition: transform 140ms ease;
}

.toggle input:checked + .toggle-track {
  background: var(--accent);
}

.toggle input:checked + .toggle-track::after {
  transform: translateX(16px);
}

.repeat-rows {
  display: grid;
  gap: 0;
}

.repeat-row {
  position: relative;
  padding: 14px 0;
  border-top: 1px solid var(--line);
}

.repeat-row:first-child {
  border-top: 0;
  padding-top: 2px;
}

/* Out of the flow, so removing the "Row n" caption gave the row back a whole
   line rather than just its text. */
.repeat-row-head {
  position: absolute;
  top: 12px;
  right: 0;
  z-index: 1;
}

.repeat-row:first-child .repeat-row-head {
  top: 0;
}

/* Buttons inherit the body font, which left them at 16px next to 14px fields.
   One size and one radius for the whole set. */
.primary-button,
.secondary-button,
.text-button {
  border: 0;
  border-radius: 8px;
  cursor: pointer;
  font-size: 13px;
  font-weight: 700;
  line-height: 1.2;
}

.primary-button {
  min-width: 128px;
  min-height: 34px;
  background: var(--accent);
  color: var(--on-accent);
  padding: 8px 16px;
}

.primary-button:hover {
  background: var(--accent-dark);
}

.secondary-button {
  min-height: 34px;
  border: 1px solid var(--field-border);
  background: var(--panel);
  color: var(--accent-dark);
  padding: 7px 14px;
}

.secondary-button:hover {
  background: var(--soft);
}

.text-button {
  background: transparent;
  color: var(--muted);
  padding: 4px 0;
  border-radius: 4px;
  font-size: 12px;
  font-weight: 600;
}

.text-button:hover {
  color: var(--warn);
  text-decoration: underline;
}

.status {
  min-height: 20px;
  padding-top: 14px;
  color: var(--muted);
  font-size: 13px;
}

.page-footer {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  flex-wrap: wrap;
  margin-top: 18px;
  padding: 18px 0 6px;
  border-top: 1px solid var(--line);
}

.footer-end {
  display: flex;
  align-items: center;
  gap: 10px;
  color: var(--muted);
  font-size: 13px;
}

.footer-mark {
  display: grid;
  width: 24px;
  height: 24px;
  place-items: center;
  border-radius: 6px;
  background: var(--accent);
  color: var(--on-accent);
  font-size: 13px;
  font-weight: 800;
  flex: 0 0 auto;
}

.footer-actions {
  display: flex;
  align-items: center;
  gap: 16px;
}

.footer-top {
  color: var(--accent-dark);
  font-size: 13px;
  font-weight: 700;
  text-decoration: none;
}

.footer-top:hover {
  text-decoration: underline;
}

@media (max-width: 860px) {
  .content {
    padding: 18px 14px 34px;
  }

  .section,
  .intake-card {
    padding: 0 16px 18px;
    border-radius: 12px;
  }

  .section > .section-heading,
  .intake-card > h2 {
    margin: 0 -16px 16px;
    padding: 11px 16px;
    border-radius: 11px 11px 0 0;
  }

  .subsection {
    margin-left: -16px;
    margin-right: -16px;
    padding-left: 16px;
    padding-right: 16px;
  }

  .subsection .subsection {
    margin-left: 0;
    margin-right: 0;
    padding-left: 0;
    padding-right: 0;
  }


  /* The appbar's clusters stack rather than overflowing the viewport. */
  .appbar {
    grid-template-columns: minmax(0, 1fr);
    justify-items: stretch;
    gap: 12px;
    padding: 12px 16px;
  }

  .appbar-left {
    flex-wrap: wrap;
  }

  .appbar-actions {
    justify-self: stretch;
  }

  .answer-picker-wrap {
    flex: 1 1 100%;
  }



  .brand {
    padding-right: 0;
    border-right: 0;
  }

  .appbar-title h1,
  .appbar-title p {
    white-space: normal;
  }

  /* Let the action row wrap so the full-width Download button drops to its
     own line instead of overflowing the viewport (horizontal scroll). */
  .appbar-actions {
    flex-wrap: wrap;
  }

  .appbar-actions .primary-button {
    flex: 1 0 100%;
  }

  .primary-button {
    width: 100%;
  }

  .field-grid {
    grid-template-columns: minmax(0, 1fr);
  }
}

/* --- The template's own layout breaks ------------------------------------
   HotDocs dialogs can carry horizontal dividers (optionally captioned) and
   vertical spacing. They are the author saying "these questions are one group
   and those are another", and rendering them is what keeps a forty-question
   dialog readable. Full-bleed so the rule spans the card like a section break. */
.dialog-divider {
  margin: 26px -24px 22px;
  border-top: 1px solid var(--line);
}

/* A captioned divider sets its own display, which would beat the UA's [hidden]
   rule when a break is pruned for having nothing on one side of it. */
.dialog-divider[hidden],
.dialog-spacer[hidden] {
  display: none;
}

.dialog-divider-captioned {
  display: flex;
  align-items: center;
  justify-content: center;
  height: 0;
  border-top: 1px solid var(--line);
}

.dialog-divider-caption {
  padding: 0 12px;
  background: var(--panel);
  color: var(--muted);
  font-size: 12px;
  font-weight: 700;
  letter-spacing: 0.02em;
}

.dialog-spacer {
  height: 10px;
}

/* --- Show / hide animation for conditional questions ---------------------
   The form only gets .interview-ready after the first /interview round-trip has
   settled (see app.js), so the large block of questions the interview hides on
   load doesn't flash in and straight back out on the way there. */
@media (prefers-reduced-motion: no-preference) {
  /* A field is a cell in a wrapping row, so its neighbours reflow around it
     horizontally: it fades and lifts rather than collapsing its height. The
     discrete `display` step is what keeps it painted while it fades out. */
  .interview-ready .field {
    transition:
      opacity 170ms ease,
      translate 170ms ease,
      display 170ms allow-discrete;
  }

  .interview-ready .field[hidden] {
    opacity: 0;
    translate: 0 -6px;
  }

  @starting-style {
    .interview-ready .field:not([hidden]) {
      opacity: 0;
      translate: 0 -6px;
    }
  }

  /* A repeat section is a full-width block, so it genuinely expands and
     collapses. `interpolate-size` (set on :root) is what lets that height
     animate to and from `auto`; without it the section simply snaps, which is
     the behaviour this replaces. */
  .interview-ready .repeat-section {
    overflow: hidden;
    transition:
      opacity 220ms ease,
      height 220ms cubic-bezier(0.4, 0, 0.2, 1),
      margin-top 220ms cubic-bezier(0.4, 0, 0.2, 1),
      padding-top 220ms cubic-bezier(0.4, 0, 0.2, 1),
      padding-bottom 220ms cubic-bezier(0.4, 0, 0.2, 1),
      border-width 220ms cubic-bezier(0.4, 0, 0.2, 1),
      display 220ms allow-discrete;
  }

  /* The panel's own padding and border have to collapse too: with
     border-box sizing they are a floor under `height`, so animating height
     alone stopped the block a couple of dozen pixels short of gone. */
  .interview-ready .repeat-section[hidden] {
    opacity: 0;
    height: 0;
    margin-top: 0;
    padding-top: 0;
    padding-bottom: 0;
    border-width: 0;
  }

  @starting-style {
    .interview-ready .repeat-section:not([hidden]) {
      opacity: 0;
      height: 0;
      margin-top: 0;
      padding-top: 0;
      padding-bottom: 0;
      border-width: 0;
    }
  }

  /* Rows added to a repeat section slide in the same way. */
  .interview-ready .repeat-row {
    transition: opacity 200ms ease, translate 200ms ease;
  }

  @starting-style {
    .interview-ready .repeat-row {
      opacity: 0;
      translate: 0 -6px;
    }
  }
}

/* Request intake (upload / paste to pre-fill) */
.intake-card {
  margin: 0;
  padding: 0 24px 24px;
  border: 1px solid var(--line);
  border-radius: 14px;
  background: var(--panel);
}
.intake-card > h2 {
  font-size: 17px;
  line-height: 19.5px;
  font-weight: 700;
  letter-spacing: 0.01em;
}
.intake-hint {
  margin: 0 0 10px;
  color: var(--muted);
  font-size: 0.82rem;
}

/* One box for both ways in: the paste area is itself the drop target, so a
   dropped file and pasted text land in the same place. */
.intake-drop {
  position: relative;
  display: flex;
}

.intake-text {
  width: 100%;
  min-height: 72px;
  padding: 10px 12px;
  border: 1px solid var(--field-border);
  border-radius: 10px;
  background: var(--input-bg);
  color: var(--ink);
  font: inherit;
  font-size: 14px;
  resize: vertical;
  transition: border-color 120ms ease, background 120ms ease, box-shadow 120ms ease, min-height 120ms ease;
}
.intake-text:focus {
  outline: none;
  border-color: var(--accent);
  background: var(--panel);
  box-shadow: 0 0 0 3px var(--focus-ring);
}
.intake-text::placeholder {
  color: var(--muted);
}
/* Once the box actually has text, give it more room. */
.intake-text.has-content {
  min-height: 136px;
}

/* Shown over the box only while a file is being dragged onto it, so the box
   reads as a plain text field the rest of the time. */
.intake-drop-hint {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 10px;
  border: 1.5px dashed var(--accent);
  border-radius: 10px;
  background: var(--drag);
  color: var(--accent-dark);
  font-size: 13px;
  font-weight: 700;
  opacity: 0;
  visibility: hidden;
  transition: opacity 120ms ease;
}
.intake-drop.is-dragover .intake-drop-hint {
  opacity: 1;
  visibility: visible;
}
.intake-drop-hint svg {
  width: 20px;
  height: 20px;
}

/* Choose file + chosen name on the left, Load request centred on the card. */
.intake-actions {
  display: flex;
  align-items: center;
  gap: 12px;
  margin-top: 12px;
}
.intake-file-pick,
.intake-actions-balance {
  display: flex;
  align-items: center;
  gap: 12px;
  flex: 1 1 0;
  min-width: 0;
}

/* The real file input is hidden inside this label, which doubles as a button. */
.intake-browse,
.intake-actions .secondary-button {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 128px;
  min-height: 34px;
  border: 1px solid var(--field-border);
  border-radius: 8px;
  padding: 7px 14px;
  background: var(--panel);
  color: var(--accent-dark);
  font-size: 13px;
  font-weight: 700;
  cursor: pointer;
  transition: background 120ms ease, border-color 120ms ease;
}
.intake-actions .secondary-button:hover,
.intake-browse:hover {
  background: var(--soft);
  border-color: var(--accent);
}
.intake-file {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}
.intake-filename {
  max-width: 320px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  color: var(--muted);
  font-size: 13px;
}
.intake-filename.has-file {
  color: var(--ink);
  font-weight: 600;
}

.intake-warnings {
  margin-top: 10px;
  color: var(--warn);
  font-size: 0.85rem;
}
.intake-warnings ul {
  margin: 6px 0 0;
  padding-left: 18px;
}

/* Appbar actions: the "Assemble invoice?" toggle next to Download DOCX. */
.appbar-actions {
  display: flex;
  align-items: center;
  justify-content: flex-end;
  justify-self: end;
  gap: 16px;
  min-width: 0;
}
.assemble-toggle {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  color: var(--muted, #6d746f);
  font-size: 0.85rem;
  white-space: nowrap;
  cursor: pointer;
}
.assemble-toggle input {
  width: 16px;
  height: 16px;
  accent-color: var(--accent, #0f766e);
}

/* Invoice "missing fields" modal. */
.modal-overlay {
  position: fixed;
  inset: 0;
  background: rgba(20, 30, 28, 0.45);
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 24px;
  z-index: 50;
}
.modal {
  background: var(--panel, #fff);
  border: 1px solid var(--line, #d9ded8);
  border-radius: 12px;
  box-shadow: 0 18px 50px rgba(0, 0, 0, 0.25);
  width: min(520px, 100%);
  max-height: 85vh;
  overflow: auto;
  overscroll-behavior: none;
  padding: 22px 24px;
}
.modal h2 {
  margin: 0 0 14px;
  font-size: 1.1rem;
  color: var(--ink, #202322);
}
.modal-warnings {
  margin: 0 0 16px;
  padding-left: 18px;
  color: var(--warn, #8a3b12);
  font-size: 0.82rem;
}
/* The save prompt's one-line heads-up ("already in the library"). Empty most
   of the time, so it takes no room until it has something to say. */
.modal-note {
  margin: 10px 0 0;
  color: var(--warn, #8a3b12);
  font-size: 0.82rem;
}
.modal-note:empty {
  display: none;
}
.modal-actions {
  display: flex;
  justify-content: flex-end;
  gap: 10px;
  margin-top: 20px;
}


/* --- Custom select --------------------------------------------------------
   The native <select> stays in the DOM as the answer's source of truth (see
   app.js) but is taken out of sight, because the one thing a stylesheet cannot
   reach is the OS-drawn popup. The trigger below is a plain button styled as a
   field, and the menu is a popover so it can escape the overflow clip an
   animating repeat section puts on its contents. */
.select {
  position: relative;
  width: 100%;
}

.select > select {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}

.select-trigger {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  width: 100%;
  min-height: 34px;
  padding: 7px 10px;
  border: 1px solid var(--field-border);
  border-radius: 8px;
  background: var(--input-bg);
  color: var(--ink);
  font-size: 14px;
  font-weight: 400;
  text-align: left;
  cursor: pointer;
  transition: border-color 120ms ease, box-shadow 120ms ease, background 120ms ease;
}

.select-trigger:hover:not(:disabled) {
  border-color: var(--field-border-strong);
}

.select-trigger:focus-visible,
.select-trigger[aria-expanded="true"] {
  outline: none;
  border-color: var(--accent);
  background: var(--panel);
  box-shadow: 0 0 0 3px var(--focus-ring);
}

.select-trigger:disabled {
  cursor: default;
}

.select-value {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.select-value.is-placeholder {
  color: var(--muted);
}

/* Drawn rather than an image so it inherits the theme's text colour. */
.select-arrow {
  flex: 0 0 auto;
  width: 8px;
  height: 8px;
  margin-right: 2px;
  border-right: 1.5px solid var(--muted);
  border-bottom: 1.5px solid var(--muted);
  rotate: 45deg;
  translate: 0 -2px;
}

.select-menu {
  position: fixed;
  inset: auto;
  /* Fallback only -- positionMenu() measures the menu and sets the real cap, so
     a list that fits on screen shows in full rather than scrolling. */
  max-height: 75vh;
  max-width: min(420px, calc(100vw - 16px));
  /* The MENU holds still and the LIST inside it scrolls, so a pinned search box
     stays put while results move under it. (Both scrolling nests one scroller
     inside another, which reads as "the list won't scroll".) */
  display: flex;
  flex-direction: column;
  overflow: hidden;
  overscroll-behavior: contain;
  margin: 0;
  padding: 4px;
  border: 1px solid var(--line);
  border-radius: 10px;
  background: var(--panel);
  box-shadow: 0 12px 32px rgba(0, 0, 0, 0.16), 0 2px 6px rgba(0, 0, 0, 0.06);
  color: var(--ink);
}

.select-menu:not(:popover-open) {
  display: none;
}

.select-option {
  padding: 7px 10px;
  border-radius: 6px;
  font-size: inherit;
  line-height: 1.35;
  cursor: pointer;
  outline: none;
}

.select-option:hover,
.select-option:focus {
  background: var(--soft);
}

.select-option.is-selected {
  color: var(--accent-dark);
  font-weight: 700;
}

.select-option-empty {
  color: var(--muted);
}

/* Section heading inside a menu, from an <optgroup> label. */
.select-group {
  padding: 8px 10px 4px;
  color: var(--muted);
  font-size: 0.82em;
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
}

.select-group ~ .select-group {
  margin-top: 5px;
  padding-top: 9px;
  border-top: 1px solid var(--line);
}

/* The deed picker in the app bar is the same control at a smaller size. */
.deed-select ~ .select-trigger,
.brand .select-trigger {
  min-height: 0;
  padding: 4px 8px;
  border-radius: 6px;
  font-size: 12px;
}

/* Light/dark theme toggle in the topbar. */
.theme-toggle {
  display: inline-grid;
  place-items: center;
  width: 34px;
  height: 34px;
  flex: 0 0 auto;
  border: 1px solid var(--field-border);
  border-radius: 8px;
  background: var(--panel);
  color: var(--ink);
  font-size: 16px;
  line-height: 1;
  cursor: pointer;
  transition: background 120ms ease, border-color 120ms ease;
}
.theme-toggle:hover {
  background: var(--soft);
  border-color: var(--accent);
}

/* ---- Answer picker --------------------------------------------------------
   Beside the template name, because choosing the client is the first thing you
   do. It is allowed to shrink but keeps a usable minimum, and the template name
   keeps its own basis so the two never squeeze each other to nothing. */
.answer-picker-wrap {
  display: flex;
  align-items: center;
  gap: 8px;
  /* A floor, so the picker never shrinks to the point where a client name is
     unreadable -- the title wraps instead of stealing from it. */
  min-width: 170px;
  flex: 0 1 clamp(170px, 14vw, 240px);
}

/* Said in the bar where the picker would have been, so the absence has a reason
   attached to it rather than looking like an empty firm library. */
.answer-picker-error {
  margin: 0;
  font-size: 12px;
  line-height: 1.3;
  color: var(--warn);
}

/* The picker is enhanced into the same custom control as every other dropdown
   (see enhanceSelect), so only its size is set here. */
.answer-picker-wrap .select {
  width: 100%;
}

/* The one control that cannot grow to fit: widening it would push the document
   actions off the bar. It ellipsizes and carries the full name as a tooltip. */
.answer-picker-wrap .select-value {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* What opening an answer set says (see showAnswerNotice): status text beside the
   picker, and a toast in the top right for errors and warnings. Both fixed and
   laid over the page -- never in its flow -- so opening a set cannot move the
   sections; the script sets left/top. Above the sticky header (20), below the
   modal overlay (50). visibility rides along with opacity so a faded-out notice
   cannot be clicked or read out, and waits for the fade to finish before it
   hides. */
.answer-status,
.answer-toast {
  position: fixed;
  top: 0;
  left: 0;
  z-index: 30;
  font-size: 13px;
  line-height: 1.4;
  opacity: 0;
  visibility: hidden;
  transition: opacity 400ms ease, visibility 0s linear 400ms;
}

.answer-status.is-visible,
.answer-toast.is-visible {
  opacity: 1;
  visibility: visible;
  transition: opacity 250ms ease;
}

/* Just text, part of the bar. One line: placeAnswerStatus caps the width at the
   room left beside the title, and a long client name ellipsizes into it. */
.answer-status {
  color: var(--muted);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* The phone layout has no room beside the picker, and text with no box behind
   it would sit on top of the form -- so there it gets the toast's card. */
.answer-status.is-boxed,
.answer-toast {
  max-width: min(420px, calc(100vw - 28px));
  padding: 8px 12px;
  border: 1px solid var(--line);
  border-radius: 10px;
  background: var(--panel);
  box-shadow: 0 8px 24px rgba(0, 0, 0, 0.14);
  color: var(--ink);
}

.answer-status.is-boxed {
  white-space: normal;
}

.answer-toast {
  display: flex;
  align-items: flex-start;
  gap: 10px;
  max-height: 60vh;
  overflow: auto;
  overscroll-behavior: none;
  /* Something went wrong: the edge says so before the words do. */
  border-left: 3px solid var(--warn);
}

.answer-toast-body {
  min-width: 0;
}

.answer-toast-line {
  margin: 0;
}

.answers-warnings {
  margin: 4px 0 0;
  padding-left: 18px;
  color: var(--muted);
}

.answer-toast-close {
  flex: 0 0 auto;
  margin: -2px -4px 0 0;
  padding: 0 4px;
  border: 0;
  background: none;
  color: var(--muted);
  font-size: 18px;
  line-height: 1;
  cursor: pointer;
}

.answer-toast-close:hover {
  color: var(--ink);
}

/* ---- Searchable dropdown ---------------------------------------------------
   A list of every client the firm has minutes for cannot be scanned, only
   searched, so a menu past a dozen options gets a filter box pinned above a
   scrolling result list. */
.select-search {
  /* A flex item outside the scrolling list, so it needs no sticky positioning. */
  flex: 0 0 auto;
  box-sizing: border-box;
  width: 100%;
  margin: 0;
  padding: 9px 12px;
  border: 0;
  border-bottom: 1px solid var(--line);
  background: var(--panel);
  color: inherit;
  font: inherit;
  font-size: 0.9rem;
}

.select-search:focus {
  outline: none;
  box-shadow: inset 0 -2px 0 var(--accent);
}

.select-search::-webkit-search-cancel-button {
  cursor: pointer;
}

.select-list {
  /* positionMenu caps the menu's height; this takes whatever is left under the
     search box and scrolls within it. min-height:0 is what lets a flex child
     shrink below its content and actually scroll. */
  flex: 1 1 auto;
  min-height: 0;
  overflow-y: auto;
  /* none, not contain: still keeps the page from scrolling behind the list,
     and also drops the bounce at the list's ends. */
  overscroll-behavior: none;
}

.select-empty {
  padding: 10px 12px;
  color: var(--muted);
  font-size: 0.9rem;
}

/* ---- Sign-in ---------------------------------------------------------------
   One centred card. Deliberately plain: this is a door, not a page. */
.signin {
  display: flex;
  flex-direction: column;
  gap: 10px;
  width: min(360px, calc(100vw - 32px));
  margin: 12vh auto;
  padding: 28px;
  border: 1px solid var(--line);
  border-radius: 14px;
  background: var(--panel);
  box-shadow: 0 12px 32px rgba(0, 0, 0, 0.08);
}

.signin .brand {
  padding-right: 0;
  border-right: 0;
  gap: 10px;
}

.signin-lede {
  margin: 0 0 8px;
  color: var(--muted);
  font-size: 0.9rem;
}

.signin label {
  font-size: 0.8rem;
  font-weight: 600;
}

.signin input {
  padding: 9px 11px;
  border: 1px solid var(--line);
  border-radius: 8px;
  background: var(--panel);
  color: inherit;
  font: inherit;
}

.signin input:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 1px;
}

.signin .primary-button,
.signin .secondary-button {
  margin-top: 6px;
}

.signin-note {
  margin: 4px 0 0;
  color: var(--muted);
  font-size: 0.85rem;
}

.signin-note:empty {
  display: none;
}
