/* ============================================================================
   ASK PIOTR — live hero chat entry + floating panel.  piotrservice.ca pilot.
   ----------------------------------------------------------------------------
   WHAT THIS REPLACES. The red hero CTA (a.btn-call). Nothing else on the page
   is styled here: all 20+ selectors are .ap- prefixed, there is not a single
   element or global selector, so this file cannot leak into existing rules.

   HEIGHT IS PINNED ON PURPOSE. The hero has min-height:auto, so its height is
   whatever its content needs. The entry reproduces the former red button's box
   to the pixel, and it still does now that a live-status row sits above the
   field: the vertical padding was reduced by exactly what the new row adds, so
   the total is unchanged.

       desktop   status 0.72rem x 1.4 = 16.128px, gap 4px,
                 input 1.2rem x 1.4 = 26.88px, padding 9.936px x2,
                 border 2px x2   =  16.128 + 4 + 26.88 + 19.872 + 4 = 70.88px
       mobile    status 0.68rem x 1.4 = 15.232px, gap 3px,
                 input 1.1rem x 1.4 = 24.64px, padding 6.884px x2,
                 no border       =  15.232 + 3 + 24.64 + 13.768 + 0 = 56.64px

   The status row and the input both have their height set with `height: 1.4em`
   rather than left to the browser, because a bare <input> computes its own line
   box and would land a few pixels short — which would quietly shrink the hero.
   The fractional padding is not a typo; it is what makes both totals exact.

   ON TRANSPARENCY. Entry 88%, panel 95%, navy bar 97%, input row 98%. Enough
   for the hero photograph to register behind the entry, never enough to cost
   legibility. The focus layer in section 6 does use backdrop-filter, but only
   behind the open panel and at the approved strengths; the entry itself is
   never blurred.

   ON THE GREEN. The 13 sites' CSS contains no green at all — navy, gold, red
   and greys. But the Piotr Service LOGO does: favicon.png (192x192 RGBA,
   byte-identical in / and /blog) was decoded and its green pixels counted. The
   dominant one is #9eca2c — hsl(77 64% 48%), 1588 green pixels across 911
   shades — a lime/leaf green. That is the value used below, so the status
   colour is the brand's own rather than an invention.

   The previous #9eca2c was rejected as too dark, and measurement agrees twice
   over: it is hsl(151 55% 41%), a blue-green emerald 74 degrees away in hue
   from the logo, with WCAG relative luminance 0.2786 against the logo green's
   0.4969 — 44% darker. Green stays confined to small state accents: 9-10px
   dots, a 3px bubble rule, focus rings and the 20px unread badge. There is no
   green surface anywhere.
   ========================================================================== */

/* Scoped to the component's three roots rather than :root, so this file
   contains no global selector at all and cannot reach the rest of the page.
   Every element that needs these tokens lives inside one of the three. */
.ap-entry, .ap-panel, .ap-mini {
    /* Sampled from the logo in favicon.png: hsl(77 64% 48%). See note above. */
    --ap-live: #9eca2c;
    --ap-live-glow: rgba(158, 202, 44, 0.50);
}

/* ---------------------------------------------------------------- 1. ENTRY */

.ap-entry {
    display: flex;
    flex-direction: column;
    align-items: stretch;
    gap: 4px;
    width: 100%;
    /* Fractional on purpose — see the height arithmetic at the top. */
    padding: 9.936px 20px;
    /* Kept so the box is unambiguous even before the input is laid out. */
    font-size: 1.2rem;
    line-height: 1.4;
    background: rgba(255, 255, 255, 0.88);
    /* 2px all round = the same 4px vertical border the red button had. */
    border: 2px solid rgba(10, 25, 47, 0.10);
    border-top: 2px solid var(--gold, #c5a059);
    border-radius: 4px;
    box-shadow: 0 8px 25px rgba(10, 25, 47, 0.22);
    cursor: text;
    transition: background 0.3s, box-shadow 0.3s, border-color 0.3s;
}

.ap-entry:hover {
    background: rgba(255, 255, 255, 0.94);
    box-shadow: 0 10px 28px rgba(10, 25, 47, 0.28);
}

/* The field itself carries focus, so the surface shows the focus state. */
.ap-entry:focus-within {
    background: rgba(255, 255, 255, 0.96);
    border-color: rgba(158, 202, 44, 0.50);
    border-top-color: var(--gold, #c5a059);
}

/* Status row: the dot plus "Piotr Service is live". Its height is pinned for
   the same reason the input's is — the hero is content-sized, so an unpinned
   line box here would move the fold. The 10px dot is shorter than the row, so
   it never contributes height. */
.ap-entry__status {
    display: flex;
    align-items: center;
    gap: 8px;
    flex: 0 0 auto;
    font-size: 0.72rem;
    height: 1.4em;          /* = 16.128px desktop, 15.232px mobile */
}

.ap-entry__live {
    font-size: inherit;
    line-height: 1.4;
    font-weight: 700;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    /* Navy, not green: the dot carries the signal, the words carry the name. */
    color: var(--main-blue, #0a192f);
    opacity: 0.72;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

/* Live dot. The ring is a box-shadow, so the pulse costs no layout. */
.ap-entry__dot {
    position: relative;
    width: 10px;
    height: 10px;
    flex: 0 0 auto;
    border-radius: 50%;
    background: var(--ap-live, #9eca2c);
    box-shadow: 0 0 0 0 var(--ap-live-glow);
    animation: ap-pulse 2.2s ease-in-out infinite;
}

@keyframes ap-pulse {
    0%   { box-shadow: 0 0 0 0 var(--ap-live-glow); opacity: 1; }
    55%  { box-shadow: 0 0 0 7px rgba(158, 202, 44, 0); opacity: 0.72; }
    100% { box-shadow: 0 0 0 0 rgba(158, 202, 44, 0); opacity: 1; }
}

/* A real field, styled down to look like part of the surface. Weight and
   letter-spacing are deliberately NOT the red button's uppercase 900: this has
   to read as somewhere you type, not as a button. Height is unaffected. */
.ap-entry__input {
    flex: 1 1 auto;
    min-width: 0;
    height: 1.4em;          /* = 26.88px desktop, 24.64px mobile */
    padding: 0;
    font-family: inherit;
    font-size: inherit;
    line-height: 1.4;
    font-weight: 500;
    letter-spacing: 0;
    text-transform: none;
    color: var(--main-blue, #0a192f);
    background: transparent;
    border: none;
    border-radius: 0;
    appearance: none;
    -webkit-appearance: none;
}

.ap-entry__input:focus { outline: none; }

/* 62% strength — inside the approved 60-75% band. */
.ap-entry__input::placeholder {
    color: var(--main-blue, #0a192f);
    opacity: 0.62;
    font-weight: 500;
}

/* ------------------------------------------------- 2. FLOATING CHAT PANEL */

.ap-panel {
    position: fixed;
    right: 24px;
    bottom: 24px;
    z-index: 1100;
    width: 400px;
    height: 540px;
    display: flex;
    flex-direction: column;
    background: rgba(255, 255, 255, 0.95);
    border-radius: 8px;
    overflow: hidden;
    box-shadow: 0 24px 60px rgba(10, 25, 47, 0.42);
    font-family: inherit;
}

.ap-panel[hidden], .ap-mini[hidden] { display: none; }

/* Navy bar with the site's thin gold edge. */
.ap-panel__bar {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 12px 10px 12px 16px;
    background: rgba(10, 25, 47, 0.97);
    border-bottom: 2px solid var(--gold, #c5a059);
    flex: 0 0 auto;
}

/* Same live dot as the entry, so "we are here" reads the same in both states. */
.ap-panel__dot {
    position: relative;
    width: 9px;
    height: 9px;
    flex: 0 0 auto;
    border-radius: 50%;
    background: var(--ap-live, #9eca2c);
    animation: ap-pulse 2.2s ease-in-out infinite;
}

.ap-panel__title {
    flex: 1 1 auto;
    color: var(--white, #ffffff);
    font-size: 0.95rem;
    font-weight: 800;
    letter-spacing: 0.5px;
    text-transform: uppercase;
}

/* Deliberately large and obvious controls. */
.ap-ctl {
    width: 34px;
    height: 34px;
    flex: 0 0 auto;
    display: flex;
    align-items: center;
    justify-content: center;
    background: rgba(255, 255, 255, 0.08);
    color: var(--white, #ffffff);
    border: 1px solid rgba(255, 255, 255, 0.22);
    border-radius: 4px;
    font-family: inherit;
    font-size: 1.15rem;
    line-height: 1;
    cursor: pointer;
    transition: 0.2s;
}

.ap-ctl:hover { background: var(--accent-blue, #172a45); }
.ap-ctl:focus-visible { outline: 2px solid var(--gold, #c5a059); outline-offset: 1px; }

/* The underscore sits low in its own box; nudge it onto the optical centre. */
.ap-ctl--min { align-items: flex-end; padding-bottom: 7px; }

.ap-panel__body {
    flex: 1 1 auto;
    overflow-y: auto;
    padding: 16px;
    display: flex;
    flex-direction: column;
    gap: 10px;
}

.ap-msg {
    max-width: 85%;
    padding: 10px 13px;
    border-radius: 10px;
    font-size: 0.95rem;
    line-height: 1.45;
    word-wrap: break-word;
}

.ap-msg--you {
    align-self: flex-end;
    background: var(--main-blue, #0a192f);
    color: var(--white, #ffffff);
    border-bottom-right-radius: 3px;
}

/* A message FROM Piotr Service. Used for the scripted booking question on the
   navy-button path and for real inbound replies once a source is connected.
   Visually distinct from the system notice below, because one is Piotr talking
   and the other is the page explaining itself. */
.ap-msg--piotr {
    align-self: flex-start;
    background: #ffffff;
    color: var(--main-blue, #0a192f);
    border: 1px solid rgba(10, 25, 47, 0.12);
    border-left: 3px solid var(--ap-live, #9eca2c);
    border-bottom-left-radius: 3px;
}

/* A notice, never a reply: nothing is connected yet and it must not look as if
   something answered. */
.ap-msg--sys {
    align-self: stretch;
    max-width: 100%;
    background: rgba(244, 244, 244, 0.92);
    color: #55606f;
    border-left: 3px solid var(--gold, #c5a059);
    border-radius: 4px;
    font-size: 0.85rem;
}

.ap-panel__input {
    flex: 0 0 auto;
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 10px 12px;
    background: rgba(251, 251, 252, 0.98);
    border-top: 1px solid rgba(10, 25, 47, 0.10);
}

.ap-input__dot {
    width: 9px;
    height: 9px;
    flex: 0 0 auto;
    border-radius: 50%;
    background: var(--ap-live, #9eca2c);
}

.ap-input {
    flex: 1 1 auto;
    min-width: 0;
    padding: 11px 14px;
    font-family: inherit;
    font-size: 0.95rem;
    color: var(--main-blue, #0a192f);
    background: rgba(255, 255, 255, 0.99);
    border: 1px solid rgba(10, 25, 47, 0.16);
    border-radius: 22px;
    transition: border-color 0.2s, box-shadow 0.2s;
}

.ap-input::placeholder { color: var(--main-blue, #0a192f); opacity: 0.45; }

/* Green is the live/active accent — this is the one place it signals state. */
.ap-input:focus {
    outline: none;
    border-color: var(--ap-live, #9eca2c);
    box-shadow: 0 0 0 3px rgba(158, 202, 44, 0.18);
}

.ap-send {
    width: 38px;
    height: 38px;
    flex: 0 0 auto;
    display: flex;
    align-items: center;
    justify-content: center;
    background: var(--main-blue, #0a192f);
    color: var(--white, #ffffff);
    border: none;
    border-radius: 50%;
    font-family: inherit;
    font-size: 1.1rem;
    line-height: 1;
    cursor: pointer;
    transition: 0.2s;
}

.ap-send:hover { background: var(--accent-blue, #172a45); }
.ap-send:focus-visible { outline: 2px solid var(--gold, #c5a059); outline-offset: 2px; }

/* ------------------------------------------------------ 3. MINIMIZED BAR */

/* Minimize is not close: the panel is only hidden, so every message is still
   there when it is restored. */
.ap-mini {
    position: fixed;
    right: 24px;
    bottom: 24px;
    z-index: 1100;
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 12px 16px;
    background: rgba(10, 25, 47, 0.97);
    border-top: 2px solid var(--gold, #c5a059);
    border-radius: 6px;
    color: var(--white, #ffffff);
    font-family: inherit;
    font-size: 0.85rem;
    font-weight: 700;
    letter-spacing: 0.5px;
    cursor: pointer;
    box-shadow: 0 14px 34px rgba(10, 25, 47, 0.38);
}

.ap-mini:focus-visible { outline: 2px solid var(--gold, #c5a059); outline-offset: 2px; }

.ap-mini__dot {
    width: 9px;
    height: 9px;
    flex: 0 0 auto;
    border-radius: 50%;
    background: var(--ap-live, #9eca2c);
    animation: ap-pulse 2.2s ease-in-out infinite;
}

.ap-mini__up { opacity: 0.75; font-size: 1rem; }

/* ------------------------------------------------------------- 4. MOBILE */

@media (max-width: 768px) {
    /* Mirrors the red button's mobile box: 16px padding, 1.1rem, 95% width,
       translateY(-4px), and no border — so mobile hero height is unchanged.
       The gold accent survives as an inset shadow, which costs no height. */
    .ap-entry {
        padding: 6.884px 16px;   /* compensated, see arithmetic at top */
        font-size: 1.1rem;
        width: 95%;
        margin: 0 auto;
        transform: translateY(-4px);
        gap: 3px;
        border: none;
        box-shadow: inset 0 2px 0 var(--gold, #c5a059),
                    0 4px 8px rgba(10, 25, 47, 0.30),
                    0 30px 40px -12px rgba(10, 25, 47, 0.45);
    }

    .ap-entry:focus-within { border: none; }

    /* Near-full width with a small outer margin, clear of the tall mobile
       header (stacked logo + phone + promotions button). */
    .ap-panel {
        right: 10px;
        left: 10px;
        bottom: 10px;
        width: auto;
        height: auto;
        max-height: calc(100vh - 230px);
    }

    .ap-panel__body { padding: 14px; }
    .ap-ctl { width: 40px; height: 40px; font-size: 1.25rem; }
    .ap-send { width: 42px; height: 42px; }
    .ap-input { padding: 12px 14px; }

    .ap-mini { right: 10px; left: 10px; bottom: 10px; justify-content: center; }

    .ap-entry__status { font-size: 0.68rem; gap: 7px; }
}

/* Short viewports: keep the input reachable instead of growing off-screen. */
@media (max-width: 768px) and (max-height: 620px) {
    .ap-panel { max-height: calc(100vh - 150px); }
}

/* --------------------------------------------------- 5. REDUCED MOTION */

/* A visitor who has asked for less motion still needs to see that the service
   is live, so the dot stays — it simply stops moving. The looping pulse is what
   gets disabled here. The typewriter is NOT switched off: it keeps running on
   every platform and only softens (no caret blink, no per-character erase,
   longer holds), which is handled in JS. Switching it off entirely was the bug
   that made it look broken on desktop. */
@media (prefers-reduced-motion: reduce) {
    .ap-entry__dot,
    .ap-panel__dot,
    .ap-mini__dot {
        animation: none;
        box-shadow: 0 0 0 3px rgba(158, 202, 44, 0.26);
    }

    .ap-entry, .ap-input, .ap-ctl, .ap-send { transition: none; }
}

/* ================================================= 6. FOCUS LAYER (dim/blur)

   WHY A SEPARATE ELEMENT AND NOT A FILTER ON THE PAGE. This page has two
   position:fixed elements (the site header, and the old Square modal). A CSS
   filter on any ancestor of the chat would turn that ancestor into the
   containing block for every fixed descendant AND would blur the chat itself.
   So the dim is its own layer, a sibling of the panel, sitting between the page
   (header z-index 1000) and the chat (1100). Nothing is an ancestor of
   anything, so no containing block anywhere changes.

   backdrop-filter does the work. Where it is unsupported the @supports block
   below falls back to a plain tint, which is a weaker but perfectly sane
   result rather than a broken one.
   ========================================================================== */

.ap-dim {
    position: fixed;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    z-index: 1090;
    /* Desktop: deliberately restrained. 12% dim, 1.5px blur. */
    backdrop-filter: blur(1.5px) brightness(0.88);
    -webkit-backdrop-filter: blur(1.5px) brightness(0.88);
    cursor: pointer;
}

.ap-dim[hidden] { display: none; }

@supports not ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {
    .ap-dim { background: rgba(10, 25, 47, 0.12); }
}

/* ------------------------------------- 7. MINIMIZED: NEW MESSAGE STATE */

.ap-mini__icon { font-size: 1rem; line-height: 1; flex: 0 0 auto; }

.ap-mini__badge {
    min-width: 20px;
    height: 20px;
    flex: 0 0 auto;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 0 6px;
    background: var(--ap-live, #9eca2c);
    color: #ffffff;
    border-radius: 10px;
    font-size: 0.72rem;
    font-weight: 800;
    letter-spacing: 0;
}

.ap-mini__badge[hidden], .ap-mini__icon[hidden] { display: none; }

/* Three pulses, then it stops and simply stays visible. A permanently
   blinking bar reads as broken, not as urgent. */
.ap-mini--alert {
    border-top-color: var(--ap-live, #9eca2c);
    animation: ap-alert 0.9s ease-in-out 3;
}

@keyframes ap-alert {
    0%, 100% { box-shadow: 0 14px 34px rgba(10, 25, 47, 0.38); }
    50%      { box-shadow: 0 14px 34px rgba(10, 25, 47, 0.38),
                           0 0 0 4px rgba(158, 202, 44, 0.40); }
}

/* ------------------------------------------- 8. MOBILE FOCUS LAYER */

@media (max-width: 768px) {
    /* Mobile: the chat must clearly dominate. 67% brightness, 4px blur.
       The page stays recognisable; it just stops competing. */
    .ap-dim {
        backdrop-filter: blur(4px) brightness(0.67);
        -webkit-backdrop-filter: blur(4px) brightness(0.67);
    }

    @supports not ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {
        .ap-dim { background: rgba(10, 25, 47, 0.33); }
    }
}

/* Reduced motion: the alert still appears, it just does not pulse. */
@media (prefers-reduced-motion: reduce) {
    .ap-mini--alert { animation: none; }
}

/* ================================== 9. PRESENTATION VARIANTS (SIMPLE / MODERN)

   TWO SURFACES, ONE STATE MACHINE. This section is the ONLY place the two
   variants differ, and it is purely cosmetic: nothing here sets padding,
   font-size, gap, width, height or border-width. Both variants are therefore
   the same size to the pixel, and the hero arithmetic at the top of this file
   holds for each of them. Only corner radius, shadow, surface opacity and the
   dot's motion change.

   JS adds .ap-s-simple or .ap-s-modern to the entry, the panel and the
   minimized bar, chosen from ?chatStyle=simple|modern. Every rule below is
   doubled (.ap-entry.ap-s-simple) so it outranks both the base rule and the
   mobile overrides no matter where they sit in the file.

   THE ENTRY'S SHADOW IS OVERRIDDEN ON DESKTOP ONLY. On mobile the entry has
   border:none and carries its gold accent as an inset box-shadow, so replacing
   box-shadow there would silently delete the gold line. Mobile keeps the base
   shadow in both variants; the radius alone separates them, which is plenty at
   that size.

   There is deliberately no visitor-facing switch: this is an Owner comparison
   aid, not an A/B test. The Owner has not chosen between them.
   ========================================================================== */

/* ---------------------------------------------------------------- SIMPLE
   Flat, square and still. Nothing animates except the typed text. For an
   audience that reads motion as clutter. */

.ap-entry.ap-s-simple {
    background: rgba(255, 255, 255, 0.94);
    border-radius: 0;
}

/* Still visibly live, just not moving. */
.ap-entry.ap-s-simple .ap-entry__dot {
    animation: none;
    box-shadow: 0 0 0 2px rgba(158, 202, 44, 0.30);
}

.ap-panel.ap-s-simple { border-radius: 0; }
.ap-panel.ap-s-simple .ap-msg { border-radius: 2px; }
.ap-panel.ap-s-simple .ap-input { border-radius: 4px; }
.ap-panel.ap-s-simple .ap-send { border-radius: 0; }
.ap-panel.ap-s-simple .ap-ctl { border-radius: 0; }
.ap-panel.ap-s-simple .ap-panel__dot { animation: none; }

.ap-mini.ap-s-simple { border-radius: 0; }
.ap-mini.ap-s-simple .ap-mini__badge { border-radius: 3px; }
.ap-mini.ap-s-simple .ap-mini__dot { animation: none; }

@media (min-width: 769px) {
    .ap-entry.ap-s-simple { box-shadow: 0 3px 10px rgba(10, 25, 47, 0.20); }
    .ap-panel.ap-s-simple { box-shadow: 0 10px 30px rgba(10, 25, 47, 0.30); }
}

/* ---------------------------------------------------------------- MODERN
   Rounded, soft-shadowed, with the pulse left on. This is the continuation of
   the presentation already approved in the earlier checkpoints, which is the
   only reason it is also the no-parameter default - not a recommendation. */

.ap-entry.ap-s-modern {
    background: rgba(255, 255, 255, 0.88);
    border-radius: 14px;
}

.ap-panel.ap-s-modern { border-radius: 18px; }
.ap-panel.ap-s-modern .ap-msg { border-radius: 16px; }
.ap-panel.ap-s-modern .ap-input { border-radius: 24px; }
.ap-panel.ap-s-modern .ap-send { border-radius: 50%; }
.ap-panel.ap-s-modern .ap-ctl { border-radius: 8px; }

/* A very shallow lift on the bar. Gradient stops are 3% apart: enough to stop
   the navy reading as a flat block, not enough to look like a button. */
.ap-panel.ap-s-modern .ap-panel__bar {
    background: linear-gradient(180deg, rgba(23, 42, 69, 0.97), rgba(10, 25, 47, 0.97));
}

.ap-mini.ap-s-modern { border-radius: 16px; }

@media (min-width: 769px) {
    .ap-entry.ap-s-modern { box-shadow: 0 14px 34px rgba(10, 25, 47, 0.30); }
    .ap-panel.ap-s-modern { box-shadow: 0 22px 60px rgba(10, 25, 47, 0.44); }
}

/* Reduced motion already stops every dot in section 5; MODERN does not
   reintroduce it. Nothing in this section overrides that. */
