/* West Coast In-Home — staff console + applicant tracker, compact widths.
 * ============================================================================
 *
 * The admin half of the responsive system. Loaded by the two staff shells —
 * admin_base.html (console) and ats_base.html (tracker SPA) — and, since
 * 2026-11-05, by the caregiver app's shell (wci_app/app_base.html), which
 * wears the console's bar and takes the bottom-bar rules from here so the
 * two cannot drift. The public site never fetches it, so nothing here may
 * be something it needs; that belongs in wci-core.css.
 *
 * FOR THE CAREGIVER APP, that means: a change to .wci-bottom-nav,
 * .wci-bnav-item or the body padding below lands on app.westcoastinhome.com
 * too. Everything else in this file is scoped to the tracker's classes
 * (.ats-*), Bootstrap's (.modal, .table, .btn-sm…) or <dialog>, none of
 * which that app has. Keep new rules scoped the same way; a bare element
 * selector added here now reaches caregivers' phones.
 *
 * ── CASCADE POSITION: THIS FILE LOADS LAST ──────────────────────────────────
 *
 * After Bootstrap, after each shell's inline <style>, and after
 * navbar_styles() from _admin_sections.html. That is deliberate and is the
 * opposite of wci-core.css, which loads first as a base layer.
 *
 * It has to be last because it RESHAPES things those layers built: the fixed
 * navbar becomes a brand-and-identity bar at compact widths, Bootstrap modals
 * become full-screen sheets, and the SPA app-shell has to reserve room for a
 * bottom bar that did not exist when ats_base.html computed its padding.
 *
 * The cost of loading last is that it can stomp a page's own CSS. That is why
 * nearly every rule here sits inside @media (max-width:767.98px) — above that
 * breakpoint this file is very nearly empty, and desktop is untouched.
 *
 * ── WHAT LIVES WHERE ────────────────────────────────────────────────────────
 *
 * Markup for the bottom nav is a macro in _admin_sections.html, NOT here —
 * that file is THE staff navbar and CLAUDE.md is explicit that it must not be
 * forked. The macro is parameterised; this file only styles what it emits.
 *
 * Breakpoints are Bootstrap 5's scale. See the header of wci-core.css and
 * docs/RESPONSIVE.md.
 */

/* ── The compact-width bottom tab bar ───────────────────────────────────────
   Markup is the bottom_nav() macro in _admin_sections.html. Both rules below
   — hiding the top link strip and showing this bar — live in THIS file on
   purpose, so that a failure to load the stylesheet reverts both together to
   the pre-2026-09-11 layout rather than leaving a page with no navigation.

   .wci-bottom-nav is measured at runtime by _setChromeOffsets() in
   index.html into --ats-bottomnav-h. Renaming the class silently breaks the
   SPA app-shell's height maths — the same contract .wci-nav carries. */
@media (max-width:767.98px){
  .wci-nav-links{display:none}

  .wci-bottom-nav{
    display:flex;
    position:fixed;
    left:0; right:0; bottom:0;
    z-index:1035;               /* above .wci-nav's 1030, below modals */
    align-items:stretch;
    background:#fff;
    border-top:1px solid var(--hairline,#e5e7eb);
    box-shadow:0 -1px 3px rgba(0,0,0,.05);
    /* The bar grows by the bottom inset rather than padding its contents,
       so the home indicator never sits on top of a tap target. Matches how
       .wci-nav handles the top inset. */
    height:calc(var(--wci-bottomnav-h) + env(safe-area-inset-bottom));
    padding-bottom:env(safe-area-inset-bottom);
    padding-left:env(safe-area-inset-left);
    padding-right:env(safe-area-inset-right);
  }

  /* The bar scrolls sideways rather than collapsing into a "More" sheet,
     so every section stays one tap away. Items size to their content with
     a sensible floor: at seven sections on a 375px phone that is a little
     wider than the screen, which shows a sliver of the next item — the
     affordance that says "there is more this way". */
  .wci-bottom-nav{
    overflow-x:auto;
    overflow-y:hidden;
    scrollbar-width:none;              /* Firefox */
    scroll-snap-type:x proximity;
  }
  .wci-bottom-nav::-webkit-scrollbar{ display:none; }

  .wci-bnav-item{
    flex:0 0 auto;
    min-width:4.6rem;
    scroll-snap-align:center;
    display:flex;
    flex-direction:column;
    align-items:center;
    justify-content:center;
    gap:3px;
    padding:6px 2px;
    text-decoration:none;
    color:var(--muted,#6c757d);
    font-family:'Inter',sans-serif;
    font-size:.625rem;
    font-weight:600;
    line-height:1.1;
    list-style:none;            /* it is a <summary> in the More slot */
    cursor:pointer;
    -webkit-tap-highlight-color:transparent;
  }
  .wci-bnav-item::-webkit-details-marker{display:none}
  .wci-bnav-item svg{width:19px; height:19px; flex:0 0 auto; opacity:.7}
  .wci-bnav-item:hover{color:var(--navy,#163B5C); text-decoration:none}

  .wci-bnav-item.is-active{color:var(--navy,#163B5C)}
  .wci-bnav-item.is-active svg{opacity:1}
  /* The active marker sits on the TOP edge, pointing back at the content
     it belongs to, rather than under the label next to the home indicator. */
  .wci-bnav-item.is-active::before{
    content:"";
    position:absolute;
    top:0;
    width:26px;
    height:2px;
    border-radius:0 0 2px 2px;
    background:var(--navy,#163B5C);
  }
  .wci-bnav-item{position:relative}

  .wci-bnav-item.is-planned{color:var(--faint,#8a94a3)}
  .wci-bnav-item.is-planned svg{opacity:.45}

  /* The "planned" dot is a third flex row in a column layout, which reads
     as a stray speck under the label. Pin it to the icon as a badge — same
     meaning, and it stops the slot's height depending on whether a section
     happens to be built yet. */
  .wci-bnav-item .wci-planned-dot{
    position:absolute;
    top:5px;
    left:50%;
    margin-left:7px;
  }

  .wci-bnav-label{
    max-width:100%;
    overflow:hidden;
    text-overflow:ellipsis;
    white-space:nowrap;
  }

  /* The "More" overflow sheet (.wci-bnav-more / .wci-bnav-sheet) lived
     here until 2026-09-12. The bar scrolls sideways now, so every section
     is one tap away instead of half of them being behind a guess about
     which half matters. Its markup went with it. */

  /* ── Clearing the bar ─────────────────────────────────────────────────
     Ordinary console pages scroll the document, so the body needs padding
     or the footer ends up underneath the bar.

     The SPA does NOT scroll the document — ats_base.html pins body to
     100dvh with overflow:hidden — so the same padding-bottom correctly
     shortens <main>, and the panels, which are flex children of it, resize
     to match. One rule covers both shells. */
  body{
    padding-bottom:calc(var(--wci-bottomnav-h) + env(safe-area-inset-bottom));
  }

  /* Anything the page fixes to the bottom — the unsaved-changes bar, the
     coverage-map action bar — clears the nav by reading this rather than
     hard-coding a number that goes stale the moment the bar's height
     changes. Zero above the breakpoint, where there is no bottom nav. */
  :root{ --wci-bottom-gap:var(--wci-bottomnav-h,64px); }

  /* An in-page anchor otherwise scrolls its target under the fixed top
     bar. The profile pages jump between sections constantly. */
  [id]{ scroll-margin-top:calc(var(--wci-nav-h,64px) + 12px); }
}

/* ── Modals fit the screen ──────────────────────────────────────────────────
   Every dialog in the console sets a max-width and none set a max-height, so
   a form taller than the phone runs off the bottom with nothing to scroll —
   the Save button is simply unreachable. The UA default caps the box but
   does not make it scrollable, which is the half that matters.

   dvh, not vh: on a phone vh is the LARGE viewport, so a "full height"
   dialog is taller than what you can actually see whenever the browser's
   chrome is showing (docs/RESPONSIVE.md).

   This lives here, after the templates' own <style> blocks, but only sets
   properties none of them declare — `dialog` is one tag's worth of
   specificity, so `dialog.sc-modal` still wins everything it asks for. */
dialog{
  max-height:calc(100dvh - 2rem);
  /* VERTICAL ONLY. `overflow:auto` sets both axes, and a modal that scrolls
     sideways is worse than a page that does — it is a small box with no
     visible edge to tell you there is more, and the thing out there is
     usually the Save button.

     Spelling out overflow-y is not optional either: CSS computes an
     `overflow-x:visible` to `auto` as soon as the other axis is not visible,
     so "I only set overflow-y" silently buys a horizontal scrollbar too.
     That is how this rule shipped last week creating the very problem it
     was added to prevent. hidden-then-clip so anything too old to know
     `clip` still clips. */
  overflow-y:auto;
  overflow-x:hidden;
  overflow-x:clip;
  /* Names, emails and addresses come from the database, and an unbroken one
     has no break opportunity — it just sticks out. `anywhere` rather than
     `break-word` because only `anywhere` shrinks the min-content size, which
     is what lets a flex or grid child actually give way. */
  overflow-wrap:anywhere;
  overscroll-behavior:contain;
  -webkit-overflow-scrolling:touch;
}

/* ── Tracker chrome at compact widths ───────────────────────────────────────
   .ats-chrome stacks the page header, four stat chips and fourteen pill tabs
   ABOVE the panel below 992px (the sidebar flip). Left alone on a phone that
   is roughly 300px of furniture before a single applicant is visible — on a
   667px-tall screen, minus the navbar and the bottom bar, it eats more than
   half of what is left.

   The specific culprit is flex-wrap:wrap on both rows. Fourteen pills at
   375px wrap to five rows, and four stat chips to two or three. Wrapping is
   the right call on a tablet and actively wrong on a phone, where one
   scrolling row is both smaller and easier to use.

   Net effect: ~300px of chrome becomes ~100px. */
@media (max-width:767.98px){
  .ats-chrome{padding:.6rem .85rem 0}

  /* Header: one row, no wrap. The subtitle is pure explanation and the
     first thing that should go; the title, reload and Add all stay. */
  .ats-chrome .ats-page-header{margin-bottom:.5rem}
  .ats-chrome .ats-page-header > .d-flex{
    flex-wrap:nowrap !important;
    align-items:center !important;
    gap:.5rem;
  }
  .ats-chrome .ats-page-subtitle{display:none}
  .ats-chrome .ats-page-title{font-size:1.15rem}

  /* Keep "Add applicant" on the title row rather than letting it wrap to a
     line of its own — a whole row for one button is the kind of thing that
     made the chrome 300px tall. */
  .ats-chrome .ats-page-header .btn{
    white-space:nowrap;
    padding-left:.7rem;
    padding-right:.7rem;
    font-size:.8rem;
  }

  /* Stat chips: one scrolling row instead of two or three wrapped ones.
     overscroll-behavior-x:contain stops a horizontal fling here turning
     into a browser back-navigation. */
  .ats-chrome .ats-stat-row{
    flex-wrap:nowrap;
    overflow-x:auto;
    overflow-y:hidden;
    overscroll-behavior-x:contain;
    -webkit-overflow-scrolling:touch;
    scrollbar-width:none;
    margin:.4rem 0 .5rem;
    padding-bottom:2px;
  }
  .ats-chrome .ats-stat-row::-webkit-scrollbar{display:none}
  .ats-chrome .ats-stat{flex:0 0 auto}

  /* Pill tabs: one scrolling row. This is the big saving. */
  .ats-chrome .ats-tabs{
    flex-wrap:nowrap;
    overflow-x:auto;
    overflow-y:hidden;
    overscroll-behavior-x:contain;
    -webkit-overflow-scrolling:touch;
    scrollbar-width:none;
    margin-bottom:.5rem;
  }
  .ats-chrome .ats-tabs::-webkit-scrollbar{display:none}
  .ats-chrome .ats-tabs .nav-item{flex:0 0 auto}
  .ats-chrome .ats-tabs .nav-link{white-space:nowrap}

  /* scroll-margin gives scrollIntoView() breathing room so the active pill
     never lands flush against the edge where it reads as cut off.
     _scrollActiveTabIntoView() in index.html does the scrolling. */
  .ats-chrome .ats-tabs .nav-link{scroll-margin-inline:2rem}

  .ats-panel{padding:.7rem .85rem 1.25rem}
}

/* ── SPA app-shell: the panel overflow trap ─────────────────────────────────
   index.html gives every .ats-panel `overflow-y:auto; overflow-x:hidden`.
   Mixing the two axes like that makes the panel a scroll container on BOTH,
   but only the vertical one is user-scrollable — so anything wider than the
   panel is CLIPPED AND UNREACHABLE rather than reachable by swiping.

   Keeping overflow-x:hidden is right: without it the whole SPA slides
   sideways, which feels broken. The fix is to stop content being wider than
   the panel in the first place.

   Audited 2026-09-11: the wide tables all sit in .table-responsive and scroll
   inside their own wrapper, and the three <pre> blocks either already set
   pre-wrap/break-word or carry their own overflow:auto. What is left, and
   what actually bites on a 375px screen, is a single unbroken string — an
   email address, a resume filename, a long URL in an applicant note.

   break-word (not anywhere) breaks a word ONLY when it would otherwise
   overflow, so ordinary prose still wraps at spaces. */
@media (max-width:767.98px){
  .ats-panel{overflow-wrap:break-word}
}

/* Stop a panel scroll from chaining to the document when it hits its end.
   On a phone that chaining is what triggers pull-to-refresh and the URL-bar
   show/hide — in an app-shell whose body cannot scroll, both read as the app
   glitching. Applies at every width; harmless with a mouse. */
.ats-panel,
.ats-chrome{overscroll-behavior:contain}

/* ── Bootstrap modals become sheets on a phone ──────────────────────────────
   The tracker leans on modals hard — the applicant panel is .modal-xl, "Add
   applicant" is .modal-lg. Bootstrap centres those in a viewport-width box
   with a margin, which on a 375px screen wastes the edges and leaves a tiny
   scrolling window for a 734-line panel.

   Full-bleed instead, matching .modal-fullscreen. Done in CSS rather than by
   adding .modal-fullscreen-md-down to the markup because there are several
   modals across index.html and the SPA builds some of them dynamically; one
   rule cannot drift out of sync the way six class attributes can. */
@media (max-width:767.98px){
  .modal .modal-dialog{
    max-width:none;
    width:100%;
    margin:0;
  }
  .modal .modal-content{
    height:100%;
    min-height:100dvh;   /* dvh, not vh — see ats_base.html */
    border:0;
    border-radius:0;
  }
  /* The header pins so "close" is always reachable without scrolling back
     up a long panel; the body is the only scrolling region. */
  .modal .modal-header{
    position:sticky;
    top:0;
    z-index:2;
    background:#fff;
    padding-top:calc(.75rem + env(safe-area-inset-top));
  }
  .modal .modal-body{overflow-y:auto}
  .modal .modal-footer{
    position:sticky;
    bottom:0;
    z-index:2;
    background:#fff;
    padding-bottom:calc(.75rem + env(safe-area-inset-bottom));
  }
  /* Footers are usually a right-aligned button pair; at this width they read
     better as full-width stacked actions. */
  .modal .modal-footer > .btn{flex:1 1 auto}

  /* _panel_applicant.html (734 lines, the biggest thing rendered into a
     modal) leans on `d-flex justify-content-between` rows whose trailing
     span is .text-nowrap — a screener question next to required/met
     badges, a job title next to its date range, a note next to its
     timestamp. Bootstrap's .d-flex does not wrap, so on a phone the label
     side is squeezed to a few characters per line while the chip keeps its
     full width. Letting those rows wrap puts the chip on its own line
     instead.

     Scoped to .modal-body rather than applied globally: the same pattern in
     the tab fragments sits in much wider containers where wrapping would be
     a regression, and every modal is a full-screen sheet at this width. */
  .modal-body .d-flex.justify-content-between{flex-wrap:wrap}

  /* Long unbroken strings — applicant emails, resume filenames, URLs in a
     note. Same reasoning as the .ats-panel rule below; modal bodies are a
     separate scroll container and do not inherit it. */
  .modal-body{overflow-wrap:break-word}
}

/* ── Bootstrap density at compact ───────────────────────────────────────────
   Desktop table padding is generous because a mouse needs less precision than
   a thumb but a dense grid reads better. On a phone the tradeoff inverts. */
@media (max-width:767.98px){
  .table > :not(caption) > * > *{padding:.5rem .4rem}

  /* Button groups are laid out assuming they fit on one line. They do not. */
  .btn-group,
  .btn-toolbar{flex-wrap:wrap}

  /* A dropdown anchored to a control near the right edge renders off-screen.
     Constraining the width is enough to keep it inside the viewport without
     needing Popper configuration per call site. */
  .dropdown-menu{max-width:min(92vw,20rem)}

  /* Bootstrap's .btn-sm is a 31px-tall target. */
  .btn-sm{min-height:38px}
}

/* ── Console hub + placeholder ──────────────────────────────────────────────
   admin_home.html's .hub-grid is already intrinsically responsive
   (auto-fill minmax(268px,1fr)) and needs no breakpoint. Only the page
   furniture around it does: 40px of leading whitespace above the fold is a
   desktop luxury. */
@media (max-width:767.98px){
  .hub-head{padding:24px 0 18px}
  .hub-head h1{font-size:1.5rem}
  .hub-note{margin-top:18px}
}

/* ── Flash messages ─────────────────────────────────────────────────────────
   admin_base.html gives these a fixed 18px top padding inside .wrap; at
   compact the container gutter already provides the side inset. */
@media (max-width:767.98px){
  .adm-flash{font-size:.85rem; padding:9px 12px}
}
