/* ══════════════════════════════════════════════════════════════════════════════
   shell — the frame around every screen: breadcrumb, top bar, menus, toasts,
   the command palette and the navigation progress bar. Owned by the shell
   track; app.css is untouched and this layer sits after theme-apple.css.
   ══════════════════════════════════════════════════════════════════════════ */

/* ── breadcrumb ─────────────────────────────────────────────────────────────
   Was a <p> with a bold first word and no links. Now a real <nav><ol>, so the
   parent section is one click (and, on a phone, one tap on .back).            */
.crumb ol{list-style:none; margin:0; padding:0; display:flex; align-items:center; gap:0; min-width:0}
.crumb li{display:inline-flex; align-items:center; min-width:0; white-space:nowrap; overflow:hidden; text-overflow:ellipsis}
.crumb li + li::before{content:"/"; padding:0 6px; color:var(--label-4, var(--ink-3)); flex:none}
.crumb li[aria-current="page"]{color:var(--label, var(--ink)); font-weight:500}
.crumb a{color:var(--label-2, var(--ink-2)); text-decoration:none; border-radius:4px; display:inline-flex; align-items:center; min-height:24px; padding:0 2px}
.crumb a:hover{color:var(--sys-blue-2, var(--navy)); text-decoration:underline}

/* the compact back link: the rail is off screen below 920px */
.back{display:none}

/* ── top bar controls ───────────────────────────────────────────────────────*/
.icon-btn.search-open{display:none}
.top .search-open svg{width:16px; height:16px}

/* the socket, not decoration: grey when live updates are not connected */
:root[data-live="off"] .clock .dot{background:var(--sys-gray3, #c7c7cc)}
:root[data-live="on"] .clock .dot{background:var(--ok)}

/* ── navigation progress ────────────────────────────────────────────────────*/
.nav-progress{
  position:fixed; inset:0 auto auto 0; height:2px; width:100%;
  background:var(--sys-blue, #007aff); transform-origin:0 50%; transform:scaleX(0);
  z-index:120; pointer-events:none;
}
.nav-progress.on{animation:nav-progress 10s cubic-bezier(.1,.7,.2,1) forwards}
@keyframes nav-progress{0%{transform:scaleX(0)} 40%{transform:scaleX(.55)} 100%{transform:scaleX(.94)}}
@media (prefers-reduced-motion:reduce){
  .nav-progress.on{animation:none; transform:scaleX(.5)}
}

/* ── menus (details/summary, no dependency) ─────────────────────────────────*/
details.menu{position:relative; display:inline-flex}
details.menu > summary{list-style:none; cursor:pointer}
details.menu > summary::-webkit-details-marker{display:none}
details.menu > summary::marker{content:""}
/* a closed menu is not on the page at all — not merely invisible */
details.menu:not([open]) .menu-panel{display:none}
.menu-panel{
  position:absolute; right:0; top:calc(100% + 6px); z-index:60;
  width:min(340px, calc(100vw - 24px)); padding:6px;
  background:var(--surface); border:1px solid var(--separator-2, var(--hair));
  border-radius:var(--r, 12px); box-shadow:var(--shadow-3, 0 16px 48px -12px rgba(0,0,0,.28));
}
/* Sentence case, at source. layout.ts links the track sheets AFTER
   theme-apple.css, so the theme's un-uppercasing (theme-apple.css:153) lost
   every time and these labels stayed all-caps and letterspaced — including on
   the printed statement. The source strings are already sentence case. */
.menu-head{margin:2px 8px 6px; font:600 11px/1 var(--ui); letter-spacing:0; color:var(--label-3, var(--ink-3))}
.menu-empty{margin:0; padding:14px 10px 16px; font-size:13px; color:var(--label-2, var(--ink-2))}
.menu-list{list-style:none; margin:0; padding:0; display:flex; flex-direction:column}
.menu-foot{display:flex; align-items:center; gap:6px; justify-content:flex-end; padding:6px 4px 2px; margin-top:4px; border-top:1px solid var(--separator-2, var(--hair))}
.menu-foot form{margin:0}
.menu-panel a[role=menuitem]{text-decoration:none}
.menu-panel [role=menuitem]:focus-visible{outline:2px solid var(--sys-blue, var(--navy)); outline-offset:1px; border-radius:6px}

/* notification rows inside the bell panel */
.nt{display:flex; gap:8px; align-items:flex-start; padding:8px; border-radius:8px}
.nt + .nt{border-top:1px solid var(--separator-2, var(--hair-2))}
.nt:hover{background:var(--sys-gray6, var(--surface-2))}
.nt-dot{width:7px; height:7px; border-radius:50%; margin-top:6px; flex:none; background:transparent}
.nt.unread .nt-dot{background:var(--sys-blue, var(--navy))}
.nt-body{display:flex; flex-direction:column; gap:2px; min-width:0; flex:1}
.nt-t{font-size:13px; font-weight:500; color:var(--label, var(--ink))}
.nt-m{font-size:12px; color:var(--label-2, var(--ink-2)); overflow-wrap:anywhere}
.nt-w{font-size:11px; color:var(--label-3, var(--ink-3))}
.nt-act{margin-left:auto; flex:none}

/* ── toasts ─────────────────────────────────────────────────────────────────
   Two hosts — polite for status, assertive for failures — stacked in one
   corner so they never sit on top of each other.                             */
.toast-stack{position:fixed; right:16px; bottom:16px; z-index:90; display:flex; flex-direction:column; gap:8px; pointer-events:none; align-items:flex-end}
.toast-stack .toasts{position:static; right:auto; bottom:auto; left:auto; z-index:auto; align-items:flex-end}
.toast-t{min-width:0; overflow-wrap:anywhere; display:-webkit-box; -webkit-line-clamp:2; -webkit-box-orient:vertical; overflow:hidden}
.toast{font-size:13px; align-items:center}
.toast .toast-a{margin-left:4px; color:#fff; border-color:rgba(255,255,255,.45); background:rgba(255,255,255,.12); flex:none}
.toast .toast-a:hover{background:rgba(255,255,255,.22); color:#fff}
.toast .x{width:28px; height:28px; padding:0; border-radius:6px; flex:none}

/* ── command palette ────────────────────────────────────────────────────────*/
dialog.palette{width:min(640px, calc(100vw - 32px)); max-width:none; padding:0; border-radius:var(--r-l, 16px)}
.palette-search{display:flex; align-items:center; gap:8px; padding:12px 14px; border-bottom:1px solid var(--separator-2, var(--hair))}
.palette-search svg{width:16px; height:16px; flex:none; color:var(--label-3, var(--ink-3))}
.palette-search input{flex:1; min-width:0; border:0; outline:none; background:transparent; font:400 16px/1.4 var(--ui); color:var(--label, var(--ink))}
.palette-hint{margin:0; padding:18px 16px 20px; font-size:13px; color:var(--label-2, var(--ink-2))}
.palette-list{list-style:none; margin:0; padding:6px; max-height:52vh; overflow:auto}
.palette-group{font:600 11px/1 var(--ui); letter-spacing:0; color:var(--label-3, var(--ink-3)); padding:10px 8px 6px}
.palette-list [role=option]{display:flex; flex-direction:column; gap:1px; padding:8px 10px; border-radius:8px; cursor:pointer; min-height:44px; justify-content:center}
.palette-list [role=option][aria-selected="true"]{background:var(--sys-blue-tint, var(--navy-tint))}
.palette-t{font-size:13px; font-weight:500; color:var(--label, var(--ink))}
.palette-s{font-size:12px; color:var(--label-2, var(--ink-2))}

/* ── shortcuts sheet ────────────────────────────────────────────────────────*/
.sc{margin:0; display:flex; flex-direction:column; gap:2px}
.sc-row{display:flex; align-items:baseline; gap:12px; padding:7px 0}
.sc dt{flex:none; width:104px; display:flex; gap:4px; flex-wrap:wrap}
.sc dd{margin:0; font-size:13px; color:var(--label-2, var(--ink-2))}
.sc kbd{font:500 11px/1 var(--ui); border:1px solid var(--separator, var(--hair)); border-radius:5px; padding:4px 6px; background:var(--surface-2); color:var(--label, var(--ink))}
.sc-h{margin:14px 0 6px; font:600 15px/1.3 var(--ui); color:var(--label, var(--ink))}
.sc-day{margin:0; padding-left:18px; display:flex; flex-direction:column; gap:4px; font-size:13px; color:var(--label-2, var(--ink-2))}

/* ── empty states with a way onward ─────────────────────────────────────────*/
.empty-line b{font-weight:600; color:var(--label, var(--ink))}
.empty-line a{color:var(--sys-blue-2, var(--navy))}

/* ── a focused table row must be visible ────────────────────────────────────
   table.t uses border-collapse, where a box-shadow on the <tr> does not paint. */
table.t tbody tr[data-href]:focus-visible{outline:none}
table.t tbody tr[data-href]:focus-visible > *{background:var(--sys-blue-tint, var(--navy-tint))}
table.t tbody tr[data-href]:focus-visible > *:first-child{box-shadow:inset 3px 0 0 var(--sys-blue, var(--navy))}

/* ── the More sheet ─────────────────────────────────────────────────────────*/
.more-shortcuts{
  display:flex; align-items:center; width:100%; min-height:44px; padding:10px 12px;
  background:transparent; border:0; border-radius:8px; cursor:pointer;
  font:400 14px/1 var(--ui); color:inherit; text-align:left;
}
.more-shortcuts:hover{background:rgba(120,120,128,.12)}

/* ── login ──────────────────────────────────────────────────────────────────*/
.pw{position:relative; display:flex; align-items:center}
.pw input{flex:1; min-width:0; padding-right:64px}
.pw-toggle{
  position:absolute; right:4px; top:50%; transform:translateY(-50%);
  min-height:36px; min-width:52px; padding:0 10px; border:0; border-radius:6px;
  background:transparent; color:var(--sys-blue-2, var(--navy)); cursor:pointer;
  font:500 13px/1 var(--ui);
}
.pw-toggle:hover{background:var(--sys-blue-tint, var(--navy-tint))}

/* ── body scroll lock under a sheet ─────────────────────────────────────────*/
html.sheet-open{overflow:hidden}
@supports selector(html:has(dialog[open])){
  html:has(dialog[open]){overflow:hidden}
}

/* ══ compact widths ═══════════════════════════════════════════════════════ */
@media (max-width:920px){
  /* One 44pt row. app-ext.css puts .search on a full-width second row; the
     search moves behind an icon that opens #search-sheet instead. */
  .top{flex-wrap:nowrap; height:auto; min-height:44px; padding:calc(5px + env(safe-area-inset-top)) 12px 5px; gap:8px}
  .top > .search{display:none}
  .icon-btn.search-open{display:grid}
  .top .icon-btn{width:44px; height:44px}
  .top .icon-btn svg{width:18px; height:18px}
  .crumb{flex:1; min-width:0}
  /* the parent segment is only dropped when the 44pt back link is carrying it */
  .top.has-back .crumb li:not([aria-current="page"]){display:none}
  .top.has-back .crumb li + li::before{display:none}
  .back{
    display:inline-flex; align-items:center; gap:2px; flex:none;
    min-height:44px; min-width:44px; padding:0 6px 0 2px; margin-left:-4px;
    color:var(--sys-blue-2, var(--navy)); text-decoration:none; font-size:14px;
    max-width:40vw; overflow:hidden;
  }
  .back svg{width:20px; height:20px; flex:none}
  .back span{overflow:hidden; text-overflow:ellipsis; white-space:nowrap}
  .search .kbd{display:none}
  .search.in-sheet{width:100%; margin-left:0; order:0}
  /* the More sheet must say who is signed in; app-ext.css:217 hides it for the
     horizontal rail, which is display:none at this width anyway */
  dialog.more .rail-user b{display:block}
  dialog.more .rail-user > span:last-child > span{display:block}
  .menu-panel{width:min(340px, calc(100vw - 24px))}
  /* The bell panel is bounded by the space between the two fixed bars.
     With eight notifications it measures 562px, and at 360x640 (an
     ordinary Android) the tab bar starts at 582 — measured with
     elementFromPoint: "Mark all read" and "See all" both belonged to the tab
     bar, not to the panel. At 320x640 the panel's bottom is 51px below the
     fold and it does not scroll (scrollHeight === clientHeight), and because
     it is absolutely positioned inside the sticky top bar, scrolling the page
     does not bring it back either. The LIST scrolls; the head and the foot
     stay put, so the two actions are reachable whatever the list length. */
  .menu-panel{
    display:flex; flex-direction:column;
    max-height:calc(100dvh - 56px - 70px - env(safe-area-inset-top) - env(safe-area-inset-bottom));
  }
  .menu-panel .menu-list{overflow-y:auto; overscroll-behavior:contain; min-height:0}
  .menu-panel .menu-head,.menu-panel .menu-foot{flex:none}
  .toast .x{width:44px; height:44px}
  /* The toast host is `.toast-stack` — `.toasts` inside it is position:static
     (see above), so theme-apple.css's `.toasts{bottom:…}` rule was inert and a
     toast sat exactly on top of the tab bar: measured at 390x844, the toast
     spans 756-820 and the bar 786-844, and elementFromPoint on all five tabs
     returned `div.toast`. `.toast{pointer-events:auto}` means the tap is eaten,
     not passed through, so every destination was dead for the toast's life —
     nine seconds after a failed action. One owner, on the element that is
     actually positioned. */
  .toast-stack{bottom:calc(70px + env(safe-area-inset-bottom))}
  .pw-toggle{min-height:44px; min-width:60px}
  .pw input{padding-right:74px}
  .nt{padding:10px 8px}
  .nt-act .btn{min-height:44px}
}
@media (hover:none){
  .search .kbd{display:none}
}
@media (max-width:600px){
  .toast-stack{left:12px; right:12px; align-items:stretch}
  .toast-stack .toasts{left:auto; right:auto; align-items:stretch}
  .toast{max-width:none}
  dialog.palette{width:100vw; max-width:100vw; margin:auto 0 0; border-radius:var(--r-l) var(--r-l) 0 0}
}

/* ── phone: menu rows are targets, not text ────────────────────────────────
   A notification title and an alert title inside the bell panel were 15-16px
   tall. The panel is reached by thumb on a phone, so every row that navigates
   gets the full 44pt. */
@media (max-width:600px){
  .menu-list a[role="menuitem"],
  .menu-list .nt-t a{ display:flex; align-items:center; min-height:44px; }
  .menu-list .nt{ padding:6px 8px; }
}
