/* =========================================================================
   Ronnie Trammell's Assistant - the website chat widget.

   POSITIONING, WHICH IS THE PART THAT MATTERS
   The accessibility widget owns the bottom right corner of every page. It is
   configured in templates/layout.php with position bottom-right, a 20px
   offset, a 52px button and z-index 100000, and it must stay reachable at
   every width, on every page, at every zoom level.

   So this file does not guess. It declares the geometry as custom properties,
   assumes those defaults, and assets/js/chat.js MEASURES the accessibility
   button in its rendered state and writes the real numbers back into the same
   properties. If that widget ever moves, changes size, or is replaced, the
   chat launcher follows it without anybody editing this file.

   Two consequences of that arrangement are deliberate:

     1. The chat launcher sits ABOVE the accessibility button, never beside it.
        Side by side is the arrangement that breaks first on a narrow screen.
     2. The open panel also stops short of it. On a phone the panel is a bottom
        sheet whose lower edge clears the accessibility button, so that button
        is tappable while the chat is open rather than buried under it.

   Z-INDEX. The launcher and panel sit at 99990, one below the accessibility
   widget's 100000. That ordering is intentional: if the two ever did overlap,
   the accessibility tool wins.

   MOTION. This site deliberately ignores the operating system's reduced-motion
   preference and puts motion under the accessibility widget's Pause Motion
   tool instead - see the note in templates/layout.php. The typing indicator
   below is the one narrow exception, because it is a functional status
   indicator rather than decoration, and a three-dot animation is exactly what
   the preference exists for. Pause Motion still stops it too, because that
   tool sets animation:none on everything.
   ====================================================================== */

:root{
  /* Defaults, replaced at runtime by chat.js from the real element. */
  --tr-a11y-right: 20px;
  --tr-a11y-bottom: 20px;
  --tr-a11y-size: 52px;
  --tr-widget-gap: 14px;

  --tr-chat-size: 54px;
  --tr-chat-z: 99990;

  /* The stacked position: clear of the accessibility button, and clear of the
     phone's home indicator. env() resolves to 0 where it is unsupported. */
  --tr-chat-bottom: calc(
      var(--tr-a11y-bottom)
    + var(--tr-a11y-size)
    + var(--tr-widget-gap)
    + env(safe-area-inset-bottom, 0px)
  );
  --tr-chat-right: calc(var(--tr-a11y-right) + env(safe-area-inset-right, 0px));
}

/* --- Launcher ---------------------------------------------------------- */

.trchat-launch{
  position: fixed;
  right: var(--tr-chat-right);
  bottom: var(--tr-chat-bottom);
  z-index: var(--tr-chat-z);

  /* 54px square, and never below the 44px minimum tap target even if a
     future edit shrinks the variable. */
  width: var(--tr-chat-size);
  height: var(--tr-chat-size);
  min-width: 44px;
  min-height: 44px;

  display: grid;
  place-items: center;
  padding: 0;
  border: 2px solid rgba(255,255,255,.9);
  border-radius: 16px;                 /* rounded square, not a bubble */
  background: linear-gradient(150deg, var(--brand, #1b6d9f), var(--brand-deep, #0c4468));
  color: #fff;
  cursor: pointer;
  box-shadow: 0 10px 26px rgba(6,26,48,.32), 0 2px 0 rgba(255,255,255,.14) inset;
  transition: transform .16s ease, box-shadow .16s ease, background .16s ease;

  /* Held back until the opening curtain has finished. chat.js adds is-ready. */
  opacity: 0;
  visibility: hidden;
}
.trchat-launch.is-ready{ opacity: 1; visibility: visible; }
.trchat-launch:hover{
  background: linear-gradient(150deg, var(--brand-soft, #3390c2), var(--brand, #1b6d9f));
  transform: translateY(-2px);
  box-shadow: 0 14px 30px rgba(6,26,48,.38);
}
.trchat-launch:focus-visible{
  outline: 3px solid var(--accent, #d13a92);
  outline-offset: 3px;
}
.trchat-launch svg{ width: 26px; height: 26px; fill: currentColor; pointer-events: none; }

/* The unread pip, shown once per session when the assistant has not been
   opened. Small, static, and gone the moment it is used. */
.trchat-launch .trchat-pip{
  position: absolute; top: -3px; right: -3px;
  width: 13px; height: 13px; border-radius: 50%;
  background: var(--accent, #d13a92);
  border: 2px solid #fff;
}
.trchat-launch[data-seen="1"] .trchat-pip{ display: none; }

/* While the panel is open the launcher is gone rather than underneath it. */
body.trchat-open .trchat-launch{ opacity: 0; visibility: hidden; }

/* --- Panel ------------------------------------------------------------- */

.trchat-panel{
  position: fixed;
  right: var(--tr-chat-right);
  bottom: var(--tr-chat-bottom);
  z-index: var(--tr-chat-z);

  width: min(392px, calc(100vw - 2rem));
  max-height: min(640px, calc(100vh - var(--tr-chat-bottom) - 1.25rem));

  display: flex;
  flex-direction: column;
  overflow: hidden;

  background: var(--paper, #fff);
  border: 1px solid var(--line, #d8e4ee);
  border-radius: 14px;
  box-shadow: 0 26px 64px rgba(6,26,48,.34);

  opacity: 0;
  visibility: hidden;
  transform: translateY(12px) scale(.985);
  transform-origin: bottom right;
  transition: opacity .18s ease, transform .18s ease, visibility .18s;
}
.trchat-panel.is-open{
  opacity: 1;
  visibility: visible;
  transform: none;
}

/* --- Header ------------------------------------------------------------ */

.trchat-head{
  display: flex;
  align-items: center;
  gap: .7rem;
  padding: .8rem .85rem .8rem 1rem;
  background: linear-gradient(140deg, var(--brand-deep, #0c4468), var(--brand, #1b6d9f));
  color: #fff;
  flex: none;
}
.trchat-head img{
  width: 34px; height: 34px; flex: none;
  border-radius: 6px; background: #fff; padding: 3px; object-fit: contain;
}
.trchat-head-text{ min-width: 0; line-height: 1.25; }
.trchat-head-text b{ display: block; font-size: 1rem; font-weight: 700; }
.trchat-head-text span{
  display: block; font-size: .78rem; color: #cfe6f4;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.trchat-head-actions{ margin-left: auto; display: flex; gap: .25rem; }
.trchat-head button{
  width: 40px; height: 40px;
  display: grid; place-items: center;
  background: rgba(255,255,255,.12);
  border: 1px solid rgba(255,255,255,.22);
  border-radius: 8px;
  color: #fff; cursor: pointer;
  font-size: 1.1rem; line-height: 1;
  transition: background .15s ease;
}
.trchat-head button:hover{ background: rgba(255,255,255,.24); }
.trchat-head button:focus-visible{ outline: 3px solid var(--accent, #d13a92); outline-offset: 2px; }
.trchat-head button svg{ width: 16px; height: 16px; fill: currentColor; }

/* --- Transcript -------------------------------------------------------- */

.trchat-log{
  flex: 1 1 auto;
  overflow-y: auto;
  overscroll-behavior: contain;        /* scrolling here never scrolls the page */
  -webkit-overflow-scrolling: touch;
  padding: 1rem .95rem .5rem;
  background: var(--cream, #f2f7fb);
  display: flex;
  flex-direction: column;
  gap: .7rem;
}

.trchat-msg{
  max-width: 88%;
  padding: .68rem .85rem;
  border-radius: 12px;
  font-size: .96rem;
  line-height: 1.5;
  overflow-wrap: anywhere;             /* a pasted URL cannot widen the panel */
}
/* Contrast checked against the backgrounds they sit on, both directions. */
.trchat-msg--bot{
  align-self: flex-start;
  background: var(--paper, #fff);
  color: var(--ink, #14263a);
  border: 1px solid var(--line, #d8e4ee);
  border-bottom-left-radius: 4px;
}
.trchat-msg--me{
  align-self: flex-end;
  background: var(--brand-deep, #0c4468);
  color: #fff;
  border-bottom-right-radius: 4px;
}
.trchat-msg p{ margin: 0 0 .55rem; }
.trchat-msg p:last-child{ margin-bottom: 0; }
.trchat-msg ul,
.trchat-msg ol{ margin: .1rem 0 .55rem; padding-left: 1.15rem; }
.trchat-msg li{ margin-bottom: .28rem; }
.trchat-msg a{ color: var(--brand, #1b6d9f); font-weight: 700; }
.trchat-msg--me a{ color: #fff; text-decoration: underline; }
.trchat-msg a:focus-visible{ outline: 2px solid var(--accent, #d13a92); outline-offset: 2px; }

/* --- Typing indicator -------------------------------------------------- */

.trchat-typing{
  align-self: flex-start;
  display: inline-flex;
  gap: 5px;
  padding: .8rem .9rem;
  background: var(--paper, #fff);
  border: 1px solid var(--line, #d8e4ee);
  border-radius: 12px;
  border-bottom-left-radius: 4px;
}
.trchat-typing i{
  width: 7px; height: 7px; border-radius: 50%;
  background: var(--muted, #5b7085);
  animation: trchatDot 1.25s infinite ease-in-out;
}
.trchat-typing i:nth-child(2){ animation-delay: .16s; }
.trchat-typing i:nth-child(3){ animation-delay: .32s; }
@keyframes trchatDot{
  0%, 70%, 100%{ transform: translateY(0); opacity: .38; }
  35%{ transform: translateY(-5px); opacity: 1; }
}
/* The one place on this site that honours the OS preference - see the note at
   the top of this file. A status indicator that pulses is exactly what the
   setting is for, and a static row of dots still says "working". */
@media (prefers-reduced-motion: reduce){
  .trchat-typing i{ animation: none; opacity: .55; }
  .trchat-panel{ transition: none; }
  .trchat-launch{ transition: none; }
}

/* --- Quick actions ----------------------------------------------------- */

.trchat-chips{
  flex: none;
  display: flex;
  flex-wrap: wrap;
  gap: .4rem;
  padding: .55rem .95rem .3rem;
  background: var(--cream, #f2f7fb);
}
.trchat-chips:empty{ display: none; }
.trchat-chip{
  min-height: 34px;
  padding: .34rem .7rem;
  background: var(--paper, #fff);
  border: 1px solid var(--brand-soft, #3390c2);
  border-radius: 999px;
  color: var(--brand-deep, #0c4468);
  font: inherit;
  font-size: .84rem;
  font-weight: 600;
  cursor: pointer;
  transition: background .14s ease, color .14s ease;
}
.trchat-chip:hover{ background: var(--brand, #1b6d9f); color: #fff; }
.trchat-chip:focus-visible{ outline: 3px solid var(--accent, #d13a92); outline-offset: 2px; }

/* --- Composer ---------------------------------------------------------- */

.trchat-form{
  flex: none;
  display: flex;
  align-items: flex-end;
  gap: .5rem;
  padding: .6rem .7rem;
  background: var(--paper, #fff);
  border-top: 1px solid var(--line, #d8e4ee);
}
.trchat-form textarea{
  flex: 1 1 auto;
  /* Two lines high, so a placeholder or a typed line that wraps on a narrow
     phone is never clipped at the bottom of the box. */
  min-height: 48px;
  max-height: 120px;
  padding: .62rem .7rem;
  border: 1px solid var(--line, #d8e4ee);
  border-radius: 9px;
  font: inherit;
  font-size: 1rem;                     /* 16px: stops iOS zooming on focus */
  line-height: 1.35;
  color: var(--ink, #14263a);
  background: #fff;
  resize: none;
}
.trchat-form textarea:focus-visible{
  outline: 3px solid var(--accent, #d13a92);
  outline-offset: 1px;
  border-color: var(--brand, #1b6d9f);
}
.trchat-send{
  flex: none;
  width: 44px; height: 44px;
  display: grid; place-items: center;
  background: var(--accent, #d13a92);
  border: 0; border-radius: 9px;
  color: #fff; cursor: pointer;
  transition: background .14s ease;
}
.trchat-send:hover:not(:disabled){ background: var(--accent-dark, #a52c72); }
.trchat-send:disabled{ background: var(--muted, #5b7085); cursor: not-allowed; opacity: .65; }
.trchat-send:focus-visible{ outline: 3px solid var(--brand-deep, #0c4468); outline-offset: 2px; }
.trchat-send svg{ width: 19px; height: 19px; fill: currentColor; }

/* --- Guided quote form ------------------------------------------------- */

.trchat-lead{
  align-self: stretch;
  max-width: 100%;
  background: var(--paper, #fff);
  border: 1px solid var(--brand-soft, #3390c2);
  border-radius: 12px;
  padding: .85rem;
}
.trchat-lead h3{
  margin: 0 0 .15rem;
  font-size: 1rem;
  color: var(--brand-deep, #0c4468);
}
.trchat-lead p.hint{ margin: 0 0 .7rem; font-size: .84rem; color: var(--muted, #5b7085); }
.trchat-lead label{
  display: block;
  margin: 0 0 .2rem;
  font-size: .82rem;
  font-weight: 700;
  color: var(--brand-deep, #0c4468);
}
.trchat-lead .row{ margin-bottom: .6rem; }
.trchat-lead input[type=text],
.trchat-lead input[type=email],
.trchat-lead input[type=tel],
.trchat-lead select,
.trchat-lead textarea{
  width: 100%;
  min-height: 42px;
  padding: .5rem .6rem;
  border: 1px solid var(--line, #d8e4ee);
  border-radius: 8px;
  font: inherit;
  font-size: 1rem;
  color: var(--ink, #14263a);
  background: #fff;
}
.trchat-lead textarea{ min-height: 66px; resize: vertical; }
.trchat-lead .two{ display: grid; grid-template-columns: 1fr 1fr; gap: .5rem; }
.trchat-lead .check{ display: flex; gap: .5rem; align-items: flex-start; margin-bottom: .7rem; }
.trchat-lead .check input{ margin-top: .22rem; width: 18px; height: 18px; flex: none; }
.trchat-lead .check label{ font-weight: 400; font-size: .84rem; color: var(--muted, #5b7085); }
.trchat-lead .err{
  display: block; margin-top: .2rem;
  font-size: .8rem; font-weight: 700; color: #b3261e;
}
.trchat-lead .actions{ display: flex; gap: .5rem; }
.trchat-lead .actions button{
  min-height: 44px;
  padding: .5rem 1rem;
  border-radius: 8px;
  font: inherit; font-weight: 700;
  cursor: pointer;
}
.trchat-lead .actions .go{ background: var(--accent, #d13a92); border: 0; color: #fff; flex: 1; }
.trchat-lead .actions .go:hover{ background: var(--accent-dark, #a52c72); }
.trchat-lead .actions .cancel{
  background: #fff; border: 1px solid var(--line, #d8e4ee); color: var(--brand-deep, #0c4468);
}
.trchat-lead .actions button:focus-visible{ outline: 3px solid var(--brand-deep, #0c4468); outline-offset: 2px; }
/* The honeypot. Off-screen rather than display:none, which some bots skip. */
.trchat-lead .hp{
  position: absolute; left: -9999px; top: auto;
  width: 1px; height: 1px; overflow: hidden;
}

/* --- "When is good to call?" -------------------------------------------
   Four tappable choices rather than a text box, because "best time to call"
   typed freehand produces "whenever" far more often than it produces a time.
   The free-text line underneath takes anybody whose answer is a real one. */
.trchat-lead fieldset.trcb-when{
  margin: 0 0 .6rem;
  padding: 0;
  border: 0;
}
.trchat-lead fieldset.trcb-when legend{
  padding: 0;
  margin: 0 0 .35rem;
  font-size: .82rem;
  font-weight: 700;
  color: var(--brand-deep, #0c4468);
}
.trchat-lead .trcb-times{
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: .3rem .5rem;
  margin-bottom: .4rem;
}
/* These labels wrap their own checkbox, so the block-level bold styling that
   every other label in this form wants is exactly wrong here. */
.trchat-lead .trcb-times label{
  display: flex;
  align-items: center;
  gap: .45rem;
  margin: 0;
  min-height: 34px;
  font-size: .88rem;
  font-weight: 400;
  color: var(--ink, #14263a);
  cursor: pointer;
}
.trchat-lead .trcb-times input{
  width: 18px; height: 18px;
  flex: none;
  margin: 0;
  accent-color: var(--brand, #1a3060);
}
.trchat-lead .trcb-times label:focus-within{
  outline: 2px solid var(--brand-deep, #0c4468);
  outline-offset: 2px;
  border-radius: 5px;
}
/* The hint under "what is it about" sits inside a .row, where the rule above
   only covers a hint that is a direct paragraph of the form. */
.trchat-lead .row .hint{
  display: block;
  margin-top: .22rem;
  font-size: .78rem;
  font-weight: 400;
  color: var(--muted, #5b7085);
}

/* --- Footer ------------------------------------------------------------ */

/* Two items on one row, and the credit is the one that must never break.
   "Powered by Pro Star AI" wrapping across two lines - which it did, because
   both halves were free to shrink equally - reads as a layout fault rather
   than as a byline. So the credit is fixed width and nowrap, and the privacy
   note is the flexible half that gives way. On a panel too narrow for both,
   the credit drops onto its own line still intact rather than splitting. */
.trchat-foot{
  flex: none;
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  justify-content: space-between;
  gap: .2rem .7rem;
  padding: .5rem .8rem calc(.5rem + env(safe-area-inset-bottom, 0px));
  background: var(--cream, #f2f7fb);
  border-top: 1px solid var(--line, #d8e4ee);
  font-size: .74rem;
  line-height: 1.4;
  color: var(--muted, #5b7085);
}
/* The two halves are not the same kind of text and should not look it.
   The privacy note is fine print and stays quiet. The credit is a byline, and
   at 11.8px in muted grey it was being missed entirely - Chad looked for it in
   the panel and did not see it. It is now a step larger and a step darker,
   with the name itself in brand blue and bold. Still the smallest thing in the
   panel; just no longer invisible. */
.trchat-foot-note{ flex: 1 1 12rem; min-width: 0; }
.trchat-foot-by{
  flex: 0 0 auto;
  white-space: nowrap;
  font-size: .82rem;
  color: var(--ink, #14263a);
}
.trchat-foot a{ color: var(--brand, #1b6d9f); font-weight: 700; white-space: nowrap; }
.trchat-foot-by a{ text-decoration: underline; text-underline-offset: 2px; }
.trchat-foot-by a:hover{ color: var(--accent, #d13a92); }
.trchat-foot a:focus-visible{ outline: 2px solid var(--accent, #d13a92); outline-offset: 2px; }

/* Screen-reader only, matching the site's own convention. */
.trchat-sr{
  position: absolute; width: 1px; height: 1px;
  margin: -1px; padding: 0; overflow: hidden;
  clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}

/* --- Phones ------------------------------------------------------------
   A bottom sheet with real margins, NOT a takeover. The lower edge still
   clears the accessibility button, so that button stays tappable while the
   assistant is open. */
@media (max-width: 560px){
  :root{ --tr-chat-size: 50px; }

  .trchat-panel{
    left: .5rem;
    right: .5rem;
    width: auto;
    bottom: var(--tr-chat-bottom);
    /* dvh where it is supported, so the iOS toolbar appearing does not crop
       the composer off the bottom of the sheet. */
    max-height: min(78vh, calc(100vh - var(--tr-chat-bottom) - 1rem));
    border-radius: 16px;
    transform-origin: bottom center;
  }
  .trchat-msg{ max-width: 92%; }
  .trchat-lead .two{ grid-template-columns: 1fr; }
}
@supports (height: 100dvh){
  @media (max-width: 560px){
    .trchat-panel{ max-height: min(78dvh, calc(100dvh - var(--tr-chat-bottom) - 1rem)); }
  }
}

/* Short landscape phones: the sheet gets whatever is left and scrolls. */
@media (max-height: 460px){
  .trchat-panel{ max-height: calc(100vh - var(--tr-chat-bottom) - .5rem); }
}

/* --- High contrast and forced colours ---------------------------------- */
@media (forced-colors: active){
  .trchat-launch,
  .trchat-panel,
  .trchat-msg,
  .trchat-chip{ border: 1px solid CanvasText; }
  .trchat-launch svg,
  .trchat-send svg{ fill: CanvasText; }
}

/* --- Print -------------------------------------------------------------
   A chat transcript is not part of the document. */
@media print{
  .trchat-launch,
  .trchat-panel{ display: none !important; }
}

/* ==========================================================================
   CONTRAST: white on brand gold
   ==========================================================================
   The panel was styled before the palette was settled and kept #fff on the
   gold fill in three places. White on #c8a832 measures 2.31:1, which is not
   a near miss - it is half of what AA asks for, and the send arrow is a
   19px glyph, so it is the worst case rather than the best.

   Dark ink on the same gold measures 6.82:1 and keeps the button gold, which
   is the whole reason the colour is there. --on-accent is the token the rest
   of the site already uses for exactly this; see the block in trammell.css.

   Do not put #fff back on a gold fill.
   ========================================================================== */
.trchat-send{ color: var(--on-accent, #1b2333); }
.trchat-send:hover:not(:disabled){ color: var(--on-accent, #1b2333); }
.trchat-lead .actions .go{ color: var(--on-accent, #1b2333); }
.trchat-lead .actions .go:hover{ color: var(--on-accent, #1b2333); }
