/* Salve — mobile app layer. ADDITIVE ONLY: every rule lives behind a media query, so
   desktop rendering is byte-for-byte untouched. The same server-rendered pages become
   an app-like experience on phones: the sidebar turns into a fixed bottom tab bar,
   lists go full-bleed, targets grow to thumb size, and safe-area insets are respected.
   Pairs with the PWA manifest + service worker so "Add to Home Screen" launches Salve
   standalone (no browser chrome), which is what makes it feel like a real app. */

/* Cross-page navigations animate like native screen pushes (Safari 18+/Chrome 126+,
   older browsers just navigate normally). For a server-rendered app this is the single
   biggest "feels native" win: tapping an inquiry slides to it instead of flashing. */
@view-transition { navigation: auto; }

/* ---------- tablet / narrow desktop (821px - 1100px): icon-rail sidebar ----------
   Between the phone layout and full desktop the 222px labelled sidebar crushes the
   content. Collapse it to a 64px icon rail (the iPad-app pattern): glyphs centered,
   labels hidden via the font-size-0 trick (nav labels are bare text nodes), badges
   float on the icon corner. Everything else inherits desktop styles. */
@media (min-width: 701px) and (max-width: 1100px) {
  html, body { overflow-x: hidden; }
  .side { width: 64px; padding: 14px 8px; }
  .brand-row { justify-content: center; padding-right: 0; }
  .brand-row .wm { display: none; }
  .nav a, .foot-link {
    gap: 0; justify-content: center; padding: 11px 0; position: relative;
  }
  .nav a i, .foot-link i { font-size: 21px !important; }
  .nav a.on::before, .foot-link.on::before { left: -8px; }
  .nav .badge {
    position: absolute; top: 2px; right: 4px; margin: 0;
    font-size: 10px; min-width: 16px; height: 16px; padding: 0 4px;
    z-index: 2;
  }
  /* rail = icons only, labels off across the board */
  .nav-lab, .foot-link-lab { display: none; }
  /* avatar stacks over sign-out, centered in the rail */
  .acct { flex-direction: column; gap: 4px; padding: 8px 0 2px; justify-content: center; align-items: center; }
  .acct .who { display: none; }
  .acct form { margin: 0 !important; }

  /* hover tooltips replace the hidden labels (rail widths are mouse territory) */
  .nav a, .foot-link, .logout-btn { position: relative; }
  [data-tip]:hover::after {
    content: attr(data-tip);
    position: absolute; left: calc(100% + 12px); top: 50%; transform: translateY(-50%);
    background: var(--ink); color: var(--bg); font-size: 11.5px; font-weight: 600;
    padding: 5px 10px; border-radius: 7px; white-space: nowrap; z-index: 500;
    box-shadow: var(--shadow-md); pointer-events: none;
  }
  /* conversation header: the name owns its space; actions wrap below when tight
     instead of squashing the title into a two-line sliver */
  .ihead { flex-wrap: wrap; row-gap: 8px; }
  /* guaranteed air between the name block and the action buttons */
  .ihead .col-min { flex: 1 1 auto; min-width: 200px; padding-right: 14px; }
  .ihead .meta { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; max-width: 100%; }
  /* roomier content paddings for the narrower canvas */
  .head { padding: 16px 18px 12px; }
  .wrap { padding: 14px 18px 48px; }
  .list { padding: 12px 16px 36px; }
  .week { padding: 6px 16px 48px; }
  .msgs { padding: 18px 18px 8px; }
}

/* ---------- AI panel as an off-canvas drawer (rail + phone widths) ----------
   The fixed side column squeezed the thread anywhere under full desktop. Below 1100px
   it slides in from the right; the sparkle tab attached to its edge stays on screen
   and toggles it. The composer also slims down, the thread is the star. */
@media (max-width: 1100px) {
  .ai-panel {
    position: fixed; top: 0; right: 0; bottom: 0; z-index: 350;
    display: block; width: min(330px, 88vw);
    border-left: 1px solid var(--border); background: var(--surface);
    overflow-y: auto; padding: 18px 16px calc(26px + env(safe-area-inset-bottom));
    transform: translateX(calc(100% + 2px)); transition: transform .25s ease;
  }
  .ai-panel.open { transform: none; box-shadow: var(--shadow-lg); }
  /* the tab is fixed to the viewport edge (NOT inside the scrolling panel, which would
     clip it) and slides left in step with the panel when open */
  .ai-drawer-tab {
    position: fixed; right: 0; top: 50%; transform: translateY(-50%); z-index: 360;
    width: 44px; height: 62px; border: none; border-radius: 13px 0 0 13px;
    background: var(--ink); color: var(--bg); cursor: pointer;
    display: flex; align-items: center; justify-content: center; font-size: 20px;
    box-shadow: var(--shadow-md); transition: right .25s ease;
  }
  .ai-drawer-tab.open { right: min(330px, 88vw); }
  .composer { padding: 10px 14px calc(12px + env(safe-area-inset-bottom)); }
  /* content-sized like desktop (app.css), just a tighter floor and cap on phones */
  .composer-email textarea { min-height: 64px; max-height: 32vh; }
  .reply-box textarea { min-height: 46px; }
}
@media (min-width: 1101px) { .ai-drawer-tab { display: none; } }

@media (max-width: 700px) {

  /* native touch feel: no grey tap flashes, no double-tap zoom delay, chrome
     (nav, headers, buttons) isn't text-selectable like a web page */
  * { -webkit-tap-highlight-color: transparent; }
  body { touch-action: manipulation; -webkit-text-size-adjust: 100%; }
  /* a single over-wide element must never drag the whole layout sideways */
  html, body { overflow-x: hidden; }
  .side, .head, .ihead, .btn, .icon-btn, .toggle, .seg, .status { -webkit-user-select: none; user-select: none; }

  /* ---------- shell: sidebar becomes the bottom tab bar ---------- */
  .app { display: block; }
  .side {
    position: fixed; left: 0; right: 0; bottom: 0; top: auto; z-index: 300;
    width: 100%; height: auto; flex-direction: row; align-items: stretch;
    padding: 6px 8px calc(6px + env(safe-area-inset-bottom));
    border-right: none; border-top: 1px solid var(--border);
    box-shadow: 0 -10px 28px -14px rgba(20, 14, 6, .22);
  }
  .side .brand-row { display: none; }
  .side .nav { flex-direction: row; flex: 1; gap: 2px; }
  .nav a {
    flex: 1; flex-direction: column; gap: 3px; justify-content: center;
    padding: 7px 2px; font-size: 10.5px; font-weight: 600; border-radius: 12px;
    min-height: 52px;
  }
  .nav a i { font-size: 22px !important; }
  .nav a.on { background: none; }
  .nav a.on i { color: var(--acc); }
  /* the desktop side-line becomes a short pink underline bar at the top of the tab */
  .nav a.on::before {
    left: 50%; right: auto; top: 0; bottom: auto; transform: translateX(-50%);
    width: 28px; height: 3px; border-radius: 0 0 3px 3px; background: var(--acc);
  }
  .nav .badge {
    position: absolute; top: 3px; left: calc(50% + 4px); margin: 0;
    min-width: 17px; height: 17px; font-size: 10px; padding: 0 5px;
    background: var(--acc); color: #fff; z-index: 2;
  }
  /* Settings is a first-class tab; the account chip collapses to just the sign-out
     glyph. All five items share the width evenly, nothing squashes at the edge. */
  .side .nav { flex: 3; }
  .side .foot { display: flex !important; border-top: none; padding-top: 0; flex-direction: row; align-items: stretch; gap: 0; flex: 1.7; }
  .foot-link {
    display: flex; flex: 1; min-width: 0;
    flex-direction: column; gap: 3px; align-items: center; justify-content: center;
    padding: 7px 4px; font-size: 10.5px; font-weight: 600; min-height: 52px;
  }
  /* tab labels always visible on the phone bar */
  .nav-lab, .foot-link-lab { display: block; font-size: 10.5px; line-height: 1; }
  .foot-link i { font-size: 22px !important; }
  .foot-link.on { background: none; }
  .foot-link.on i { color: var(--acc); }
  /* same pink underline bar as the nav tabs — Settings is a first-class tab */
  .foot-link.on::before {
    left: 50%; right: auto; top: 0; bottom: auto; transform: translateX(-50%);
    width: 28px; height: 3px; border-radius: 0 0 3px 3px; background: var(--acc);
  }
  .acct { padding: 0; display: flex; align-items: center; justify-content: center; flex: 0.7; }
  .acct .av, .acct .who { display: none; }
  .acct form { margin: 0 !important; }
  .logout-btn { padding: 7px 8px; min-height: 52px; }
  .logout-btn i { font-size: 20px; }

  /* every page leaves room for the tab bar */
  .main { padding-bottom: calc(76px + env(safe-area-inset-bottom)); }

  /* ---------- page chrome ---------- */
  /* Headers with back link + identity + actions (contact page etc.) wrap into rows
     instead of compressing the title: the spacer acts as a line break, so badges and
     action buttons drop to their own row below the name. */
  .head { padding: 13px 16px 11px; gap: 8px 10px; position: sticky; top: 0; background: var(--bg); z-index: 60; flex-wrap: wrap; }
  .head .spacer { flex-basis: 100%; height: 0; flex-grow: 0; }
  /* calendar header: the connected pill fits beside the title, no need to drop it */
  .head-cal .spacer { flex-basis: auto; height: auto; flex-grow: 1; }
  .head-cal .gcal { font-size: 11.5px; }
  .head .head-titles { min-width: 0; flex: 1; }
  .head h1 { font-size: 20px; overflow-wrap: anywhere; }
  .head .count { font-size: 12px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; max-width: 100%; }
  .wrap { padding: 12px 13px 36px; }
  .list { padding: 10px 11px 28px; }
  .week { padding: 6px 11px 40px; }

  /* iOS zooms the page when a focused input is under 16px, which shatters the app
     illusion. Every text control reads at 16px on phones. */
  input:not([type="checkbox"]):not([type="radio"]), textarea, select { font-size: 16px !important; }

  /* comfortable thumb targets without redesigning every button */
  .btn-sm { padding: 9px 14px; min-height: 38px; }
  .icon-btn { width: 36px; height: 36px; flex-basis: 36px; }

  /* ---------- inbox ---------- */
  .iq { padding: 12px 12px; gap: 10px; border-radius: 13px; }
  .iq .sm { font-size: 12.5px; }
  .feed-toolbar { flex-wrap: wrap; gap: 8px; }

  /* ---------- conversation ---------- */
  /* Native pattern: detail screens hide the tab bar (there's a back link), which gives
     the composer the whole bottom edge instead of being cut off behind the tabs. */
  body:has(.main.detail) .side { display: none; }
  .main.detail { padding-bottom: 0; height: 100dvh; } /* dvh: Safari's collapsing bar never clips the composer */
  .ihead { padding: 10px 12px; gap: 8px 9px; flex-wrap: wrap; position: sticky; top: 0; z-index: 60; }
  .ihead .col-min { padding-right: 12px; }
  /* the spacer becomes a line break: identity row on top, actions (Book, waitlist,
     status) as their own clean second row instead of squeezing then dangling */
  .ihead .spacer { flex-basis: 100%; height: 0; flex-grow: 0; }
  .ihead .nm { font-size: 15px; }
  .ihead .meta { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; max-width: 52vw; }
  .ihead .back { font-size: 13px; }
  .iwrap { flex-direction: column; }
  .thread { min-height: 0; flex: 1; }
  .msgs { padding: 14px 13px 8px; }
  .msg { max-width: 88%; }
  .msg-media { max-width: 220px; max-height: 220px; }
  .composer { padding: 10px 12px calc(12px + env(safe-area-inset-bottom)); }
  /* (the AI panel drawer for small screens lives in the shared <=1100px block below) */

  /* ---------- settings & cards ---------- */
  .trust-banner { padding: 12px 14px; }
  .chan-row { flex-wrap: wrap; row-gap: 8px; }
  .auto { flex-wrap: wrap; row-gap: 10px; }
  /* when a card's action wraps below the text, it always lands bottom-RIGHT,
     whatever the card's markup (bare button, row-r wrapper, or form) */
  .auto > .btn, .auto > .row-r, .auto > form, .chan-row .row-r { margin-left: auto; }
  .sheet { padding: 18px 16px calc(18px + env(safe-area-inset-bottom)); }
  /* modals become bottom sheets, the native-app gesture language. Sheets taller than
     the screen scroll INSIDE themselves, and the close X rides sticky at the top so
     it can never scroll out of reach (the booking calendar was uncloseable without it). */
  /* overlay must beat the sticky page header (z60), tab bar (300) and drawer tab (360) */
  .ov { place-items: end center; padding: 0; z-index: 400; }
  .ov .sheet {
    width: 100%; max-width: 100%; border-radius: 20px 20px 0 0; border-bottom: none;
    max-height: calc(100dvh - 12px); overflow-y: auto;
  }
  /* block-level sticky (float kills stickiness): the X rides the top edge while the
     sheet scrolls, always one tap away */
  .sheet .sheet-x {
    position: sticky; top: 0; z-index: 20; float: none;
    display: flex; margin-left: auto; width: fit-content;
    background: var(--surface); border-radius: 10px; padding: 8px 10px;
    box-shadow: 0 0 0 6px var(--surface);
  }

  /* ---------- services page grids ---------- */
  .svc-grid { grid-template-columns: 20px 1fr 58px 58px 48px 46px 28px; gap: 5px; }
  .svc-grid input[type="text"], .svc-grid input[type="number"] { padding: 7px 7px; }
  .svc-grid-s { grid-template-columns: 1fr 52px 52px 46px 46px 32px 32px; gap: 5px; }
  .svc-grid-head { font-size: 10px; letter-spacing: .02em; }
  .svc-name { font-size: 13.5px; }
  .svc-meta { font-size: 12.5px; }

  /* ---------- onboarding checklist ---------- */
  .onb-card { padding: 15px 14px; }
  .onb-step { gap: 10px; }
  .onb-step .row-r .btn { padding: 8px 12px; }

  /* ---------- banners & action rows, the systematic pass ----------
     Shared pattern: rows that are [icon][text][buttons...] on desktop wrap on phones
     into text-first, full-width, with the button group on its own line, right-aligned. */

  /* follow-ups due (contacts page): Snooze / Dismiss / Draft nudge drop below the text */
  .fu { flex-wrap: wrap; row-gap: 8px; padding: 12px 13px; }
  .fu .info { flex: 1 1 0; min-width: calc(100% - 56px); }
  .fu form:first-of-type, .fu .manage:first-of-type { margin-left: auto; }
  .fu .info .nm { font-size: 14px; }

  /* provisional-bookings banner (calendar): confirm/cancel below each row's text */
  .prov-row { flex-wrap: wrap; row-gap: 8px; }
  .prov-row-info { flex: 1 1 100%; }
  .prov-row form, .prov-row .btn { margin-left: 0; }
  .prov-row form:first-of-type { margin-left: auto; }

  /* contacts list rows + contact detail cards: wrap, CTA pins right when it drops */
  .ct { flex-wrap: wrap; row-gap: 8px; padding: 12px 13px; gap: 11px; }
  .ct .ct-contact, .ct > form { margin-left: auto; }
  .ct-auto-banner, .ct-thread-head { flex-wrap: wrap; row-gap: 8px; }
  .ct-card { padding: 13px 13px; }

  /* calendar events on phones, agenda grid:
       16:00 | [31] Dentistry — Nick Pomodoro
             |      30 min · [Nick Pomodoro]
             | [Completed] [link / add actions]
     Time is its OWN column, nothing ever sits under it; icon + title head the content
     column; the foot row (chip + actions) aligns under the content. */
  .ev {
    display: grid; grid-template-columns: 46px 30px minmax(0, 1fr);
    column-gap: 10px; row-gap: 11px; align-items: center; padding: 13px 14px;
  }
  .ev .t { grid-row: 1; grid-column: 1; }
  .ev .bar-i { display: none; }
  .ev .ch { grid-row: 1; grid-column: 2; }
  .ev .info { grid-row: 1; grid-column: 3; min-width: 0; }
  .ev .info .ti { font-size: 15px; overflow-wrap: anywhere; }
  .ev .info .mt { margin-top: 4px; }
  .ev .ev-foot { grid-column: 2 / 4; display: flex; flex-wrap: wrap; gap: 8px; align-items: center; }
  .ev .cal-chip { font-size: 11.5px; padding: 5px 11px; flex-shrink: 0; }
  /* the link-contact popover anchors to the CARD (not the tiny button), so it always
     opens inside the screen, spanning the card width just below the row */
  .ev .ev-link { position: static; }
  .ev .ev-link-menu { left: 8px; right: 8px; min-width: 0; max-width: none; }
  .day-h { flex-wrap: wrap; }
  /* any other dropdown stays inside the viewport */
  .cg-select-menu { max-width: calc(100vw - 28px); }

  /* connect pages: dry-run banner + step lists */
  .fu-banner { flex-wrap: wrap; padding: 11px 13px; }
  .provider-grid { grid-template-columns: 1fr; }

  /* insights stats: one column */
  .stats-row, .stat-grid { grid-template-columns: 1fr 1fr; }
  .stat-big { font-size: 26px; }

  /* segmented toolbars: never overflow, counts shrink */
  .seg { max-width: 100%; overflow-x: auto; }
  .seg a { padding: 6px 9px; font-size: 12.5px; white-space: nowrap; }

  /* ---------- misc fluidity ---------- */
  .stats-in, .hero-in { padding-left: 14px; padding-right: 14px; }
  .empty { padding: 26px 18px; }
  .placeholder { padding: 48px 18px; }
}

/* small phones: the page subtitle eats two rows under the h1 (ported from the
   removed legacy layer, the one idea worth keeping) */
@media (max-width: 540px) {
  .head .count { display: none; }
}

/* Standalone (installed) mode: the page IS the app window. Kill overscroll rubber-band
   showing the body background behind the UI, and let content sit under the iOS status
   bar area cleanly. */
@media (display-mode: standalone) {
  html, body { overscroll-behavior-y: none; }
  .head { padding-top: calc(13px + env(safe-area-inset-top)); }
  .ihead { padding-top: calc(10px + env(safe-area-inset-top)); }
}
