/*
 * app-rail.css — unified left navigation rail, multi-tenant AI platform.
 *
 * Colors are pulled exclusively from the tokens defined in profile-shell.css
 * (--bg --bg-2 --panel --panel-2 --line --line-soft --text --text-dim
 * --text-muted --text-faint --accent --accent-soft --radius). No hardcoded
 * hex/rgb values for text, background, or border anywhere in this file.
 * This file assumes profile-shell.css (or an equivalent host stylesheet
 * defining those same custom properties) is already loaded on the page.
 */

.app-rail {
  position: fixed;
  top: 0;
  left: 0;
  /* 100dvh, NOT 100vh (2026-09-01, Jason on a phone: "the bottom drawer we
     have now is hiding the icon that allows me to click on my name and then
     go to settings and connectors. I can't scroll down any further").
     100vh on mobile Safari/Chrome is the LARGE viewport - it includes the
     browser's own bottom toolbar. The rail was therefore taller than the
     screen, and the user card, which sits at the rail's bottom edge, was
     rendered underneath the toolbar with nothing left to scroll. The bottom
     action bar (.app-rail-bbar, position:fixed) sticks to the VISUAL
     viewport, so it looked like the bar was covering the card; the bar was
     just the last thing you could still see. 100vh stays as the fallback
     for anything that does not know dvh. */
  height: 100vh;
  height: 100dvh;
  box-sizing: border-box;
  width: 62px;
  z-index: 40;
  display: flex;
  flex-direction: column;
  background: var(--panel);
  border-right: 1px solid var(--line);
  overflow: visible;
  transition: width 0.18s ease;
  font-family: inherit;
}

@media (prefers-reduced-motion: reduce) {
  .app-rail,
  .app-rail * {
    transition: none !important;
  }
}

.app-rail.is-expanded {
  width: 250px;
}

.app-rail.is-signed-out {
  opacity: 0.45;
}

/* body offset classes — added/removed by app-rail.js
   THE RAIL OVERLAYS, IT DOES NOT PUSH (2026-08-28, Jason: "when I open it, it
   should overlay across the back page rather than squishing the page
   together"). Expanding used to widen the body's padding from 62px to 250px,
   so opening the menu reflowed the whole page under it - text re-wrapped,
   cards re-stacked, and whatever you were reading moved. The page now
   reserves the COLLAPSED width only, permanently, and the expanded rail
   slides over the content instead of displacing it. */
body.app-rail-offset-collapsed,
body.app-rail-offset-expanded {
  padding-left: 62px;
  /* NO transition (2026-09-03). Both states above are 62px, so this could only
     ever animate the one jump it should not: the initial 0 -> 62 when the class
     first landed after /api/me resolved. The class is now added synchronously
     at script eval (see app-rail.js), so there is no jump left to animate and
     an easing here would only make a future one prettier instead of visible. */
}
/* The expanded rail floats above the page it covers. */
.app-rail.is-expanded {
  box-shadow: 0 0 32px rgba(0, 0, 0, 0.45);
}

/* THE RAIL STARTS BELOW THE SHARED TOP BAR (2026-08-28, Jason: "the drawer
   menu is not working on mobile"). The rail is fixed at top:0 and so is the
   top bar, so the bar sat on top of the rail's first 56px - which is exactly
   where the brand square that OPENS the rail lives. Measured on Jason's page
   at 375px: the toggle's centre was at y=28, underneath a 52px bar. The
   control was not broken, it was covered, and there was no second way in.
   Only applies where the shared bar is actually mounted, so a page without
   it still gets a full-height rail. */
body.stb-mounted .app-rail {
  top: var(--hdr-h, 56px);
  height: calc(100vh - var(--hdr-h, 56px));
  height: calc(100dvh - var(--hdr-h, 56px));
}

.app-rail-scroll {
  flex: 1 1 auto;
  overflow-y: auto;
  overflow-x: hidden;
  min-height: 0;
  scrollbar-width: thin;
}
.app-rail-scroll::-webkit-scrollbar {
  width: 6px;
}
.app-rail-scroll::-webkit-scrollbar-thumb {
  background: var(--line);
  border-radius: var(--radius);
}

/* ---- Brand mark (hamburger substitute) ---- */
.app-rail-brand-row {
  display: flex;
  align-items: center;
  height: 56px;
  flex: 0 0 auto;
  padding: 0 16px;
}
.app-rail-brand {
  width: 30px;
  height: 30px;
  min-width: 30px;
  border-radius: var(--radius-sm, 10px);
  background: var(--accent);
  color: var(--bg);
  display: flex;
  align-items: center;
  justify-content: center;
  font-weight: 700;
  font-size: 13px;
  letter-spacing: 0.02em;
  cursor: pointer;
  border: none;
  padding: 0;
}
.app-rail-brand:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}
/* 2026-09-02: the owner's own photo, when signed in and one is on file -
   round rather than the square/rounded-square the "AI" glyph sits in, so it
   reads unambiguously as a person, not a second app icon. */
.app-rail-brand-photo {
  width: 100%;
  height: 100%;
  border-radius: 50%;
  object-fit: cover;
  display: block;
}

/* ---- Search ---- */
.app-rail-search-row {
  flex: 0 0 auto;
  height: 40px;
  display: flex;
  align-items: center;
  padding: 0 16px;
  margin-bottom: 8px;
  position: relative;
}
.app-rail-search-icon {
  width: 30px;
  height: 30px;
  min-width: 30px;
  display: flex;
  align-items: center;
  justify-content: center;
  color: var(--text-muted);
  cursor: pointer;
  border-radius: var(--radius-sm, 10px);
  border: none;
  background: transparent;
  flex: 0 0 auto;
}
.app-rail-search-icon:hover {
  background: var(--panel-2);
  color: var(--text);
}
.app-rail-search-input {
  width: 100%;
  height: 32px;
  border-radius: var(--radius-sm, 10px);
  border: 1px solid var(--line);
  background: var(--bg-2);
  color: var(--text);
  font-size: 13px;
  padding: 0 10px;
  outline: none;
  font-family: inherit;
}
.app-rail-search-input::placeholder {
  color: var(--text-faint);
}
.app-rail-search-input:focus {
  border-color: var(--accent);
}
.app-rail.is-collapsed .app-rail-search-input {
  display: none;
}
.app-rail.is-expanded .app-rail-search-icon {
  display: none;
}

/* ---- Generic row ---- */
.app-rail-row {
  display: flex;
  align-items: center;
  height: 40px;
  padding: 0 16px;
  gap: 12px;
  color: var(--text-dim);
  cursor: pointer;
  text-decoration: none;
  border: none;
  background: transparent;
  width: 100%;
  font-family: inherit;
  font-size: 13.5px;
  border-radius: 0;
}
.app-rail-row:hover {
  background: var(--panel-2);
  color: var(--text);
}
.app-rail-row[aria-disabled="true"] {
  cursor: default;
  pointer-events: none;
  opacity: 0.6;
}
.app-rail-row-icon {
  width: 30px;
  height: 30px;
  min-width: 30px;
  display: flex;
  align-items: center;
  justify-content: center;
  flex: 0 0 auto;
  border-radius: var(--radius-sm, 10px);
  overflow: hidden;
  color: var(--text-muted);
}
.app-rail-row-icon img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
  border-radius: var(--radius-sm, 10px);
}
.app-rail-row-icon.is-initials {
  background: var(--accent-soft);
  color: var(--accent);
  font-size: 11px;
  font-weight: 700;
  text-transform: uppercase;
}
.app-rail-row-label {
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  flex: 1 1 auto;
  min-width: 0;
  display: flex;
  flex-direction: column;
  justify-content: center;
}
.app-rail-row-sub {
  font-size: 11px;
  color: var(--text-faint);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.app-rail.is-collapsed .app-rail-row-label {
  display: none;
}
/* 2026-09-01, Jason live, with a screenshot: icons in a collapsed row sat
   left-of-center, not centered, across every AI's subnav. Root cause: with
   the label hidden above, the icon is the only visible flex child left in
   .app-rail-row, and flexbox's default justify-content (flex-start) leaves
   it sitting right after the row's own left padding instead of centering it
   in the collapsed width - the row never had a collapsed-specific layout
   rule of its own. .app-rail-oparea already got this exact treatment
   (search this file for "justify-content:center" further down) when it hit
   the identical problem; this is that same fix applied to the general row
   class every icon in the screenshot actually uses. Padding drops to 0 too:
   with content centered, asymmetric left/right padding would just push it
   off-center again the other direction. */
.app-rail.is-collapsed .app-rail-row {
  justify-content: center;
  padding: 0;
}

/* ---- Group labels ---- */
.app-rail-group-label {
  height: 28px;
  display: flex;
  align-items: center;
  padding: 0 16px;
  font-size: 11px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--text-faint);
  margin-top: 8px;
}
.app-rail.is-collapsed .app-rail-group-label {
  display: none;
}

.app-rail-group {
  padding-bottom: 4px;
}

/* Page-specific nav (2026-09-02) - the folded-in .cc-nav Focus/People/Tools
   count badges, same look profile-shell.css's own .cc-nav .count used. */
.app-rail-row-count {
  font-size: 11px;
  padding: 2px 8px;
  border-radius: 999px;
  background: var(--accent-soft, rgba(59,130,246,0.14));
  border: 1px solid var(--line, rgba(148,163,184,0.2));
  color: var(--accent, #4f7cff);
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  flex: 0 0 auto;
}
.app-rail.is-collapsed .app-rail-row-count {
  display: none;
}
/* Page-nav rows carry no icon (cc-nav's own items never did either), so
   collapsing just their label like every other row would leave a blank,
   broken-looking row instead of an icon stub. Hide the whole section in
   collapsed mode instead - !important because JS also toggles this same
   element's inline display (empty-content vs has-content, a different
   concern - see renderPageNav) and inline style would otherwise always win. */
.app-rail.is-collapsed .app-rail-pagenav {
  display: none !important;
}

/* ---- Spacer ---- */
.app-rail-spacer {
  flex: 1 1 auto;
  min-height: 8px;
}

/* ---- User card ---- */
.app-rail-usercard-wrap {
  position: relative;
  flex: 0 0 auto;
  border-top: 1px solid var(--line-soft);
}
.app-rail-usercard {
  display: flex;
  align-items: center;
  gap: 12px;
  height: 56px;
  padding: 0 16px;
  cursor: pointer;
  border: none;
  background: transparent;
  width: 100%;
  font-family: inherit;
  color: var(--text);
}
.app-rail-usercard:hover {
  background: var(--panel-2);
}
.app-rail-usercard-name {
  font-size: 13px;
  font-weight: 600;
  color: var(--text);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.app-rail-usercard-sub {
  /* BLOCK, not the inline default. As inline inside a block parent the name
     and this line rendered on ONE line - "Jason Haygood" immediately followed
     by its own subtitle with no break. Both halves of this card stack. */
  display: block;
  font-size: 11px;
  color: var(--text-muted);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.app-rail.is-collapsed .app-rail-usercard-text {
  display: none;
}

.app-rail-signin-btn {
  display: flex;
  align-items: center;
  justify-content: center;
  height: 34px;
  margin: 11px 16px;
  border-radius: var(--radius-sm, 10px);
  background: var(--accent);
  color: var(--bg);
  font-size: 13px;
  font-weight: 700;
  text-decoration: none;
  white-space: nowrap;
  overflow: hidden;
}
.app-rail.is-collapsed .app-rail-signin-btn {
  width: 30px;
  height: 30px;
  margin: 13px 16px;
  padding: 0;
  font-size: 11px;
}

/* ---- User menu (opens above card) ---- */
.app-rail-usermenu {
  position: absolute;
  left: 8px;
  bottom: 100%;
  margin-bottom: 6px;
  width: 210px;
  background: var(--panel-2);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  box-shadow: 0 8px 24px rgba(0, 0, 0, 0.3);
  overflow: hidden;
  display: none;
  z-index: 41;
}
.app-rail-usermenu.is-open {
  display: block;
}
.app-rail-usermenu-item {
  display: flex;
  align-items: center;
  justify-content: space-between;
  height: 38px;
  padding: 0 14px;
  font-size: 13px;
  color: var(--text-dim);
  cursor: pointer;
  border: none;
  background: transparent;
  width: 100%;
  text-align: left;
  font-family: inherit;
}
.app-rail-usermenu-item:hover {
  background: var(--panel);
  color: var(--text);
}
.app-rail-usermenu-toggle {
  font-size: 11px;
  color: var(--text-faint);
}

/* ---- Show all row ---- */
.app-rail-showall {
  font-size: 12px;
  color: var(--accent);
}

/* When collapsed, keep collapsed-only elements aligned to the same
   vertical rhythm as the expanded rail by reusing the same row heights
   defined above — no separate collapsed geometry needed. */

/* ---- Mobile drawer (2026-08-27, Jason) ----
   Below 768px the rail stops being a permanent column that reserves body
   width (that's what was "squishing" every page's content on a phone) and
   becomes a true drawer: off-canvas by default, sliding OVER the content as
   an overlay with a backdrop when opened, closed again on backdrop tap or
   Escape. Desktop's collapsed/expanded (icon-only vs labeled) distinction is
   irrelevant here - on mobile the drawer is always full width when open,
   controlled by the separate .is-mobile-open class so it never fights the
   desktop is-collapsed/is-expanded state that localStorage remembers. */
@media (max-width: 768px) {
  /* CLOSED BUT VISIBLE (2026-08-28, Jason: "it should have the app drawer
     closed but visible along the left-hand vertical menu"). The 2026-08-27
     pass fixed the squishing by pushing the rail fully off-canvas
     (translateX(-100%)), which solved the reflow and cost the affordance:
     on a phone there was no menu on screen at all, and nothing to tell you
     one existed. It behaves like the desktop rail now - a permanent icon
     strip you can always see and tap - and opening it slides OVER the page
     rather than moving it, which is what off-canvas was bought for. */
  .app-rail {
    width: 56px;
    transform: none;
    transition: width 0.22s ease;
  }
  .app-rail.is-collapsed,
  .app-rail.is-expanded {
    width: 56px;
  }
  .app-rail.is-mobile-open,
  .app-rail.is-mobile-open.is-collapsed,
  .app-rail.is-mobile-open.is-expanded {
    width: 250px;
    box-shadow: 0 0 32px rgba(0, 0, 0, 0.45);
  }
  /* Labels belong to the OPEN drawer, never to the icon strip. Keyed off
     is-mobile-open rather than the desktop is-collapsed/is-expanded state,
     which localStorage remembers independently and must not leak in here. */
  .app-rail:not(.is-mobile-open) .app-rail-row-label,
  .app-rail:not(.is-mobile-open) .app-rail-group-label,
  .app-rail:not(.is-mobile-open) .app-rail-usercard-text,
  .app-rail:not(.is-mobile-open) .app-rail-search-input,
  .app-rail:not(.is-mobile-open) .app-rail-retract,
  .app-rail-pin {
    display: none;
  }
  .app-rail.is-mobile-open .app-rail-row-label,
  .app-rail.is-mobile-open .app-rail-group-label,
  .app-rail.is-mobile-open .app-rail-usercard-text,
  .app-rail.is-mobile-open .app-rail-search-input {
    display: initial;
  }
  .app-rail.is-mobile-open .app-rail-search-icon {
    display: none;
  }
  /* Reserve the strip's width only. The open drawer overlays the page, so
     this never changes when it opens - that is the whole point. */
  body.app-rail-offset-collapsed,
  body.app-rail-offset-expanded {
    padding-left: 56px !important;
  }
  .app-rail-backdrop {
    position: fixed;
    inset: 0;
    background: rgba(0, 0, 0, 0.5);
    z-index: 39;
    opacity: 0;
    pointer-events: none;
    transition: opacity 0.22s ease;
  }
  .app-rail-backdrop.is-visible {
    opacity: 1;
    pointer-events: auto;
  }
  body.app-rail-mobile-locked {
    overflow: hidden;
  }
}

/* RETRACT ARROW (2026-08-27, Jason: "a little arrow on the top right corner of
   it to show people they can click on the arrow to make it retract"). Sits at
   the far right of the brand row; the brand square stays a toggle too, this
   just makes the affordance visible. Hidden when the rail is collapsed to
   icons on desktop - there is no room, and the brand square is still there. */
.app-rail-brand-row { justify-content: space-between; }
.app-rail-retract {
  width: 26px;
  height: 26px;
  min-width: 26px;
  border: none;
  background: transparent;
  color: var(--muted, #8b93a7);
  font-size: 20px;
  line-height: 1;
  cursor: pointer;
  border-radius: var(--radius-sm, 8px);
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 0;
}
.app-rail-retract:hover { background: var(--hover, rgba(127,127,127,.12)); color: var(--text, inherit); }
.app-rail-retract:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.app-rail.is-collapsed .app-rail-retract { display: none; }

/* PIN BUTTON (2026-09-02, Jason: "a pin button next to that arrow to close
   the drawer so people can keep it open"). Same shape and slot as the
   retract arrow next to it - collapsed when the rail itself is collapsed,
   for the same no-room reason. Unpinned it reads as a plain icon action
   like retract; pinned it stays visibly "on" (filled background, full
   opacity) so the state is legible without hovering, the same distinction
   .app-rail-acct.is-active already uses for "this is the open one". */
.app-rail-pin {
  width: 26px;
  height: 26px;
  min-width: 26px;
  border: none;
  background: transparent;
  color: var(--muted, #8b93a7);
  font-size: 14px;
  line-height: 1;
  cursor: pointer;
  border-radius: var(--radius-sm, 8px);
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 0;
  opacity: .55;
}
.app-rail-pin:hover { background: var(--hover, rgba(127,127,127,.12)); opacity: .85; }
.app-rail-pin:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.app-rail-pin.is-pinned { background: var(--accent-soft, rgba(139,147,255,.16)); opacity: 1; }
.app-rail.is-collapsed .app-rail-pin { display: none; }

/* MOBILE-OPEN BEATS DESKTOP-COLLAPSED (2026-08-28). Two rules further up hide
   chrome whenever .is-collapsed is present, and on mobile that class is
   whatever localStorage remembered for the DESKTOP rail - it is not the
   drawer's own state. So an open mobile drawer inherited the icon-only
   rail's "no close arrow", leaving no visible way to shut it again except
   the backdrop. These sit at the end of the file deliberately: the rules
   they correct are declared after the mobile block, so source order, not
   just specificity, has to be on this side. */
@media (max-width: 768px) {
  .app-rail.is-mobile-open.is-collapsed .app-rail-retract,
  .app-rail.is-mobile-open.is-expanded .app-rail-retract {
    display: inline-flex;
  }
}

/* Operator context marker - only ever rendered for an admin session standing
   on another owner's host (see app-rail.js). Amber rather than the brand blue
   because it is a state warning, not a destination. 2026-08-29. */
.app-rail-oparea{
  display:flex; align-items:center; gap:10px;
  margin:6px 8px 2px; padding:7px 9px;
  border:1px dashed rgba(251,191,36,.55);
  border-radius:9px;
  background:rgba(251,191,36,.10);
  color:#d99b0b;
  font-size:12px; font-weight:700; letter-spacing:.01em;
}
.app-rail-oparea svg{width:15px;height:15px;flex:0 0 auto}
.app-rail.is-collapsed .app-rail-oparea .app-rail-row-label{display:none}
.app-rail.is-collapsed .app-rail-oparea{justify-content:center;padding:7px 0}

/* Operator account groups (2026-08-29). One row per person, collapsed, with
   only the account you are standing in expanded. Replaces a flat list of every
   AI in the estate, which on a phone was eighteen rows with no owner context. */
.app-rail-acct{cursor:pointer;text-align:left}
/* Split AI row (2026-08-31, Jason): left zone = link that switches to the AI
   (avatar with a tiny caret under it + name), right zone = chevron button
   that expands that AI's Desk/Calendar/Tasks subnav. text-align:left above
   also fixes the name misalignment - desk-AI rows were <button>s, whose
   default centered text made their names sit differently from plain rows. */
.app-rail-ai-split{padding-right:8px}
.app-rail-ai-go{display:flex;align-items:center;gap:12px;flex:1 1 auto;min-width:0;color:inherit;text-decoration:none}
/* 2026-09-01, Jason live, after the plain-icon-row centering fix: "can you
   get the AI pictures aligned so they're in the center... as well?" The row
   (.app-rail-row.app-rail-acct) already centers its content, but
   .app-rail-ai-go's own flex:1 1 auto GROWS it to fill the entire row width
   regardless - so there was nothing left to center INTO, and the avatar,
   flush at go's own left edge, ended up at the row's left edge too. Once
   collapsed, go's only other sibling (the chevron button) is already
   display:none elsewhere in this file, so go has no reason left to grow -
   shrinking it to its own content (just the avatar, since the name label is
   hidden the same way) is what lets the row's existing centering actually
   center something. */
.app-rail.is-collapsed .app-rail-ai-go{flex:0 0 auto}
.app-rail-ai-avwrap{display:flex;flex-direction:column;align-items:center;flex:0 0 auto}
.app-rail-ai-switch-caret{font-size:9px;line-height:1;opacity:.85;margin-top:2px;color:#8ab4f8}
.app-rail-ai-chevbtn{flex:0 0 auto;display:flex;align-items:center;justify-content:center;width:26px;height:26px;border:1px solid rgba(148,163,184,.35);background:rgba(148,163,184,.08);color:inherit;cursor:pointer;border-radius:8px}
.app-rail-ai-chevbtn .app-rail-acct-chev{margin-left:0;font-size:11px;opacity:.9}
.app-rail-ai-chevbtn:hover{background:rgba(96,165,250,.22);border-color:rgba(96,165,250,.5)}
.app-rail.is-collapsed .app-rail-ai-chevbtn,
.app-rail.is-collapsed .app-rail-ai-switch-caret{display:none}
.app-rail-acct.is-open{background:rgba(96,165,250,.10)}
.app-rail-acct.is-active{background:rgba(96,165,250,.14);box-shadow:inset 2px 0 0 #60a5fa}
/* CURRENT-TAB HIGHLIGHT (2026-09-02) - see the matching JS comment in
   app-rail.js (markCurrentRailRow). Same visual language as
   .app-rail-acct.is-active just above (soft accent fill + inset accent
   bar) so "you are here" reads consistently whether it's the AI switcher
   or an ordinary Desk/Calendar/Tasks row, but built from this file's own
   tokens rather than the hardcoded #60a5fa - this rule applies to every
   tenant's rail, not just the one that hex happened to look right on. */
.app-rail-row.is-current{background:var(--accent-soft);box-shadow:inset 2px 0 0 var(--accent);color:var(--text)}
.app-rail-row.is-current .app-rail-row-icon{color:var(--accent)}
.app-rail-row.is-current .app-rail-row-label{font-weight:600}
.app-rail-acct-chev{margin-left:auto;font-size:10px;opacity:.65;flex:0 0 auto}
.app-rail-acct-kids{display:block}
.app-rail-row-sub-item{padding-left:26px}
.app-rail-row-sub-item .app-rail-row-label{font-size:13px}
.app-rail.is-collapsed .app-rail-acct-chev{display:none}
.app-rail.is-collapsed .app-rail-row-sub-item{padding-left:0}

/* Per-AI desk subnav (2026-08-31, Jason: clicking an AI with a real desk
   opens its own Desk/Calendar/Tasks/People/Communications/History/Recents,
   with an explicit Back row rather than only re-clicking the header). */
.app-rail-ai-block{display:flex;flex-direction:column}
.app-rail-ai-back{color:var(--text-dim);font-size:13px}
.app-rail-ai-back:hover{background:var(--panel-2);color:var(--text)}
.app-rail-back-chev{font-size:15px;line-height:1;flex:0 0 auto;opacity:.8}
.app-rail.is-collapsed .app-rail-ai-back .app-rail-row-label,
.app-rail.is-collapsed .app-rail-back-chev{display:none}

/* ── MOBILE BOTTOM BAR (2026-08-29) ──────────────────────────────────────
   Phone only. On desktop a mouse has no thumb arc, so the call control stays
   on the AI card where it reads naturally and this bar is not rendered. */
.app-rail-bbar{display:none}
@media (max-width: 768px){
  .app-rail-bbar{
    display:flex; align-items:center; gap:9px;
    position:fixed; left:0; right:0; bottom:0; z-index:70;
    padding:8px 12px calc(8px + env(safe-area-inset-bottom,0px));
    background:var(--rail-bg,#0b1220);
    border-top:1px solid var(--rail-line,rgba(255,255,255,.10));
    box-shadow:0 -8px 24px rgba(0,0,0,.34);
  }
  .app-rail-bb-nav{
    width:40px; height:40px; flex:0 0 auto; border-radius:12px;
    border:0; background:#2563eb; color:#fff;
    font-family:inherit; font-size:12px; font-weight:800; cursor:pointer;
  }
  .app-rail-bb-nav.is-open{background:#7c3aed; font-size:18px; font-weight:600}
  .app-rail-bb-ask{
    flex:1 1 auto; min-width:0; height:40px; text-align:left;
    border-radius:99px; border:1px solid var(--rail-line,rgba(255,255,255,.14));
    background:transparent; color:var(--rail-dim,#93a3be);
    font-family:inherit; font-size:13px; padding:0 14px; cursor:pointer;
    white-space:nowrap; overflow:hidden; text-overflow:ellipsis;
  }
  .app-rail-bb-callwrap{display:flex; flex-direction:column; align-items:center; gap:1px; flex:0 0 auto}
  .app-rail-bb-call{
    width:40px; height:40px; border-radius:12px; border:0;
    background:#15803d; color:#fff; font-size:17px; cursor:pointer; line-height:1;
  }
  .app-rail-bb-call:disabled{opacity:.7}
  .app-rail-bb-cap{
    font-size:7.5px; font-weight:700; letter-spacing:.06em; text-transform:uppercase;
    color:var(--rail-dim,#93a3be); max-width:52px; overflow:hidden;
    text-overflow:ellipsis; white-space:nowrap;
  }
  /* The bar owns the bottom of the screen; nothing else may sit there. */
  .app-rail-bbar ~ * .dock-card,
  body .dock-card{display:none !important}
  body{padding-bottom:64px}
  /* The drawer must clear the bar rather than hide behind it. The bar is
     40px of content + 8px top padding + 8px bottom padding + the home
     indicator, so a flat 66px was already short by the safe-area inset on
     every notched phone - and with the rail measured in 100vh (fixed above)
     the user card sat below the fold regardless. Derive it from the same
     numbers the bar itself uses instead of guessing. 2026-09-01. */
  .app-rail.is-mobile-open{padding-bottom:calc(var(--rail-bbar-h, 70px) + 8px)}
  /* The chat launcher must clear it too. Declared HERE rather than in
     agent-dock.js because the bar owns the bottom of the screen, and because
     ai-desk.html loads agent-dock.js unversioned - an edit there would sit in
     browser cache indefinitely, while this file carries a ?v= that is bumped
     on every change. 2026-08-29. */
  body .ad-bubble{bottom:calc(84px + env(safe-area-inset-bottom,0px)) !important}
}

/* THIRD ROUND, SAME ROOT CAUSE, SAME PLACEMENT RULE (2026-09-01). These
   corrections MUST be the last thing in the file. The 2026-08-28 block above
   says so in its own comment - "the rules they correct are declared after the
   mobile block, so source order, not just specificity, has to be on this
   side" - and then five more collapsed-rail rules were appended below it over
   the following days, which silently put those rules back on the winning side
   again. Verified live in a 375px browser: with this block mid-file,
   .app-rail.is-collapsed .app-rail-row-sub-item (declared later, identical
   specificity) still forced padding-left:0 on an open drawer. */
@media (max-width: 768px) {
  /* SECOND ROUND OF THE SAME BUG (2026-09-01, Jason with a screenshot of his
     own drawer: "there's also misalignment between operator and Maya's
     picture"). Five collapsed-rail rules were added on 2026-08-29/09-01 -
     row centering, the AI go-link shrink, the two AI chevrons, the sub-item
     indent - and none of them were given the mobile-open exemption this
     block exists to provide. On a phone .is-collapsed is whatever
     localStorage remembered for the DESKTOP rail, so an OPEN mobile drawer
     was centering every row's content while its labels were visible: each
     row landed at a different left edge depending on how long its name was
     (Maya indented further than "Rosie Marla Ellerman"), which is exactly
     the staircase Jason saw. It also hid both chevrons, so the two-arrow
     model - picture selects, chevron expands - had no chevron on a phone at
     all. An open drawer is an EXPANDED rail, whatever the desktop
     remembers. */
  .app-rail.is-mobile-open .app-rail-row {
    justify-content: flex-start;
    padding: 0 16px;
  }
  .app-rail.is-mobile-open .app-rail-ai-go { flex: 1 1 auto; }
  .app-rail.is-mobile-open .app-rail-ai-chevbtn { display: flex; }
  .app-rail.is-mobile-open .app-rail-ai-switch-caret,
  .app-rail.is-mobile-open .app-rail-acct-chev,
  .app-rail.is-mobile-open .app-rail-back-chev { display: inline; }
  .app-rail.is-mobile-open .app-rail-row-sub-item { padding-left: 26px; }
  .app-rail.is-mobile-open .app-rail-oparea {
    justify-content: flex-start;
    padding: 7px 9px;
  }
  .app-rail.is-mobile-open .app-rail-oparea .app-rail-row-label { display: initial; }
  /* Verified live in a 375px browser: the Back row rendered as a bare "‹"
     with no word next to it, because its own label rule is three classes
     deep and outranked the general mobile-open label rule further up. */
  .app-rail.is-mobile-open .app-rail-ai-back .app-rail-row-label { display: initial; }
}
