.assistant-trigger{position:fixed;right:24px;bottom:24px;z-index:52;display:flex;align-items:center;gap:10px;border:1px solid var(--border-3);border-radius:99px;padding:13px 18px;background:var(--surface-2);color:var(--text-hi);font:12px var(--font-body);cursor:pointer;box-shadow:0 8px 30px #0004;min-height:48px}
.assistant-trigger svg{width:var(--ico-lg,20px);height:var(--ico-lg,20px);stroke:var(--sage)}.assistant-trigger:hover{border-color:var(--sage)}
.assistant-scrim{position:fixed;inset:0;background:#03060599;z-index:109;opacity:0;visibility:hidden;transition:opacity .25s}.assistant-scrim.open{visibility:visible;opacity:1}
.assistant-panel{position:fixed;inset:16px 16px 16px auto;width:min(460px,calc(100vw - 32px));z-index:110;display:flex;flex-direction:column;background:var(--surface-1);border:1px solid var(--border-3);border-radius:16px;transform:translateX(calc(100% + 32px));visibility:hidden;transition:transform .35s var(--ease),visibility .35s;box-shadow:-20px 0 80px #0004;overflow:hidden}
.assistant-panel.open{transform:none;visibility:visible;transition-property:transform}.assistant-head{padding:26px;display:flex;gap:16px;border-bottom:1px solid var(--border-2);align-items:center}/* Was a flat 26px against an 18px title - a 2.26 mark-to-cap ratio where the header and footer used 1.15. Same tokens as every other lockup now, sized from this panel's own title. */.assistant-emblem{font-size:18px;width:auto;height:var(--brand-mark-h,1.872em);aspect-ratio:var(--brand-mark-aspect,552 / 763);flex:none;display:block;object-fit:contain;filter:drop-shadow(0 0 14px rgba(171,201,176,.35))}.assistant-head h2{font:500 18px var(--font-body);letter-spacing:-.025em}/* 10px is an EYEBROW size - it works for a tracked uppercase label like "01 / WHAT WE MAKE"
   and not for a sentence. These two are sentences ("Answers from Ravenor's project history",
   "Please avoid sensitive information"), and the second is the one a visitor most needs to
   read before typing into a chat box. 11.5px with a little more line height, still clearly
   subordinate to the title above it. */
.assistant-head p{font-size:11.5px;color:var(--muted);line-height:1.7;margin-top:7px}.assistant-head .rv-x{margin-left:auto;flex:none}
.assistant-history{flex:1;overflow:auto;overscroll-behavior:contain;padding:26px;scroll-behavior:smooth}.assistant-welcome{padding:16px 0 30px}.assistant-welcome h3{font:400 30px/1.25 var(--font-body);letter-spacing:-.035em;margin-bottom:18px}.assistant-welcome p{color:var(--muted);font-size:14px;line-height:1.8}
.assistant-prompts{display:flex;flex-direction:column;gap:9px;margin-top:24px}.assistant-prompts button{border:1px solid var(--border-3);background:var(--surface-2);text-align:left;color:var(--text);padding:14px 16px;border-radius:var(--r-control,2px);font:13px/1.5 var(--font-body);cursor:pointer}.assistant-prompts button:hover{border-color:var(--sage);color:var(--sage)}
.assistant-message{font-size:14px;line-height:1.8;padding:15px 18px;border-radius:12px;background:var(--surface-2);margin:0 28px 16px 0;white-space:pre-wrap;overflow-wrap:anywhere}.assistant-message.user{margin:0 0 16px 28px;background:#abc9b019;color:var(--sage-bright)}.assistant-message p{margin:0}.assistant-actions{display:flex;gap:8px;flex-wrap:wrap;margin-top:12px}.assistant-actions a,.assistant-actions button{border:0;background:transparent;text-decoration:underline;text-underline-offset:4px;color:var(--sage);font:12px/1.7 var(--font-body);cursor:pointer;padding:8px 0}
/* A list of eight service names, or seven rows of opening hours, is a list. The bubble sets
   white-space:pre-wrap, so these items are built as real elements with no text nodes between
   them - stray markup whitespace would otherwise render as blank lines inside the bubble. */
.assistant-details{list-style:none;margin:12px 0 0;padding:0;display:flex;flex-direction:column;gap:7px}.assistant-details li{position:relative;padding-left:15px;font-size:13px;line-height:1.65;color:var(--text-hi);white-space:normal}.assistant-details li::before{content:"";position:absolute;left:0;top:.62em;width:6px;height:1px;background:var(--sage)}
/* Quick replies are a question back to the visitor, so they read as pressable chips rather than
   as the text links used for navigation. Sized to the 44px touch minimum at every width. */
.assistant-options{display:flex;flex-wrap:wrap;gap:8px;margin-top:14px}.assistant-options button{min-height:44px;border:1px solid var(--border-3);background:var(--surface-2);color:var(--text);padding:11px 14px;border-radius:var(--r-control,2px);font:12px/1.5 var(--font-body);cursor:pointer;text-align:left;white-space:normal}.assistant-options button:hover{border-color:var(--sage);color:var(--sage)}.assistant-options button:disabled{opacity:.4}
/* No chevron on a quick reply. The mark means "this takes you somewhere", and these do not - they
   answer the question the assistant just asked. It also stopped wrapping onto a line of its own
   under the longer Armenian service names at 320px. */
.assistant-options button.line-action::after{content:none}
.assistant-state{font-size:12px;color:var(--muted);padding:0 26px 12px;min-height:24px}.assistant-compose{padding:18px 26px 22px;border-top:1px solid var(--border-2);background:var(--surface-1)}.assistant-compose label{display:block;font-size:11px;color:var(--muted);margin-bottom:8px}.assistant-input-row{display:flex;gap:8px;align-items:flex-end}.assistant-input-row textarea{resize:none;min-height:48px;max-height:130px;flex:1;min-width:0;padding:12px;font:16px/1.5 var(--font-body);border:1px solid var(--border-3);border-radius:var(--r-control,2px);background:var(--bg);color:var(--text-hi)}.assistant-input-row button{width:48px;height:48px;border:0;border-radius:var(--r-control,2px);background:var(--sage);color:var(--on-sage);font-size:24px;cursor:pointer}.assistant-input-row button:disabled{opacity:.4}.assistant-compose p{font-size:10px;line-height:1.6;color:var(--muted);margin-top:12px}.assistant-compose p a{color:var(--sage)}
@media(max-width:600px){.assistant-trigger{left:18px;right:auto;bottom:18px;padding:12px;width:48px;justify-content:center}.assistant-trigger span{display:none}.assistant-panel{inset:0;width:100%;border-radius:0;border:0;height:100dvh}.assistant-head{padding:20px}.assistant-history{padding:22px}.assistant-compose{padding:16px 20px max(18px,env(safe-area-inset-bottom))}.assistant-welcome h3{font-size:28px}}
@media(prefers-reduced-motion:reduce){.assistant-panel,.assistant-scrim{transition:none}.assistant-history{scroll-behavior:auto}}
.assistant-head .rv-x{width:44px;height:44px;min-width:44px;min-height:44px}
.assistant-panel button,.assistant-panel a{transition-property:color,background-color,border-color,opacity}
.line-action::after{content:'';display:inline-block;width:13px;height:7px;margin-left:8px;border-top:1px solid currentColor;border-right:1px solid currentColor;transform:rotate(45deg) translateY(2px);opacity:.8}

/* ---------------------------------------------------------- floating-control hierarchy
   Production's closed quote trigger is a slim tab on the right edge, and the owner asked for that
   appearance to be preserved. It does not compete with the header button the way the bottom-right
   pill did, because it sits at the middle of the edge rather than on top of the content, and it
   only names itself on approach.

   >=761px  edge tab (quote.css's own design) at the right edge, Ask Ravenor bottom-right. They
            occupy different corners, so neither covers the other or the page.
   <=760px  the header button is inside the burger and an edge tab is awkward on a phone, so the
            trigger becomes a bottom-right pill and Ask Ravenor drops to its icon on the opposite
            corner. Two full-size pills never stack at any width. */
@media(min-width:761px){
  body .assistant-trigger{bottom:24px;right:24px;left:auto}
}
/* The phone used to get a different CONTROL, not a smaller one: the edge tab was thrown away and
   replaced with a filled sage pill 124x48 anchored bottom-right. On a 360px body that is the
   brightest object on the page, parked permanently over the lower right of the hero - the owner's
   report, and visible in qa/_out/mobile/before_*.png.

   A phone is exactly where a persistent filled pill costs the most, so it now gets the same
   right-edge tab the desktop does: collapsed, welded to the edge, opening the same drawer. Only
   the things that must change for touch change - the tab widens to the 44px target minimum, grows
   a little taller, and the label is legible at rest, because there is no hover to reveal it on.
   Everything else - the seam, the chevrons, the drawer it opens - is the accepted desktop design
   rather than a second one. */
@media(max-width:760px){
  /* THE PHONE GETS A CORNER CHIP, NOT AN EDGE TAB.
     The edge tab was measured at 44x133 in English and 44x189 in Armenian - 22% of the height of
     a 390x844 screen, welded under the burger, and the loudest object in the upper right. Every
     part of that came from the label: set vertically, `nav_quote` is as long as the script that
     writes it, so the control's size was a translation artefact rather than a design decision.

     So the phone stops carrying a label. The chip is 48x48 - the same box, the same surface and
     the same shadow as the Ask Ravenor trigger in the opposite corner, because two matched marks
     in the two bottom corners read as a pair that was placed, and one tab plus one circle reads
     as two controls that arrived separately. It is 2304px2 against 8337px2 in Armenian: 72%
     less, and the same size in all three languages because nothing inside it is words.

     What it loses is the word, and that is the real cost. It is paid back three ways: the mark
     is an estimate sheet rather than the chevron pair that reads as "collapse this panel";
     aria-label still carries the full translated name, so assistive technology is unaffected;
     and the page already names the action twice in prose - the header pill and the in-page CTA -
     which is the repetition that made a third shouting copy wrong in the first place.

     Anchored bottom-right against BOTH safe-area insets, so a notch in landscape and a home
     indicator in portrait both move it rather than sit under it. */
  /* REVISED: the corner belongs to chat, and the quote is a pin on the right edge.
     The corner chip answered "too big" but put the conversion action in the thumb corner, which
     is where the owner wants Ask Ravenor. So the quote goes back to the edge - as a PIN, not as
     the 44x189 slab that started this: no label, so it is the same 34x56 in all three languages,
     welded to the edge with the seam it always had.
     Vertically it sits at 68%, not 50%. Measured at 390x844: the wordmark band runs 47-56% of the
     viewport and the scroll cue starts at 72.9%, so true centre lands on the brand and anything
     lower lands on the cue. 68% is the clear gap between them, and it reads as right-of-middle
     rather than as a corner object. The painted box is 34px wide; the TOUCH target is pushed back
     out to 44px+ with ::after, so it is delicate to look at and not to hit. */
  body .rv-quote-handle{
    width:34px;height:56px;min-height:0;padding:0;gap:0;
    top:68%;bottom:auto;
    right:max(0px,env(safe-area-inset-right,0px));
    transform:translateY(-50%);border-radius:12px 0 0 12px;
    border:1px solid rgba(171,201,176,.26);border-right:0;
    background:linear-gradient(180deg,rgba(26,32,28,.88),rgba(17,22,19,.88));
    box-shadow:-10px 0 26px -18px rgba(0,0,0,.9);
    backdrop-filter:blur(10px);-webkit-backdrop-filter:blur(10px)}
  /* the hit area, pushed beyond the paint on three sides */
  body .rv-quote-handle::after{content:'';position:absolute;top:-6px;bottom:-6px;left:-12px;right:0}
  /* The seam is back: this is an edge-welded control again. */
  body .rv-quote-handle::before{display:block;top:12px;bottom:12px;opacity:.45}
  body .rv-qh-mark{display:block}
  body .rv-qh-mark svg{width:var(--ico-md,18px);height:var(--ico-md,18px)}
  body .rv-qh-chev{display:none}
  /* Hidden from sight, kept for assistive technology - the button's accessible name comes from
     aria-label, and this keeps the translated words in the accessibility tree either way. */
  body .rv-qh-lbl{position:absolute;width:1px;height:1px;padding:0;margin:-1px;
    overflow:hidden;clip-path:inset(50%);white-space:nowrap;border:0}
  /* Every transform on this control elsewhere composes with translateY(-50%), because everywhere
     else it is vertically centred on the edge. The chip is corner-anchored and has no centring to
     preserve, so each of those is restated here WITHOUT the -50%. Missing one of them makes the
     chip jump half the viewport on press, which is exactly what happened to the tab's fade-out
     before it was composed properly. */
  /* Centred on the edge again, so every transform composes with translateY(-50%). Getting one of
     these wrong moves the pin half the viewport - it is restated in full for that reason. */
  body .rv-quote-handle:hover,body .rv-quote-handle:focus-visible{transform:translate(-3px,-50%)}
  body .rv-quote-handle:active{transform:translate(-2px,-50%)}
  body.rv-cta-rest .rv-quote-handle{transform:translate(10px,-50%)}
  body.rv-locked .rv-quote-handle{transform:translate(24px,-50%)}
  body .assistant-trigger{left:16px;right:auto;bottom:max(16px,env(safe-area-inset-bottom));
    padding:12px;width:48px;justify-content:center;gap:0}
  body .assistant-trigger>span{position:absolute;width:1px;height:1px;overflow:hidden;
    clip-path:inset(50%);white-space:nowrap}
}
/* Stand the floating controls down while the mobile navigation is open.
   This is a regression THIS change introduced and it is worth stating plainly: the old
   bottom-right pill sat at y~780 on a 390x844 phone while the menu occupies 70-558, so the two
   never met. Moving the tab to 28% to clear the hero lockup put it at 170-302 - inside the menu -
   and at z-index 70 against the menu's 59 it floated ON TOP of the navigation.

   The quote drawer already solves this for itself by setting body.rv-locked, but opening the menu
   sets no body class, so there is no state to hang a rule on. :has() reads the open menu directly.
   Where :has() is unsupported the selector simply never matches and the tab stays put, which is
   exactly today's behaviour - a graceful degradation, not a broken layout. */
@media(max-width:760px){
  body:has(.rv-mm.open) .rv-quote-handle,
  body:has(.rv-mm.open) .assistant-trigger{
    opacity:0;pointer-events:none;visibility:hidden}
}

/* A tab that travels on :hover is a pointer gesture. On touch the equivalent feedback is the
   press itself, so the tab answers :active instead and never sits in a stuck hover state after
   a tap - which is what a hover rule does on a phone. */
@media(hover:none){
  .rv-quote-handle:active{transform:translate(-3px,-50%)}
  .rv-quote-handle:active::before{opacity:1}
}
/* ...except on the phone, where the control is the corner chip and has no centring to compose
   with. Stated after the block above so it wins on specificity of order, not of weight. */
@media(hover:none) and (max-width:760px){
  body .rv-quote-handle:active{transform:translate(-2px,-50%)}
}

/* ------------------------------------------------------ Ask Ravenor at rest: a mark, not a pill
   On desktop this sat permanently as a ~150px labelled pill in the bottom-right corner, which put
   it on top of whatever the page had there — a project photograph on the homepage, the "what do
   you need" choices on the contact form. A floating shortcut that covers the content it floats
   over is a defect no matter how useful the shortcut is.

   It collapses to its mark at rest and names itself on approach, which is the same discipline the
   quote tab already uses on the opposite edge. The label is still in the DOM and still read by
   assistive technology - only its width is animated - so nothing is lost for a screen reader, and
   the corner stops competing with the work. */
@media(min-width:761px){
  .assistant-trigger{gap:0;padding:13px;width:50px;height:50px;justify-content:center;
    transition:width var(--t-move) var(--ease),padding var(--t-move) var(--ease),
               border-color var(--t-ctl) var(--ease),background var(--t-ctl) var(--ease)}
  .assistant-trigger>span{max-width:0;opacity:0;overflow:hidden;white-space:nowrap;
    transition:max-width var(--t-move) var(--ease),opacity var(--t-ctl) var(--ease),
               margin-left var(--t-move) var(--ease)}
  .assistant-trigger:hover,.assistant-trigger:focus-visible,
  .assistant-trigger[aria-expanded="true"]{width:auto;padding:13px 18px}
  .assistant-trigger:hover>span,.assistant-trigger:focus-visible>span,
  .assistant-trigger[aria-expanded="true"]>span{max-width:220px;opacity:1;margin-left:10px}
}
@media(prefers-reduced-motion:reduce){
  .assistant-trigger,.assistant-trigger>span{transition:none}
}

/* The privacy link sits inline inside the compose footer's sentence, so it measured 75x12 on a
   phone. WCAG 2.5.8 exempts a target "in a sentence or block of text", and breaking it out of the
   sentence to reach 44px would be worse writing. Vertical padding on an inline box grows the HIT
   area without changing the line box, so the sentence still sets as one line of prose and the
   target is easier to hit. Visible size and target size are different things. */
.assistant-compose p a{padding-block:9px;text-underline-offset:3px}
