/* eHolidayer front page — mock-up port, front-page-only rules.
 *
 * This file is linked ONLY on the front page (templates/aurora/index.php,
 * after ehd-site.css and after aiagent.css), so everything here is scoped
 * to the front page by the file itself. Tokens come from ehd-site.css.
 *
 * Rendered order (verified with curl): .navigation header, .hidden-area
 * strip, .aurora_top hero + search (mod_tabsearch), this page's
 * reassurance line (includes/eholidayer-home.php), the hotel modules in
 * .main-body, the trust counters in .frontpage-wrapper (mod_mscounter),
 * then the footer. Each real module is restyled, not replaced.
 */

/* ---- aiagent widget: warm coral -> blue hour ----
   aiagent.css declares its widget palette as --eh-* on :root. This file
   loads after it, so the remap takes effect on the front page without
   touching the widget's CSS or JS: the launcher and panel keep their
   shape, only the colours follow the mock-up. */
:root {
    --eh-warm:       #FFFFFF;  /* panel background */
    --eh-sand:       #F5F2EB;  /* muted chips */
    --eh-sand-deep:  #E2E6E5;  /* chip borders */
    --eh-coral:      #4285F4;  /* primary button (brand-400) */
    --eh-coral-dark: #1A73E8;  /* hover (brand-500) */
    --eh-teal:       #172E3B;  /* secondary accent (ink) */
    --eh-teal-soft:  #E8F0FE;  /* soft accent background (brand-50) */
    --eh-ink:        #172E3B;
    --eh-ink-soft:   #5F6B70;
    --eh-shadow:       0 14px 40px rgba(21,59,75,.14);
    --eh-shadow-soft:  0 8px 28px rgba(21,59,75,.08);
}

/* ---- page surface ---- */
body { background: var(--canvas); }

/* The mock-up front page has no breadcrumb band. */
.paths { display: none; }

/* ---- hero / search module (mod_tabsearch) ----
   tabsearch-hero.css ships a fixed 1280px hero and hides the tab bar
   ("Figma has no tabs"). Two problems with that here: the width
   overflows any window narrower than 1280, and the search card is
   absolutely positioned at bottom:-48px so it hangs half off the
   photo instead of sitting under it like the mock-up's
   .ehd-searchbar sibling.

   tabsearch-hero.css uses .aurora_top .ts_hero_wrap, which is
   specificity (0,2,0) and outranks anything a bare .ts_hero_wrap
   rule here can do, so these overrides are written at (0,2,0) too
   and win on equal footing by load order (this file loads later).
   Every control the module renders — tabs, date fields, the guest
   picker, the submit button — keeps working; only its box changes. */
.aurora_top { background: var(--canvas); }

/* The mock-up's .ehd-hero-block is a column: the photo card, then
   the search bar as a SIBLING 18px below it, never on top of it.
   The module instead paints the photo as a plain <img> filling
   .ts_hero_wrap and hangs every other piece absolutely over it, so
   the search card would land on the picture. The photo becomes a
   background on the wrapper and the wrap becomes a real column with
   a fixed photo block on top; the search card then follows it in
   flow. .ts_hero_image / .ts_hero_overlay stay absolute because the
   module's own markup still expects them there. */
.aurora_top .ts_hero_wrap {
    box-sizing: border-box;
    display: flex;
    flex-direction: column;
    gap: var(--sp-5);
    width: min(1280px, calc(100% - 2 * var(--gutter-wide)));
    min-height: 0;          /* core pins 480px on the wrapper */
    height: auto;
    margin: 0 auto;
}

/* The photo block: exactly the mock-up's 480px hero card. The <img>
   is nested INSIDE .ts_hero_image, so that wrapper has to become the
   in-flow flex child - leaving it absolute collapses the column to the
   height of the search card alone and the hero photo disappears. */
.aurora_top .ts_hero_image {
    position: relative;
    width: 100%;
    height: 480px;
    border-radius: var(--r-hero);
    overflow: hidden;
    pointer-events: none;
}
.aurora_top .ts_hero_image img {
    display: block;
    width: 100%;
    height: 100%;
    object-fit: cover;
}

/* The veil and the headline block overlay the photo, so they are
   measured against .ts_hero_image rather than the whole wrap. */
.aurora_top .ts_hero_overlay,
.aurora_top .ts_hero_content {
    top: 0;
    height: 480px;
}

/* The intro sentence is TRIMMED and MOVED (owner 2026-10-17, point 6:
   "trim or move that sentence of the hero's intro paragraph"). Trimmed
   to one line in mod_tabsearch.php; moved here to ride the bottom of
   the photo. Before: the paragraph lived in the content column's flow
   at 221-275px and the floating card starts at 243px - its lower half
   was physically under the glass. Pinned to the photo's bottom instead
   (a flex child CANNOT be bottom-pinned by margin, only by leaving the
   flow), it can never meet the card again whatever the card measures,
   because the card is vertically centred on the photo and this sits
   below even its lowest possible position. Hidden outright on phones
   in the @media (max-width:768px) block - there the card covers the
   photo's bottom.
   The location chip (.ts_hero_caption) was deleted from the module's
   PHP the same day (point 2); this hide is insurance so a half-uploaded
   site - old PHP, new CSS, or a browser-cached page - never shows it. */
.aurora_top .ts_hero_description {
    position: absolute;
    left: 0;
    right: 24px;
    bottom: 40px;
    margin: 0;
    width: auto;
}
.aurora_top .ts_hero_caption { display: none !important; }

/* The search card FLOATS IN THE MIDDLE OF THE PHOTO (owner, 2026-10-17,
   points 1-2: "make the tab search floating in the middle of the hero
   image, with a little transparent background").

   The geometry that makes this exact: the module's own absolute
   positioning is resolved against .ts_hero_wrap (measured live, not
   assumed - its offsetParent), and the 480px photo is the wrap's first
   in-flow child starting at the wrap's very top. So top:240px with a
   -50%/-50% transform is the photo's true centre at every width, no
   calc() against the photo needed.

   Width is capped narrower than the wrap so the glass card reads as a
   card ON the photo, with photo visible all around it - a full-bleed
   bar edge-to-edge would look flush, not floating.

   On phones the bar floats OVER THE PHOTO TOO (owner 2026-10-17, point
   1) - see the @media (max-width: 768px) block further down; this base
   rule is the in-flow fallback if that block is ever removed. */
.aurora_top .ts_hero_search {
    position: relative;
    z-index: 4;
    margin-top: 0;
}
/* The vendor wrapper paints an OPAQUE white rectangle behind the card
   (measured: rgb(255,255,255) on .ts_container_sblue). That white sheet
   is why the bar reads "empty and plain" - a white card sitting on a
   white box is one big flat rectangle - and it would silently defeat
   any translucency on the card itself, since translucent over opaque
   white is just white. Making it transparent is the prerequisite for
   every glass rule below; on phones it changes nothing visible because
   the page canvas there is white anyway. */
.aurora_top .ts_container_sblue {
    max-width: none;
    width: 100%;
    background: transparent;
}

/* Desktop: lift the bar onto the photo's centre and turn the card to
   glass. --eh-* roles: brand-400 is #4285F4, ink #172E3B (the remap at
   the top of this file). The blur is what makes it read as glass rather
   than a faded box; @supports covers Firefox, where backdrop-filter is
   off by default and a solid near-white is the honest fallback. */
@media (min-width: 769px) {
    .aurora_top .ts_hero_search {
        position: absolute;
        left: 50%;
        top: 240px;
        right: auto;
        bottom: auto;
        transform: translate(-50%, -50%);
        width: min(1120px, calc(100% - 48px));
    }
    /* Specificity note: these glass rules carry .ts_hero_search to sit
       at (0,5,0) - ONE class above the base .ts_columns rule further
       down in this same file (measured live via a CSSOM winner scan:
       the base rule was winning background/box-shadow purely because
       it appears later at equal (0,4,0), while backdrop-filter, which
       the base never declares, survived. Specificity, not order, has
       to carry the win. */
    .aurora_top .ts_hero_search .ts_container_sblue .ts_curcontent_sblue .ts_columns {
        background: rgba(255, 255, 255, .82);
        -webkit-backdrop-filter: blur(18px) saturate(140%);
        backdrop-filter: blur(18px) saturate(140%);
        border: 1px solid rgba(255, 255, 255, .65);
        box-shadow: 0 24px 60px rgba(13, 38, 60, .28);
    }
    @supports not ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {
        .aurora_top .ts_hero_search .ts_container_sblue .ts_curcontent_sblue .ts_columns {
            background: rgba(255, 255, 255, .94);
        }
    }
    /* Hairlines inside glass read better light-on-dark than the solid
       grey the solid card uses. */
    .aurora_top .ts_columns .ts_col35wbtn,
    .aurora_top .ts_columns .ts_col30wbtn { border-right-color: rgba(255, 255, 255, .55); }
    .aurora_top .ts_col35wbtn:hover,
    .aurora_top .ts_col30wbtn:hover { background: rgba(66, 133, 244, .06); }

    /* The guests/rooms line hangs under the card as its own small glass
       pill, matching the card so it reads as part of it (it is a sibling
       of .ts_columns, so it cannot share the card's background). */
    .aurora_top .ts_guestsrow {
        width: max-content;
        max-width: 100%;
        margin: 10px auto 0;
        padding: 8px 18px;
        text-align: center;
        background: rgba(255, 255, 255, .85);
        -webkit-backdrop-filter: blur(14px) saturate(140%);
        backdrop-filter: blur(14px) saturate(140%);
        border: 1px solid rgba(255, 255, 255, .65);
        border-radius: 999px;
        box-shadow: 0 10px 26px rgba(13, 38, 60, .18);
        color: var(--ink-display);
    }
    .aurora_top .ts_guestsrow a { color: var(--brand-500); font-weight: 600; }

    /* The Search button fills the card's height and says what it does.
       Winner scan: tabsearch-hero.css paints `.ts_hero_wrap
       button.ts_btn { height: 46px }` at (0,2,1) - the element
       selector tips it past a plain two-class rule - so this block
       carries .ts_hero_search too and answers at (0,3,0). The label
       rides along under the same prefix. */
    .aurora_top .ts_hero_search .ts_btn {
        height: 100%;
        min-height: 56px;
        display: inline-flex;
        align-items: center;
        justify-content: center;
        gap: 8px;
        padding: 14px 26px;
    }
    /* The vendor hides this label on desktop with BOTH display:none and
       visibility:hidden (tabsearch.css), and restores both on mobile.
       Restoring only display left the word "Search" taking its 44px of
       space while painting nothing - visibility must come back too. */
    .aurora_top .ts_hero_search .ts_btn .ts_btnmobtext { display: inline; visibility: visible; }
}

/* ---- field row: the mock-up's .ehd-searchbar spec (point 2) ----
   The owner asked for the real search to look like the mock-up page.
   The mock-up (ehd-chrome.css) draws .ehd-searchbar as a 96px-min
   row with 12px padding, three fields at flex 365/235/225, a 1px 42px
   hairline between each field, an uppercase 11px label, and a
   brand-400 send button. The real module gives different boxes for
   the same information, so the sizes, colours and dividers are copied
   across here while every input, the guest picker and the real submit
   stay exactly as the module rendered them.

   The flex bases are the load-bearing part. tabsearch-hero.css:264-268
   sets .ts_col35wbtn/.ts_col30wbtn to `flex: 1 1 auto` at
   specificity (0,2,0), which beats the base `flex: 1 1 32%`. With
   flex-basis:auto each field sizes to its own CONTENT, and the date
   inputs do not shrink - measured 375+360+542+193 = 1470px of content
   in a 735px row, so "Check out" wrapped onto a second line and the
   row grew to 90px. Writing the percentages back at (0,4,0) - which
   wins on specificity, not merely on load order - restores the
   intended share-based sizing and puts all three fields on one line. */
.aurora_top .ts_container_sblue .ts_curcontent_sblue .ts_columns {
    display: flex;
    flex-wrap: nowrap;
    align-items: stretch;
    gap: 0;
    padding: var(--sp-3);
    min-height: 96px;
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--r-card);
    box-shadow: var(--e-1);
}
/* Desktop shares. These are SCOPED to >=769px rather than left
   unconditional, because a flex-basis written for a 1200px row is not
   a neutral default at 375px - it is an instruction to squeeze. With
   these values applying on a phone, all three fields measured 41px
   wide (48-89, 89-130, 130-171) while the never-shrinking button took
   279px. The phone layout is the @media block further down. */
@media (min-width: 769px) {
    .aurora_top .ts_col35wbtn { flex: 365 1 0; min-width: 0; }
    .aurora_top .ts_col30wbtn { flex: 235 1 0; min-width: 0; }
}

/* Each field is the mock-up's .ehd-field: the icon on the left
   spanning both lines, the label above the value on the right, and a
   1px hairline divider on the field's right edge (the mock-up draws
   it with .ehd-field + .ehd-field::before).

   The module's markup is NOT that shape: label.ts_label and
   .ts_iconbox are siblings, and the icon and the input are children
   OF .ts_iconbox. So `display: contents` on .ts_iconbox dissolves it
   and promotes .ts_iconboxi and .ts_iconboxv to be direct children of
   the field - the icon and the value can then sit on their own grid
   lines beside the label. Without it the label and the icon+value
   compete on one row, and the label's width:100% (tabsearch-hero.css:332)
   squeezes the value to 16-27px - measured, with the dates unreadable.

   grid, not flex: the value must be allowed to fill the second column
   without a minimum of its own, which is what min-width:0 buys, while
   the icon column stays a fixed 22px. */
.aurora_top .ts_col35wbtn,
.aurora_top .ts_col30wbtn {
    display: grid;
    grid-template-columns: 36px minmax(0, 1fr);
    grid-template-rows: auto auto;
    column-gap: 12px;
    row-gap: 3px;
    align-items: center;
    align-content: center;
    padding: 0 20px;
    height: auto;
    border-right: 1px solid var(--hairline);
}.aurora_top .ts_iconbox { display: contents; }
.aurora_top .ts_iconboxi { grid-column: 1; grid-row: 1 / span 2; align-self: center; }
.aurora_top label.ts_label { grid-column: 2; grid-row: 1; align-self: end; }
.aurora_top .ts_iconboxv { grid-column: 2; grid-row: 2; min-width: 0; align-self: start; }

/* The label is the mock-up's .ehd-field-label: uppercase, 11px,
   600, letter-spaced, muted. Placed on grid row 1 by the field rule
   above; width:100% would be measured against the grid column, so it
   is left as the module sets it. */
.aurora_top label.ts_label {
    margin: 0;
    font: 600 11px/1.2 var(--font-ui);
    letter-spacing: 0.04em;
    text-transform: uppercase;
    color: var(--text-secondary);
    white-space: nowrap;
}

/* The mock-up puts each field's icon on a tinted TILE; the real module
   leaves a bare 15px Font Awesome glyph floating in the column, which
   is a big part of why the bar "feels empty and plain". The .ts_iconboxi
   wrapper is already a child of my grid, so it can become the tile
   itself - no markup change, and the FA font (verified loaded) keeps
   rendering inside it. The value gets weight 600 so "Cairo, Egypt"
   reads as an answer, not a whisper. */
.aurora_top .ts_iconboxi {
    width: 34px;
    height: 34px;
    border-radius: 10px;
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 14px;                  /* FA is font-size driven */
    color: var(--brand-500);
    background: rgba(66, 133, 244, .10);
}
.aurora_top .ts_columns .ts_iconboxv input { font-weight: 600; }

/* Phone: one field per full-width row.
   flex-wrap MUST be reset here - the .ts_columns rule above pins
   nowrap, and without wrap the fields cannot take their own line at
   all, however they are sized. min-height is reset for the same
   reason: 96px is the height of the desktop single line. */
@media (max-width: 768px) {
    .aurora_top .ts_container_sblue .ts_curcontent_sblue .ts_columns {
        flex-wrap: wrap;
        min-height: 0;
    }
    .aurora_top .ts_col35wbtn,
    .aurora_top .ts_col30wbtn,
    .aurora_top .ts_colbtn {
        flex: 1 1 100%;
        min-width: 0;
    }
    /* The vertical dividers between fields become horizontal rules. */
    .aurora_top .ts_col35wbtn,
    .aurora_top .ts_col30wbtn {
        padding: 10px 16px;
        border-right: 0;
        border-bottom: 1px solid var(--hairline);
    }
    .aurora_top .ts_nolabel { display: none; }
    .aurora_top .ts_colbtn {
        padding: 10px 16px 12px;
        border-right: 0;
    }
    .aurora_top .ts_btn { width: 100%; }

    /* Guests/rooms lives OUTSIDE .ts_columns - mod_tabsearch.php:463
       emits .ts_guestsrow as a sibling of the field row, not a child -
       so it needs its own treatment or it reads as an orphan below
       the Search button. */
    .aurora_top .ts_guestsrow {
        margin: 0 16px;
        padding: 10px 0;
        border-top: 1px solid var(--hairline);
    }
}

/* Send button: the mock-up's .ehd-search-go - brand-400 fill, rounded
   input radius, matching height. */
.aurora_top .ts_colbtn { flex: 0 0 auto; align-self: stretch; padding: 0 0 0 var(--sp-3); }
.aurora_top .ts_btn {
    padding: 14px 22px;
    background: var(--brand-400);
    color: var(--surface);
    border-radius: var(--r-input);
    font: 600 14px/1 var(--font-ui);
    white-space: nowrap;
}
.aurora_top .ts_btn:hover { background: var(--brand-500); }

/* The tab bar is intentionally absent.

   tabsearch-hero.css:212-216 already hides it (`.ts_hero_wrap
   ul.ts_tabs_* { display: none }`) because the design has no tabs. An
   earlier pass here re-showed it with an equal-specificity
   `display: flex` that won on load order, which put a 305px-wide
   strip of five chips - one of them a duplicate "Hotels", from the
   module appending a configured tab to its four built-in ones - into
   the layout at every width. That rule is deleted, so the module's own
   hides it stands and the front page shows one search and nothing to
   switch between.

   `.ts_content_sblue` / `.ts_curcontent_sblue` are no longer
   overridden either. Hiding all but the first panel was only ever
   needed for tab switching, and tabsearch.js is never loaded, so
   nothing was switching anyway. The module's own rules apply. */

/* Phone float (owner 2026-10-17, point 1: "it's not [floating] in
   mobile and it conflicts with ehd-reassure - make it also floating
   over the hero image in mobile"). The bar used to sit in the flow
   under the photo, where its full-width stacked fields grew ~400px
   tall and collided with the feature band below it.

   Deterministic geometry: the photo is the wrap's first in-flow child
   and this file pins it to exactly 480px at EVERY width, so in wrap
   coordinates top:480px IS the photo's bottom edge - no measuring
   needed. The card is then lifted by 57% of its OWN height: however
   tall the stacked fields make it, the same proportion of the card
   stays on the photo and the overhang below the photo is always
   43% of the card height. padding-bottom on the wrap reserves room
   for that overhang so the feature band starts under the card instead
   of underneath it (tightened live after measuring). Same glass
   treatment desktop gets, so it reads as one card across devices. */
@media (max-width: 768px) {
    .aurora_top .ts_hero_wrap {
        width: min(1280px, calc(100% - 2 * var(--gutter)));
        position: relative;
        padding-bottom: 210px;
    }
    .aurora_top .ts_hero_search {
        position: absolute;
        left: 10px;
        right: 10px;
        width: auto;
        max-width: none;
        top: 480px;
        bottom: auto;
        transform: translateY(-57%);
        z-index: 4;
    }
    .aurora_top .ts_hero_description { display: none; }
    /* Specificity must carry this: the base .ts_columns card rule
       (0,4,0) sits later in this file than the old in-flow phone
       layout ever needed to beat, exactly the trap the desktop glass
       block documents at (0,5,0). Same prefix, same win. */
    .aurora_top .ts_hero_search .ts_container_sblue .ts_curcontent_sblue .ts_columns {
        background: rgba(255, 255, 255, .82);
        -webkit-backdrop-filter: blur(18px) saturate(140%);
        backdrop-filter: blur(18px) saturate(140%);
        border: 1px solid rgba(255, 255, 255, .65);
        box-shadow: 0 24px 60px rgba(13, 38, 60, .28);
    }
    @supports not ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {
        .aurora_top .ts_hero_search .ts_container_sblue .ts_curcontent_sblue .ts_columns {
            background: rgba(255, 255, 255, .94);
        }
    }
}

/* ---- assistant block (includes/eholidayer-home.php) ----
   The owner asked for a fixed chat box UNDER the search tab, with no
   pop-up button - so the assistant is a block of the page, in normal
   flow, directly beneath the search.

   An earlier pass made it a 380px floating rail on the right, which
   forced the whole page to inset itself: --eh-rail-w / --eh-rail-gap
   and ~80 lines of body:has(.eh-chat-panel) rules on the hero, the
   trust band and the footer. All of that is deleted. With the panel in
   normal flow the page needs no inset at all, which is why those rules
   went rather than being retuned. */

.ehd-assist {
    max-width: 880px;
    margin: 0 auto;
    padding: 0 var(--gutter) var(--sp-9);
    text-align: center;
}
/* "Where to next?" with a live-presence badge over it, the way a chat
   app marks itself available (owner, 2026-10-17: header + subheader
   "with a nice design getting the attention"). The pulsing dot says a
   person - Era - is on the other end, which the plain headline could
   not; the animation runs on opacity/scale only and stops for
   prefers-reduced-motion at the bottom of the file. */
.ehd-assist-badge {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    margin: 0 0 var(--sp-4);
    padding: 7px 16px 7px 13px;
    border: 1px solid rgba(66, 133, 244, .25);
    border-radius: 999px;
    background: rgba(66, 133, 244, .08);
    font: 600 13px/1 var(--font-ui);
    letter-spacing: .01em;
    color: var(--brand-500);
}
.ehd-assist-badge-dot {
    width: 8px;
    height: 8px;
    border-radius: 50%;
    background: #34A853;
    animation: ehd-badge-pulse 2.2s ease-in-out infinite;
}
@keyframes ehd-badge-pulse {
    0%, 100% { box-shadow: 0 0 0 0 rgba(52, 168, 83, .45); }
    50%      { box-shadow: 0 0 0 5px rgba(52, 168, 83, 0); }
}
.ehd-assist-title {
    margin: 0 0 var(--sp-2);
    font: 700 clamp(26px, 4vw, 38px)/1.12 var(--font-display);
    color: var(--ink-display);
    letter-spacing: -0.015em;
}
/* Owner round 3 (2026-10-17, point 4): Era's round avatar rides beside
   the intro sentence - the picture is the eHolidayer brand mark since the
   owner's 2026-10-18 rename round (assistant renamed Vera -> Era). The
   avatar is a ::before, not an <img>, for the same
   reason the chat avatar is a background: a url() inside this file is
   resolved against the stylesheet, so no server-side URL builder can
   rewrite it to https and strand it on a local http page. The flex row
   puts circle left / words right; the text wraps normally when the
   line fills, the circle never does (flex:none). */
.ehd-assist-sub {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 14px;
    margin: 0 auto var(--sp-6);
    max-width: 640px;
    color: var(--text-secondary);
    font: 400 15.5px/1.55 var(--font-ui);
}
.ehd-assist-sub::before {
    content: '';
    flex: none;
    width: 52px;
    height: 52px;
    border-radius: 50%;
    background: #FFEFCC url('../images/eholidayer-mark.svg') center / 72% no-repeat;
    border: 1px solid rgba(249, 171, 0, .35);
    box-shadow: 0 4px 12px rgba(23, 46, 59, .10);
}
/* The panel's own text must not inherit the centred heading. */
#eh-chat-slot { text-align: left; }
#eh-chat-slot .eh-chat-panel {
    position: static;
    width: auto;
    max-width: none;
    right: auto;
    left: auto;
    bottom: auto;
    height: min(560px, 70vh);
}
/* aiagent.css:101-110 turns the panel into a fixed full-screen sheet
   below 700px. On its own that is right for a floating panel, but here
   it would tear the panel out of the page on exactly the phones the
   owner reported as broken - so the sheet is cancelled inside the slot
   and the panel stays a block, which is the whole point of putting it
   under the search. */
@media (max-width: 700px) {
    #eh-chat-slot .eh-chat-panel {
        position: static;
        right: auto;
        left: auto;
        bottom: auto;
        width: auto;
        height: min(520px, 68vh);
        max-height: none;
        border-radius: var(--eh-radius-lg);
    }
}

/* ---- chat panel: Claude-UI styling, scoped to #eh-chat-slot ----
   The owner asked (2026-10-17, point 3) for the chat to look like the
   Claude UI. That style is quiet: a white head with a hairline instead
   of a solid bar, assistant replies as plain text on paper rather than
   bubbles, and a rounded bordered composer with a dark rounded-rect
   send button. Every override is prefixed #eh-chat-slot, so it hits
   only the in-page panel - if aiagent.css ever floats a panel in a
   corner again (or a stale cache serves the old one), that panel keeps
   the original look. This file also loads after aiagent.css, so no
   !important is needed anywhere.

   Era's big introduction card that lived here is GONE: the owner's new
   layout (badge + "Where to next?" + sub, straight into the chat) makes
   it redundant, and its chip row duplicated the chat's own opener
   chips. Era's identity moved into the chat itself - the greeting
   string introduces her. Her avatar is the eHolidayer brand mark, eholidayer-mark.svg (owner 2026-10-18: the rename round gave her the company's own glyph, replacing the robot portrait and the hand-drawn sun before it). The warm disc stays underneath: a brand colour behind the mark keeps the circle hers even if the SVG itself loads a beat late. */
#eh-chat-slot .eh-chat-panel {
    background: #fff;
    border: 1px solid var(--eh-sand-deep);
    box-shadow: 0 1px 2px rgba(23, 46, 59, .05), 0 12px 40px rgba(23, 46, 59, .10);
}
#eh-chat-slot .eh-chat-head {
    background: #fff;
    color: var(--eh-ink);
    border-bottom: 1px solid var(--eh-sand-deep);
    padding: 12px 16px;
}
#eh-chat-slot .eh-chat-head .eh-chat-avatar {
    /* Owner 2026-10-18: Era's face is the eHolidayer brand mark itself.
       The base .eh-chat-avatar is a border-radius:50% circle; the mark is
       painted at 72% so the glyph keeps breathing room inside the round
       crop, and the amber hairline carries the mark's own warm colour
       through the panel. Relative URL on purpose - it resolves
       against the CSS file itself, so no scheme rewrite can break it. */
    background: #FFEFCC url('../images/eholidayer-mark.svg') center / 72% no-repeat;
    border: 1px solid rgba(249, 171, 0, .35);
}
/* The spark SVG the JS paints inside is hidden by the photo in both
   places the avatar appears (head + typing row). */
#eh-chat-slot .eh-chat-avatar svg { display: none; }
#eh-chat-slot .eh-chat-icon-btn {
    background: #fff;
    color: var(--eh-ink-soft);
    border: 1px solid var(--eh-sand-deep);
}
#eh-chat-slot .eh-chat-icon-btn:hover { background: var(--eh-sand); color: var(--eh-ink); }

#eh-chat-slot .eh-chat-log {
    background: #fff;
    padding: 18px 18px 10px;
}
/* Claude does not wrap its replies in bubbles - plain text on paper,
   user's side still a soft pill so the transcript reads at a glance.
   Message rows print no avatars (flush text is the look) EXCEPT the
   typing row - see below, where the face is half the signal. */
#eh-chat-slot .eh-chat-row { align-items: flex-start; margin-bottom: 16px; }
#eh-chat-slot .eh-chat-row .eh-chat-avatar { display: none; }
/* (1,2,0) beats the (1,1,0) hide above by ID-count arithmetic. */
#eh-chat-slot #eh-chat-typing .eh-chat-avatar {
    display: inline-flex;
    background: #FFEFCC url('../images/eholidayer-mark.svg') center / 72% no-repeat;
    border: 1px solid rgba(249, 171, 0, .35);
}
/* Typing dots, made unmistakable (owner 2026-10-17, point 5: "make it
   more visible"). Measured cause: the stock dots are 7px of
   var(--eh-sand-deep) #E2E6E5 animating at 60% opacity ON a white
   bubble - #E2E6E5 against #FFF is a 1.08:1 contrast ratio, the dots
   were effectively invisible, which is exactly why nobody believed
   Era was answering. These: 10px solid brand blue, deep bounce on
   their own keyframes, on a warm cream bubble that separates the
   "thinking" moment from Era's plain-text answers. (1,4,1) outranks
   aiagent.css's (0,2,1) dot rule wherever the bubble lands. */
#eh-chat-slot .eh-chat-assistant .eh-chat-bubble.eh-chat-typing {
    padding: 15px 18px;
    background: #FFF9EC;
    border: 1px solid #F3E2B6;
    box-shadow: none;
    gap: 6px;
}
#eh-chat-slot .eh-chat-assistant .eh-chat-bubble.eh-chat-typing span {
    width: 10px;
    height: 10px;
    background: var(--eh-coral);
    animation: ehd-typing-bounce 1.1s ease-in-out infinite;
}
#eh-chat-slot .eh-chat-assistant .eh-chat-bubble.eh-chat-typing span:nth-child(2) { animation-delay: .18s; }
#eh-chat-slot .eh-chat-assistant .eh-chat-bubble.eh-chat-typing span:nth-child(3) { animation-delay: .36s; }
@keyframes ehd-typing-bounce {
    0%, 55%, 100% { transform: translateY(0);    opacity: 1; }
    25%           { transform: translateY(-7px); opacity: .55; }
}
#eh-chat-slot .eh-chat-assistant .eh-chat-bubble {
    max-width: 100%;
    padding: 0 2px;
    background: transparent;
    box-shadow: none;
}
#eh-chat-slot .eh-chat-user .eh-chat-bubble { background: var(--eh-sand); box-shadow: none; }

#eh-chat-slot .eh-chat-form {
    border-top: 1px solid var(--eh-sand-deep);
    padding: 12px 16px max(12px, env(safe-area-inset-bottom));
}
#eh-chat-slot .eh-chat-input {
    border-radius: 18px;
    border-color: #E3E1DC;
    padding: 12px 16px;
}
#eh-chat-slot .eh-chat-input:focus { outline: 2px solid var(--eh-coral); }
#eh-chat-slot .eh-chat-send {
    border-radius: 14px;
    padding: 12px 18px;
    background: var(--eh-teal);
}
#eh-chat-slot .eh-chat-send:hover { background: #0F212C; }
#eh-chat-slot .eh-chat-chip:hover { background: var(--eh-sand); }

@media (prefers-reduced-motion: reduce) {
    .ehd-assist-badge-dot { animation: none; }
    /* The typing dots' stronger animation must stop here too - the
       stock one is killed by aiagent.css, but ehd-typing-bounce is new
       to this file and outranks that guard on specificity, so it needs
       its own stop or it would bounce for motion-sensitive users. */
    #eh-chat-slot .eh-chat-bubble.eh-chat-typing span { animation: none; opacity: 1; }
}

/* ---- feature band (includes/eholidayer-home.php) ----
   Owner picked the four-column strip as the target look (2026-10-17,
   point 4, mock-up scr/2026-10-10_152117 - Copy.png): a thin rule over
   each column, a bold near-black headline, one muted sentence under
   it, left-aligned, no icons. It replaces the old centered row of
   three promises; the copy is the AI_FEAT_* set already in the
   language file. The strip is a grid, not flex: the mock-up's columns
   are equal-width cells, which is what repeat(4,1fr) gives - flex
   would let the widest sentence stretch its own column. */
.ehd-reassure {
    padding: var(--sp-8) var(--gutter) var(--sp-9);
    background: var(--canvas);
    font-family: var(--font-ui);
}
.ehd-reassure-grid {
    max-width: 1180px;
    margin: 0 auto;
    display: grid;
    grid-template-columns: repeat(4, 1fr);
    gap: var(--sp-6) var(--sp-9);
}
.ehd-reassure-col {
    border-top: 2px solid var(--hairline);
    padding-top: var(--sp-4);
}
.ehd-reassure-h {
    margin: 0 0 6px;
    font: 600 15.5px/1.3 var(--font-ui);
    color: var(--eh-coral); /* owner 2026-10-17 round 2, point 2: brand blue */
}
.ehd-reassure-p {
    margin: 0;
    font: 400 13.5px/1.55 var(--font-ui);
    color: var(--text-secondary);
}
@media (max-width: 899px) {
    .ehd-reassure-grid { grid-template-columns: repeat(2, 1fr); }
}

/* ---- trust counters (mod_mscounter) — the mock-up trust band ----
   mscounter.css is the vanilla module skin (grey box, #004071 figures).
   The module markup (icon / counter / title) already matches the
   mock-up's .ehd-trust shape; this restyle flattens the grey box into
   a hairline band with Inter + tabular figures, and keeps the REAL
   live counts (1 / 3 / 5 / 9) — never the mock-up's fake
   45 / 108 / 90 / 500. */
.frontpage-wrapper {
    background: var(--canvas);
    border-top: 1px solid var(--hairline);
    border-bottom: 1px solid var(--hairline);
    padding-top: var(--sp-6);
    padding-bottom: var(--sp-6);
    margin-top: var(--sp-12);
}
.frontpage-wrapper .msc_wrap {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: center;
    gap: var(--sp-5) var(--sp-12);
}
.frontpage-wrapper .msc_box {
    flex: 0 1 auto;
    display: flex;
    align-items: center;
    gap: var(--sp-2);
    margin: 0;
    padding: 0;
    background: none;
    border-radius: 0;
    text-align: left;
    font-family: var(--font-ui);
    color: var(--ink-display);
}
.frontpage-wrapper .msc_icon {
    margin: 0;
    width: auto;
    font-size: 18px;
    color: var(--text-secondary);
}
.frontpage-wrapper .msc_counter {
    margin: 0;
    font-size: clamp(22px, 4vw, 28px);
    font-weight: 600;
    line-height: 1.1;
    font-variant-numeric: var(--tnum);
    color: var(--ink-display);
}
.frontpage-wrapper .msc_title {
    margin: 0;
    font-size: 14px;
    color: var(--text-secondary);
}

@media (max-width: 560px) {
    .ehd-reassure-grid { grid-template-columns: 1fr; }
    .frontpage-wrapper .msc_wrap { gap: var(--sp-4) var(--sp-8); }
}

/* ---------------------------------------------------------- chat chrome
   Owner round 2 (2026-10-17), points 3-5. The panel is fixed in the page,
   so it reads as a card of the site rather than a floating tooltip: a
   blue hairline frame plus a deeper drop, chips picked up in the two
   accent colours the brand already uses (blue, Era-amber) instead of
   the invisible white-on-white they were, and Send on the brand blue
   the base sheet already expected from --eh-coral. All rules are
   #eh-chat-slot-scoped so they can never touch a future floating
   variant of the widget. */
#eh-chat-slot .eh-chat-panel {
    border: 1.5px solid rgba(66, 133, 244, .45);
    box-shadow: 0 20px 50px rgba(23, 46, 59, .16), 0 2px 10px rgba(23, 46, 59, .08);
}
#eh-chat-slot .eh-chat-chip {
    background: var(--eh-teal-soft);           /* #E8F0FE */
    border: 1px solid rgba(66, 133, 244, .38);
    color: var(--eh-coral-dark);               /* #1A73E8 */
}
#eh-chat-slot .eh-chat-chip:hover {
    background: var(--eh-coral);
    border-color: var(--eh-coral);
    color: #fff;
}
/* Every third chip (middle of each row of three) wears the amber side
   of the palette, so the row reads colourful, not monochrome. */
#eh-chat-slot .eh-chat-quick .eh-chat-chip:nth-child(3n+2) {
    background: #FFF6DE;
    border-color: rgba(249, 171, 0, .5);
    color: #8A5B00;
}
#eh-chat-slot .eh-chat-quick .eh-chat-chip:nth-child(3n+2):hover {
    background: #F9AB00;
    border-color: #F9AB00;
    color: #172E3B;
}
#eh-chat-slot .eh-chat-send { background: var(--eh-coral); }
#eh-chat-slot .eh-chat-send:hover { background: var(--eh-coral-dark); }