/* THE REDESIGN'S LAYER (29 September 2026).
   ---------------------------------------------------------------------------
   Loaded after app.css, and every rule here is scoped to body.ui-new — the
   sidebar layout. Classic (body.ui-classic) never matches a rule in this file,
   which is what keeps Classic the old look exactly rather than an imitation
   of it. Take this file away and the whole app is the 29 September build.

   Four decisions, from the review:
   1. Sentence case. The small capitals everywhere (70 rules) read as a form
      to fill in. app.css now spells them var(--caps, uppercase); here they
      become none, and the tracking that only made sense for capitals goes too.
   2. One type scale: 12 / 13 / 15 / 17 / 22 / 28.
   3. A sidebar on a laptop, a tab bar on a phone.
   4. One primary action per screen; everything else quiet. */

body.ui-new {
  --caps: none;
  --caps-track: 0;
  --fs-1: 12px;
  --fs-6: 22px;
  --fs-7: 22px;
  --fs-8: 28px;
  --fs-9: 34px;
  --side-w: 252px;
  --side-bg: var(--surface-2);
  --hover: color-mix(in srgb, var(--ink) 6%, transparent);
}

/* ---- the frame ----------------------------------------------------------- */
body.has-side .app { display: grid; grid-template-columns: var(--side-w) minmax(0, 1fr); min-height: 100vh; }
body.has-side .appmain { min-width: 0; }
body.has-side .appmain > .wrap { padding-top: 28px; }
.sidecheck { position: absolute; opacity: 0; pointer-events: none; width: 1px; height: 1px; }
.sidescrim { display: none; }
.tabbar { display: none; }

/* ---- the sidebar --------------------------------------------------------- */
body.ui-new .side {
  position: sticky; top: 0; height: 100vh; overflow-y: auto; overscroll-behavior: contain;
  padding: 14px 12px 12px; background: var(--side-bg); border-right: 1px solid var(--line);
  display: flex; flex-direction: column; gap: 2px; scrollbar-width: thin;
}
.sidehead { display: flex; align-items: center; gap: 8px; padding: 4px 8px 12px; }
/* The church's logo, centred over the column and a little larger than the
   first cut: the lockup's artwork sits inside a wide margin of its own. */
.sidebrand { display: flex; flex-direction: column; align-items: center; justify-content: center; flex: 1 1 auto; min-width: 0; text-decoration: none; color: inherit; }
.sidebrand img { max-width: 200px; height: auto; max-height: 48px; display: block; }
.sidebrand svg { max-width: 100%; width: auto; height: 60px; display: block; }
.sidebrand .brandtext { font-size: 17px !important; font-weight: 600; color: var(--navy); }
.sideclose { display: none; cursor: pointer; color: var(--ink-2); padding: 8px; border-radius: 8px; }
.sidesearch {
  display: flex; align-items: center; gap: 8px; min-height: 34px; padding: 0 8px 0 10px; margin: 0 0 10px;
  border: 1px solid var(--line); border-radius: 10px; background: var(--surface);
  color: var(--muted); font-size: 13px; text-decoration: none;
}
.sidesearch span { flex: 1 1 auto; }
.sidesearch kbd { font: inherit; font-size: 12px; color: var(--ink-2); background: var(--surface-2); border-radius: 6px; padding: 1px 6px; }
.sidesearch:hover { border-color: var(--navy-line); color: var(--ink-2); text-decoration: none; }
.sidenav { display: flex; flex-direction: column; gap: 1px; }
.sl {
  display: flex; align-items: center; gap: 10px; min-height: 32px; padding: 0 10px; border-radius: 8px;
  color: var(--ink); font-size: 13px; font-weight: 500; text-decoration: none; line-height: 1.2;
}
.sl:hover { background: var(--hover); color: var(--ink); text-decoration: none; }
.sl .sli { color: var(--ink-2); flex: none; }
.sl.on { background: var(--navy-soft); color: var(--navy); font-weight: 600; }
.sl.on .sli { color: var(--navy); }
.slt { flex: 1 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.sl .badge { margin-left: 0; flex: none; }
.sldot { width: 8px; height: 8px; border-radius: 4px; background: var(--crit); flex: none; }
.sidegroup { margin-top: 10px; }
.sidegroup > summary {
  list-style: none; cursor: pointer; font-size: 12px; font-weight: 600; color: var(--muted);
  padding: 4px 10px 4px; display: flex; align-items: center; gap: 6px; border-radius: 6px; user-select: none;
}
.sidegroup > summary::-webkit-details-marker { display: none; }
.sidegroup > summary::after {
  content: ""; width: 6px; height: 6px; border-right: 1.5px solid currentColor; border-bottom: 1.5px solid currentColor;
  transform: rotate(45deg); margin: -3px 0 0 auto; opacity: 0; transition: opacity .15s, transform .15s;
}
.sidegroup > summary:hover::after { opacity: .8; }
.sidegroup:not([open]) > summary::after { transform: rotate(-45deg); margin-top: 0; opacity: .8; }
.sidefoot { margin-top: auto; padding-top: 14px; display: flex; flex-direction: column; gap: 1px; }
.sideme {
  display: flex; align-items: center; gap: 10px; margin-top: 8px; padding: 10px 10px 2px;
  border-top: 1px solid var(--line); font-size: 13px;
}
.sideme .avatar {
  width: 28px; height: 28px; flex: none; border-radius: 50%; background: var(--gold-soft); color: var(--gold-ink);
  font-size: 12px; font-weight: 600; display: flex; align-items: center; justify-content: center;
}
.sidemine { display: flex; align-items: center; gap: 10px; flex: 1 1 auto; min-width: 0; color: inherit; text-decoration: none; border-radius: 8px; margin: -4px -6px; padding: 4px 6px; }
.sidemine:hover { background: var(--surface-2); text-decoration: none; }
.sidename { flex: 1 1 auto; min-width: 0; font-weight: 500; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.sidename small { display: block; font-size: 11px; font-weight: 400; color: var(--muted); }
.sideout { font-size: 12px; color: var(--muted); }

/* ---- the phone ------------------------------------------------------------ */
@media (max-width: 900px) {
  body.has-side .app { display: block; }
  body.ui-new .side {
    position: fixed; left: 0; top: 0; bottom: var(--vfix, 0px); z-index: 80; width: min(320px, 86vw); height: auto;
    transform: translateX(-105%); transition: transform .25s ease; box-shadow: var(--shadow-lg);
    padding-top: max(14px, env(safe-area-inset-top));
    padding-bottom: max(12px, env(safe-area-inset-bottom));
  }
  .sidecheck:checked ~ .side { transform: none; }
  .sidecheck:checked ~ .sidescrim { display: block; position: fixed; inset: 0; bottom: var(--vfix, 0px); z-index: 70; background: rgba(10, 11, 14, .32); }
  .sideclose { display: inline-flex; }
  .sl { min-height: 44px; font-size: 15px; }
  .sidegroup > summary { font-size: 13px; padding-top: 8px; }
  body.has-side .appmain > .wrap { padding-top: max(16px, env(safe-area-inset-top)); padding-bottom: calc(110px + max(var(--vfix, 0px), 0px)); }
  body.has-side .tabbar {
    display: flex; position: fixed; left: 0; right: 0; bottom: var(--vfix, 0px); z-index: 60;
    padding: 6px 4px max(8px, env(safe-area-inset-bottom));
    background: color-mix(in srgb, var(--surface) 97%, transparent);
    -webkit-backdrop-filter: saturate(1.6) blur(18px); backdrop-filter: saturate(1.6) blur(18px);
    border-top: 1px solid var(--line);
  }
  .tab {
    position: relative; flex: 1 1 0; min-height: 50px; display: flex; flex-direction: column; align-items: center; justify-content: center;
    gap: 2px; color: var(--muted); font-size: 11px; font-weight: 500; text-decoration: none; cursor: pointer; letter-spacing: 0;
    text-transform: none; margin: 0;
  }
  .tab.on { color: var(--navy); font-weight: 600; }
  .tab .badge { position: absolute; top: 2px; left: calc(50% + 6px); margin: 0; }
  .tab:hover { text-decoration: none; }
}
@media (prefers-reduced-motion: reduce) { body.ui-new .side { transition: none; } }
@media print { .side, .tabbar, .sidescrim { display: none !important; } body.has-side .app { display: block; } }

/* ---- type and headings ------------------------------------------------------ */
body.ui-new h1 { font-size: 28px; font-weight: 700; letter-spacing: -.02em; }
body.ui-new .pagehead .rule { display: none; }
body.ui-new .eyebrow { font-size: 13px; font-weight: 600; }
body.ui-new label { font-size: 13px; }

/* ---- the notice: a strip, not a banner ------------------------------------ */
body.ui-new .announcebar:not(.demobar) .announce {
  display: flex; flex-wrap: wrap; align-items: center; column-gap: 10px; row-gap: 4px;
  border: 0; border-radius: 10px; background: var(--gold-soft); padding: 8px 12px;
}
body.ui-new .announcebar:not(.demobar) .announceflag {
  margin: 0; color: var(--gold-ink); font-size: 13px; font-weight: 700; display: inline-flex; align-items: center; gap: 6px;
}
body.ui-new .announcebar:not(.demobar) .announceflag::before {
  content: ""; width: 7px; height: 7px; border-radius: 50%; background: var(--gold);
}
body.ui-new .announcebar:not(.demobar) .announcebody { flex: 1 1 320px; font-size: 15px; font-weight: 600; max-width: none; line-height: 1.4; }
body.ui-new .announcebar:not(.demobar) .announcewho { margin: 0; font-size: 12px; color: var(--ink-2); }
body.ui-new .announcebar:not(.demobar) .announcewho .inlineform { margin-left: 0; }
.announcegot { display: none; }
body.ui-new .announcegot { display: inline-block; }
body.ui-new .announce.folded { cursor: pointer; padding: 5px 12px; }
body.ui-new .announce.folded .announcebody { font-size: 13px; font-weight: 500; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; flex-basis: 0; min-width: 0; }
body.ui-new .announce.folded .announcewho { display: none; }
body.ui-new .announcebar { margin-bottom: 16px; }

/* ---- controls ------------------------------------------------------------------ */
/* One segmented control: the same pill track for every "switch the view". */
body.ui-new .seg { border-radius: 10px; padding: 2px; gap: 2px; background: color-mix(in srgb, var(--ink) 8%, transparent); }
body.ui-new .seg a, body.ui-new .seg .segopt { border-radius: 8px; padding: 4px 12px; font-size: 13px; }
body.ui-new .seg a.on, body.ui-new .seg .segopt.on { box-shadow: 0 1px 2px rgba(0,0,0,.12); border-color: transparent; }
body.ui-new .lanetabs a { border-radius: 8px; }
/* A page's own sections: underlined tabs, under the family's segmented bar (assets/app.css, 28 October). */
body.ui-new .seg.pagetabs { background: transparent; border-radius: 0; padding: 0; gap: 2px; }
body.ui-new .seg.pagetabs a { border-radius: 0; padding: 10px 14px; font-size: var(--fs-3); }
body.ui-new .seg.pagetabs a.on { box-shadow: none; border-color: transparent; border-bottom-color: var(--navy); }
/* Buttons: the full navy one is the primary action. .mini and .btn.ghost are the
   same quiet button at two sizes. */
body.ui-new .mini { border-radius: 8px; background: var(--surface); border-color: var(--line); color: var(--ink-2); font-size: 12px; }
body.ui-new .mini:hover { background: var(--surface-2); border-color: var(--line); color: var(--ink); }
body.ui-new .btn { border-radius: 10px; }
body.ui-new .btn.ghost { background: var(--surface); border-color: var(--line); color: var(--ink); }
body.ui-new .btn.ghost:hover { background: var(--surface-2); border-color: var(--line); color: var(--ink); }
body.ui-new .card { border-radius: 14px; }
body.ui-new .pill, body.ui-new .tag, body.ui-new .phasechip { border-radius: 6px; font-size: 12px; font-weight: 600; }
body.ui-new thead th { font-size: 12px; font-weight: 600; }

/* ---- the page that says "not yours" ------------------------------------------ */
.noaccess { max-width: 520px; margin: 12vh auto 0; text-align: center; }
.noaccess .ico { color: var(--muted); }
.noaccess h1 { font-size: 22px; margin: 14px 0 6px; }
.noaccess p { color: var(--ink-2); margin: 0 0 18px; }
.noaccess .acts { display: flex; gap: 10px; justify-content: center; flex-wrap: wrap; }

/* ---- Today ----------------------------------------------------------------------
   Four cards, two by two on a laptop, one column on a phone. Each shows a
   handful and links to the whole; the long lists stay on their own pages. */
.todayhead { display: flex; align-items: flex-end; justify-content: space-between; gap: 12px; flex-wrap: wrap; margin-bottom: 18px; }
.todayhead h1 { margin: 0; }
.todayhead .sub { margin: 2px 0 0; color: var(--muted); font-size: 15px; }
.todayacts { display: flex; gap: 8px; align-items: center; }
.todayacts .btn .ico { margin-right: 4px; }
.todaygrid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 16px; align-items: start; }
@media (max-width: 1100px) { .todaygrid { grid-template-columns: minmax(0, 1fr); } }
.todaygrid.is-masonry { display: flex; align-items: flex-start; }
.todaygrid.is-masonry > .tcol { flex: 1 1 0; min-width: 0; display: flex; flex-direction: column; gap: 16px; }
/* Today's weather, beside the date: a quiet chip, never a card. */
.twx { display: inline-flex; align-items: center; gap: 5px; margin-left: 10px; padding: 2px 10px 2px 8px; border-radius: 99px;
       background: var(--surface); border: 1px solid var(--line-soft); font-size: 13px; color: var(--ink-2); vertical-align: 1px; white-space: nowrap; }
.twx .ico { color: var(--gold, #A67C1F); }
.twx b { font-weight: 600; color: var(--ink); }
@media (max-width: 560px) { .twx { display: flex; width: max-content; margin: 6px 0 0; } }
.tcard { background: var(--surface); border-radius: 14px; box-shadow: var(--shadow-sm); border: 1px solid var(--line-soft); padding: 14px 16px 12px; min-width: 0; }
.tcard > header { display: flex; align-items: center; gap: 8px; margin: 0 0 8px; }
.tcard > header h2 { font-size: 17px; margin: 0; flex: 1 1 auto; font-weight: 600; letter-spacing: -.01em; }
.tcard > header a { font-size: 13px; font-weight: 500; }
.tcard > header .badge { margin: 0; }
.tcard > header .tcardadd { min-height: 32px; line-height: 30px; padding: 0 12px; font-size: 13px; }
.tdim { color: var(--muted); font-weight: 400; }
.tempty { display: flex; align-items: center; gap: 8px; color: var(--muted); margin: 6px 0 8px; font-size: 15px; }
.tempty .ico { color: var(--good); }
.tlist { list-style: none; margin: 0 -6px; padding: 0; }
.tlist a { display: flex; align-items: center; gap: 12px; padding: 8px 6px; border-radius: 10px; color: var(--ink); text-decoration: none; }
.tlist a:hover { background: var(--hover, rgba(0,0,0,.04)); text-decoration: none; }
.tico { width: 36px; height: 36px; border-radius: 10px; display: flex; align-items: center; justify-content: center; flex: none; background: var(--surface-2); color: var(--ink-2); }
.tico.navy { background: var(--navy-soft); color: var(--navy); }
.tico.gold { background: var(--gold-soft); color: var(--gold-ink); }
.tico.red { background: var(--crit-soft); color: var(--crit); }
.ttxt { display: flex; flex-direction: column; min-width: 0; flex: 1 1 auto; }
.ttxt b { font-size: 15px; font-weight: 600; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.ttxt span { font-size: 13px; color: var(--muted); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.ttag { flex: none; font-size: 12px; font-weight: 600; color: var(--warn-ink, var(--warn)); background: var(--warn-soft); border-radius: 6px; padding: 2px 8px; }
.tmore { font-size: 13px; color: var(--muted); margin: 6px 0 0; }
.ttasks { margin: 0; }
.tadd { display: flex; gap: 8px; align-items: center; margin-top: 8px; padding-top: 8px; border-top: 1px solid var(--line-soft); }
.tadd input { flex: 1 1 auto; margin: 0; min-height: var(--ctl-sm); border-color: transparent; background: transparent; padding-left: 4px; }
.tadd input:focus { border-color: var(--navy-line); background: var(--surface); }
.twhen { list-style: none; margin: 0; padding: 0; display: grid; gap: 8px; font-size: 15px; }
.twhen li { display: grid; grid-template-columns: 64px minmax(0, 1fr); gap: 8px; }
.twhen .tt { color: var(--navy); font-weight: 600; font-variant-numeric: tabular-nums; }
.tserve { margin-top: 12px; padding-top: 10px; border-top: 1px solid var(--line-soft); display: grid; gap: 6px; font-size: 13px; }
.tserve > div:first-child { display: flex; justify-content: space-between; gap: 10px; }
.tserve span { color: var(--muted); }
/* This week: a day at a time, each with its own heading and, under a day
   with a service, its serving bar. */
.tday + .tday { margin-top: 12px; padding-top: 12px; border-top: 1px solid var(--line-soft); }
.tday h3 { font-size: 14px; font-weight: 600; margin: 0 0 6px; letter-spacing: -.005em; }
.tweek .twhen li { grid-template-columns: 76px minmax(0, 1fr); }
.tday .tserve { margin-top: 8px; padding-top: 0; border-top: 0; }
.tday .tserve b span { font-weight: 500; }
.tbar { height: 6px; border-radius: 3px; background: var(--surface-2); overflow: hidden; }
.tbar i { display: block; height: 6px; border-radius: 3px; background: var(--good); }
.tbar i.short { background: var(--warn); }
.talert { display: flex; align-items: center; gap: 10px; padding: 9px 12px; border-radius: 10px; background: var(--crit-soft); color: var(--ink); text-decoration: none; font-size: 13px; margin-bottom: 10px; }
.talert:hover { text-decoration: none; }
.talert .dot { width: 8px; height: 8px; border-radius: 4px; background: var(--crit); flex: none; }
.talert > span:nth-child(2) { flex: 1 1 auto; }
.talert .go { font-weight: 600; color: var(--crit); }
.tfacts { display: grid; grid-template-columns: 96px minmax(0, 1fr); gap: 8px 10px; margin: 0; font-size: 13px; }
.tfacts dt { color: var(--muted); }
.tfacts dd { margin: 0; }

/* ---- ⌘K ----------------------------------------------------------------------- */
.pal { position: fixed; inset: 0; z-index: 200; }
.pal[hidden] { display: none; }
.palscrim { position: absolute; inset: 0; background: rgba(10, 11, 14, .28); }
.palbox {
  position: absolute; left: 50%; top: 12vh; transform: translateX(-50%); width: min(640px, calc(100vw - 24px));
  max-height: 72vh; display: flex; flex-direction: column; overflow: hidden;
  background: var(--surface); border-radius: 14px; border: 1px solid var(--line);
  box-shadow: 0 24px 60px rgba(0,0,0,.28), 0 2px 6px rgba(0,0,0,.1);
}
.palhead { display: flex; align-items: center; gap: 10px; padding: 0 12px 0 16px; border-bottom: 1px solid var(--line-soft); }
.palhead::before {
  content: ""; width: 18px; height: 18px; flex: none; opacity: .6;
  background: currentColor; color: var(--muted);
  -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round'%3E%3Ccircle cx='11' cy='11' r='7'/%3E%3Cpath d='M20 20l-4.3-4.3'/%3E%3C/svg%3E") center / contain no-repeat;
          mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round'%3E%3Ccircle cx='11' cy='11' r='7'/%3E%3Cpath d='M20 20l-4.3-4.3'/%3E%3C/svg%3E") center / contain no-repeat;
}
.palin { flex: 1 1 auto; border: 0 !important; outline: none; box-shadow: none !important; background: transparent !important;
         font: inherit; font-size: 17px; height: 56px; margin: 0; padding: 0; color: var(--ink); }
.palin::-webkit-search-cancel-button { display: none; }
.palesc { font: inherit; font-size: 12px; color: var(--muted); background: var(--surface-2); border: 0; border-radius: 6px; padding: 3px 8px; cursor: pointer; }
.pallist { overflow-y: auto; padding: 6px 8px 8px; }
.palgroup { font-size: 12px; font-weight: 600; color: var(--muted); padding: 10px 10px 4px; }
.palnote { font-size: 13px; color: var(--muted); padding: 10px; }
.palrow { display: flex; align-items: center; gap: 12px; padding: 8px 10px; border-radius: 10px; color: var(--ink); text-decoration: none; }
.palrow:hover { text-decoration: none; }
.palrow.on { background: var(--navy); color: var(--on-accent); }
.palrow.on .paltxt span { color: inherit; opacity: .82; }
.paltxt { display: flex; flex-direction: column; min-width: 0; }
.paltxt b { font-size: 15px; font-weight: 600; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.paltxt span { font-size: 12px; color: var(--muted); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.palkind { width: 30px; height: 30px; flex: none; border-radius: 8px; background: var(--surface-2); position: relative; }
.palkind::after { content: ""; position: absolute; inset: 7px; border-radius: 3px; background: var(--ink-2); opacity: .5;
                  -webkit-mask: var(--kmask) center / contain no-repeat; mask: var(--kmask) center / contain no-repeat; }
.palrow.on .palkind { background: rgba(255,255,255,.16); }
.palrow.on .palkind::after { background: var(--on-accent); opacity: 1; }
.palkind.k-action { --kmask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2.4' stroke-linecap='round'%3E%3Cpath d='M5 12h14M13 6l6 6-6 6'/%3E%3C/svg%3E"); }
.palkind.k-task { --kmask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2.4' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m5 12.5 4.5 4.5L19 7.5'/%3E%3C/svg%3E"); }
.palkind.k-calendar, .palkind.k-meeting, .palkind.k-event, .palkind.k-resource, .palkind.k-trip { --kmask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2.2'%3E%3Crect x='3' y='5' width='18' height='16' rx='2.5'/%3E%3Cpath d='M3 10h18M8 3v4M16 3v4'/%3E%3C/svg%3E"); }
.palkind.k-person, .palkind.k-guest, .palkind.k-role { --kmask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2.2'%3E%3Ccircle cx='12' cy='8' r='3.6'/%3E%3Cpath d='M4.5 20.5a7.5 7.5 0 0 1 15 0'/%3E%3C/svg%3E"); }
.palkind.k-message { --kmask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2.2' stroke-linejoin='round'%3E%3Cpath d='M4 5h16v11H9l-5 4z'/%3E%3C/svg%3E"); }
.palkind.k-file, .palkind.k-project, .palkind.k-vendor, .palkind.k-maintenance, .palkind.k-serve, .palkind.k-prayer, .palkind.k-screen, .palkind.k-item { --kmask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2.2' stroke-linejoin='round'%3E%3Cpath d='M14 3H7a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h10a2 2 0 0 0 2-2V8z'/%3E%3Cpath d='M14 3v5h5'/%3E%3C/svg%3E"); }
.palfoot { display: flex; gap: 16px; align-items: center; padding: 9px 16px; border-top: 1px solid var(--line-soft); font-size: 12px; color: var(--muted); background: var(--surface-2); }
.palall { margin-left: auto; font-weight: 600; }
@media (max-width: 600px) { .palbox { top: max(12px, env(safe-area-inset-top)); max-height: 80vh; } .palfoot span { display: none; } }
html.palopen { overflow: hidden; }

/* The sidebar holds still while the page cross-fades, as the top bar does. */
body.ui-new .side { view-transition-name: ws-side; }
::view-transition-group(ws-side) { animation-duration: .18s; }

/* Links that are controls, not prose, carry no underline — the color says link. */
body.ui-new .tcard > header a, body.ui-new .sechead a, body.ui-new .todayacts a, body.ui-new .tmore a { text-decoration: none; }
body.ui-new .tcard > header a:hover, body.ui-new .sechead a:hover { text-decoration: underline; }

/* Phone details. The tab bar's "More" is a <label>, so it must not pick up the
   form-label size; the notice's two buttons sit on one line. */
body.ui-new .tabbar .tab { font-size: 11px; font-weight: 500; }
body.ui-new .tabbar .tab.on { font-weight: 600; }
@media (max-width: 560px) {
  body.ui-new .announcebar:not(.demobar) .announcewho { gap: 8px; }
  body.ui-new .announcebar:not(.demobar) .announcewho .inlineform { width: auto; }
  body.ui-new .announcebar:not(.demobar) .announcewho .mini { min-height: 32px; }
  body.ui-new .announcebar:not(.demobar) .announcewho { flex-basis: 100%; }
  .todayacts .btn { min-height: 40px; }
}
/* The palette's box is the whole dialog; a ring around the input inside it is noise. */
.palin:focus, .palin:focus-visible { outline: none !important; }
.todayacts .btn { min-height: 38px; line-height: 36px; padding: 0 14px; }
/* A keyboard ring in the brand's navy, the Apple way, on the redesign's own controls. */
body.ui-new .sl:focus-visible, body.ui-new .tab:focus-visible, body.ui-new .sidesearch:focus-visible, body.ui-new .palrow:focus-visible { outline: 2px solid var(--navy); outline-offset: 1px; }

/* ---- the inspector: a list, and the chosen one open beside it ------------------ */
.insp { display: grid; grid-template-columns: minmax(280px, 400px) minmax(0, 1fr); gap: 16px; align-items: start; }
.insp-list { display: flex; flex-direction: column; gap: 2px; background: var(--surface); border: 1px solid var(--line-soft); border-radius: 14px; padding: 6px; box-shadow: var(--shadow-sm); position: sticky; top: 16px; max-height: calc(100vh - 32px); overflow-y: auto; }
.insp-row { display: grid; grid-template-columns: minmax(0, 1fr) auto; column-gap: 8px; padding: 9px 10px; border-radius: 10px; color: var(--ink); text-decoration: none; }
.insp-row b { font-size: 15px; font-weight: 600; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.insp-row span { grid-column: 1; font-size: 13px; color: var(--muted); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.insp-row .insp-flag { grid-column: 2; grid-row: 1 / span 2; align-self: center; font-style: normal; font-size: 12px; font-weight: 600; color: var(--crit); background: var(--crit-soft); padding: 2px 7px; border-radius: 6px; }
.insp-row .insp-flag.quiet { color: var(--ink-2); background: var(--surface-2); }
.insp-row:hover { background: var(--surface-2); text-decoration: none; }
.insp-row.on { background: var(--navy); color: var(--on-accent); }
.insp-row.on span { color: inherit; opacity: .8; }
.insp-pane { min-width: 0; transition: opacity .12s; }
.insp-pane.is-loading { opacity: .45; }
.insp-pane > .card { margin: 0; }
@media (max-width: 900px) {
  .insp { grid-template-columns: minmax(0, 1fr); }
  .insp-list { position: static; max-height: none; order: 2; }
  .insp-pane { order: 1; }
}

/* ---- sheets: making something new, without leaving the page ------------------- */
.sheet { position: fixed; inset: 0; bottom: var(--vfix, 0px); z-index: 190; }
.sheet[hidden] { display: none; }
.sheetscrim { position: absolute; inset: 0; background: rgba(10, 11, 14, .28); }
.sheetpanel {
  position: absolute; left: 50%; top: 0; transform: translateX(-50%); width: min(760px, 100vw);
  max-height: calc(100vh - 24px); overflow-y: auto; background: var(--ground);
  border-radius: 0 0 16px 16px; box-shadow: 0 24px 60px rgba(0,0,0,.28);
  animation: sheetin .22s ease;
}
@keyframes sheetin { from { transform: translate(-50%, -24px); opacity: 0; } to { transform: translate(-50%, 0); opacity: 1; } }
@media (prefers-reduced-motion: reduce) { .sheetpanel { animation: none; } }
.sheethead { position: sticky; top: 0; z-index: 1; display: flex; align-items: center; gap: 10px; padding: 14px 20px; background: var(--ground); border-bottom: 1px solid var(--line-soft); }
.sheettitle { flex: 1 1 auto; margin: 0; font-size: 17px; }
.sheetx { font: inherit; font-size: 13px; font-weight: 600; color: var(--navy); background: none; border: 0; cursor: pointer; padding: 6px 4px; }
.sheetbody { padding: 16px 20px 20px; }
.sheetbody > .card { margin: 0; box-shadow: none; }
@media (max-width: 600px) { .sheetpanel { top: auto; bottom: 0; border-radius: 16px 16px 0 0; max-height: 92vh; padding-bottom: env(safe-area-inset-bottom); animation-name: sheetup; } }
/* An add form on the page, in a pop-up (14 October; shell.js 5b, lib/view.php pop_button). Hidden on the page
   until its button is pressed — or shown where it is if the script never ran (the button is a link to it). */
html.js .popbody { display: none; }
html.js .popbody:target, html.js .sheet .popbody, .sheet .popbody { display: block; }
.sheetbody > .popbody > .card, .sheetbody > .popbody > form.card { margin: 0; box-shadow: none; border: 0; padding: 0; background: transparent; }
.sheetbody > .popbody > .card + .card { margin-top: 14px; }
.popflash { margin: 0 0 14px; animation: none; }
.sheet.ispop .sheettitle { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.sheetgo { flex: none; min-height: 36px; line-height: 34px; padding: 0 14px; font-size: 14px; background: var(--navy); color: var(--on-accent); border: 0; border-radius: 10px; }
.sheetgo:hover { background: color-mix(in srgb, var(--navy) 88%, #000); color: var(--on-accent); }
.popbtn { white-space: nowrap; }
.popbtn .ico { margin-right: 4px; vertical-align: -2px; }
.sechead .popbtn, .wfhead .popbtn { margin-left: auto; align-self: center; }
/* A page whose one add button sits at the top right of its heading (RegSite, Forms…). */
.pagehead.headact { display: flex; align-items: flex-end; justify-content: space-between; gap: 16px; flex-wrap: wrap; }
.pagehead.headact > div { min-width: 0; flex: 1 1 auto; }
.pagehead.headact > .popbtn { flex: none; }
@media (max-width: 600px) { .pagehead.headact { flex-wrap: nowrap; align-items: flex-start; } .pagehead.headact > .popbtn { margin-top: 18px; } }
@media (min-width: 601px) {
  .sheet.ispop .sheetpanel { top: 50%; transform: translate(-50%, -50%); width: min(640px, calc(100vw - 32px)); max-height: calc(100vh - 48px); border-radius: 16px; animation-name: popin; }
}
@keyframes popin { from { transform: translate(-50%, calc(-50% + 16px)); opacity: 0; } to { transform: translate(-50%, -50%); opacity: 1; } }
@media (max-width: 600px) {
  .sheet.ispop .sheetpanel { max-height: calc(100% - 10px); width: 100vw; }
  .sheet.ispop .sheethead { padding: 12px 16px; }
  .sheet.ispop .sheetbody { padding: 14px 16px 22px; }
}
@keyframes sheetup { from { transform: translate(-50%, 40px); opacity: 0; } to { transform: translate(-50%, 0); opacity: 1; } }
/* A field's words are ordinary weight; only its label is bold. */
body.ui-new label input, body.ui-new label select, body.ui-new label textarea { font-weight: 400; }

/* ---- "When you approve, also…" ---------------------------------------------------
   Unscoped: the approval card is the same in Classic, and so is this. */
.fanset { border: 1px solid var(--line); border-radius: 12px; padding: 4px 0; margin: 10px 0 0; background: var(--surface); }
.fanset legend { font-size: 13px; font-weight: 600; color: var(--ink); padding: 0 6px; margin-left: 8px; text-transform: none; letter-spacing: 0; }
.fanopt { display: flex; align-items: flex-start; gap: 10px; padding: 8px 12px; margin: 0; border-top: 1px solid var(--line-soft); cursor: pointer;
          text-transform: none; letter-spacing: 0; font-weight: 400; font-size: 13px; color: var(--ink); }
.fanopt:first-of-type { border-top: 0; }
.fanopt input { width: auto; margin: 3px 0 0; flex: none; }
.fanopt span { display: flex; flex-direction: column; }
.fanopt b { font-weight: 600; }
.fanopt i { font-style: normal; color: var(--muted); font-size: 12px; }
.fanopt.is-off { cursor: default; }
.fanopt.is-off b { color: var(--muted); }
.fanlist { list-style: none; margin: 8px 0 0; padding: 0; display: grid; gap: 6px; font-size: 13px; }
.fanlist li { display: grid; grid-template-columns: 10px 110px minmax(0, 1fr) auto; gap: 10px; align-items: center; }
.fanlist li span:nth-child(3) { color: var(--ink-2); }
.fanlist a { font-size: 12px; font-weight: 600; }

/* Room panels on the Rooms page. */
.panelcards { display: grid; grid-template-columns: repeat(auto-fill, minmax(340px, 1fr)); gap: 12px; }
.panelcard .setdot { display: inline-block; vertical-align: middle; }

/* Pull to refresh, in the installed app (assets/shell.js). */
.pullhint { position: fixed; left: 50%; top: max(8px, env(safe-area-inset-top)); z-index: 300; transform: translate(-50%, 0);
            background: var(--surface); color: var(--ink-2); border: 1px solid var(--line); border-radius: 999px; padding: 6px 14px;
            font-size: 13px; font-weight: 600; box-shadow: var(--shadow-sm); opacity: 0; pointer-events: none; }
body.has-side .appmain { background: var(--ground); }

/* ---- one page per person (who.php) ---- */
.whohead { display: flex; align-items: center; gap: 16px; margin-bottom: 12px; }
.whohead h1 { margin: 0; }
.whohead .sub { margin: 2px 0 0; color: var(--muted); }
.whoav { width: 64px; height: 64px; border-radius: 50%; background: var(--gold-soft); color: var(--gold-ink); font-size: 22px; font-weight: 600; display: flex; align-items: center; justify-content: center; flex: none; }
.whoacts { display: flex; gap: 8px; flex-wrap: wrap; margin-bottom: 18px; }
.whoacts .btn .ico { margin-right: 4px; }
.whogrid { display: grid; grid-template-columns: repeat(auto-fill, minmax(280px, 1fr)); gap: 14px; align-items: start; }

/* =====================================================================
   THE APP UPGRADE (7 October 2026, from the mock-up Craig approved).
   ===================================================================== */
/* New, in the sidebar. */
.sidenew { display: flex; align-items: center; justify-content: center; gap: 8px; min-height: 38px; margin: 0 0 12px; border-radius: 10px;
           background: var(--navy); color: var(--on-accent); font-size: 14px; font-weight: 600; text-decoration: none; }
.sidenew:hover { background: color-mix(in srgb, var(--navy) 88%, #000); color: var(--on-accent); text-decoration: none; }
.sidenew .ico { color: inherit; }
/* The phone: a slim bar at the top (Inbox, search), and the menu in the middle of the tab bar (9 October). */
.phonebar { display: none; }
@media (max-width: 900px) {
  body.has-side .phonebar { display: flex; justify-content: space-between; align-items: center; position: sticky; top: 0; z-index: 50;
    padding: max(8px, env(safe-area-inset-top)) 12px 6px; background: color-mix(in srgb, var(--ground) 90%, transparent);
    -webkit-backdrop-filter: saturate(1.6) blur(18px); backdrop-filter: saturate(1.6) blur(18px); }
  body.has-side .appmain > .wrap { padding-top: 6px; }
  .pbbtn { width: 40px; height: 40px; border-radius: 12px; background: var(--surface); border: 1px solid var(--line); display: inline-flex; align-items: center; justify-content: center; color: var(--ink); cursor: pointer; }
  .pbright { display: inline-flex; gap: 8px; margin-left: auto; }
  .tabmenu { cursor: pointer; -webkit-tap-highlight-color: transparent; }
  .tabmenu:active .tabplus { transform: scale(.94); }
  .tabplus { transition: transform .12s ease; }
  .pbinbox { position: relative; }
  .pbinbox .badge { position: absolute; top: -3px; right: -5px; margin: 0; }
  .tabnew { flex: 0 0 64px; }
  .tabplus { width: 44px; height: 44px; border-radius: 50%; background: var(--navy); color: var(--on-accent); display: flex; align-items: center; justify-content: center; margin-top: -16px; box-shadow: 0 4px 14px rgba(30,58,95,.35); }
  /* Every tab says what it is, the middle one too (14 October review). */
  .tabmenu .tablbl { font-size: 11px; font-weight: 500; color: var(--muted); line-height: 1; margin-top: 2px; }
  .tabnew .ico { color: var(--on-accent); }
}
/* A family of pages: one strip of tabs at the top. */
.sectabs { display: flex; gap: 2px; padding: 3px; margin: 0 0 18px; border-radius: 11px; background: color-mix(in srgb, var(--ink) 7%, transparent); width: max-content; max-width: 100%; overflow-x: auto; scrollbar-width: none; }
.sectabs::-webkit-scrollbar { display: none; }
.sectabs a { flex: none; padding: 6px 14px; border-radius: 9px; font-size: 13px; font-weight: 600; color: var(--ink-2); text-decoration: none; min-height: 32px; display: inline-flex; align-items: center; box-sizing: border-box; }
.sectabs a:hover { color: var(--ink); text-decoration: none; }
.sectabs a.on { background: var(--surface); color: var(--ink); box-shadow: 0 1px 2px rgba(0,0,0,.14); }
/* Today: Edit Today, the cards' extras. */
.tedit { margin: 0 0 18px; }
.tedit[hidden] { display: none; }
.teditH h2 { margin: 0 0 4px; font-size: 17px; }
.teditH .note { margin: 0 0 10px; }
.teditlist { list-style: none; margin: 0 0 12px; padding: 0; display: grid; gap: 6px; }
.teditrow { display: flex; align-items: center; gap: 10px; padding: 6px 8px; border: 1px solid var(--line-soft); border-radius: 12px; background: var(--surface); }
.teditname { flex: 1 1 auto; display: flex; align-items: center; gap: 10px; margin: 0; font-size: 15px; cursor: pointer; min-height: 40px; }
.teditname input { width: 20px; height: 20px; margin: 0; flex: none; }
.teditname .tico { width: 30px; height: 30px; border-radius: 8px; }
.teditname b { font-weight: 600; }
.teditmove { display: inline-flex; gap: 4px; flex: none; }
.talerts { margin-bottom: 16px; }
.talerts .flash { margin-top: 0 !important; margin-bottom: 10px; }
.tcard .sec { margin: 0; }
.tcard .sec > .sechead { display: none; }
.tcard .talkrecent { box-shadow: none; border: 0; padding: 0; background: transparent; }
.tcard .talkrecent .trhead { display: none; }
.tcard .reqgrid { grid-template-columns: minmax(0, 1fr); }
.tcard .evgrid, .tcard .runway { grid-template-columns: minmax(0, 1fr) !important; }
.tcard .topgrid { display: block; }
.tneeds li { padding: 4px 0; border-bottom: 1px solid var(--line-soft); }
.tneeds li:last-child { border-bottom: 0; }
.tneeds .ib-acts { margin: 0 6px 8px 54px; }
.tdate { width: 40px; flex: none; text-align: center; border-radius: 10px; background: var(--gold-soft); color: var(--gold-ink); font-weight: 700; font-size: 17px; line-height: 1.1; padding: 4px 0; }
.tdate small { display: block; font-size: 10px; letter-spacing: .04em; }
.tdate.none { background: var(--surface-2); color: var(--muted); }
.tstats { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 8px; margin-bottom: 10px; }
.tstats div { background: var(--surface-2); border-radius: 10px; padding: 8px 10px; }
.tstats b { display: block; font-size: 22px; }
.tstats span { font-size: 12px; color: var(--muted); }
.tstats .is-late b { color: var(--crit); }
.tteam { width: 100%; border-collapse: collapse; font-size: 13px; }
.tteam th, .tteam td { padding: 7px 6px; border-top: 1px solid var(--line-soft); text-align: right; font-variant-numeric: tabular-nums; }
.tteam thead th { border-top: 0; color: var(--muted); font-weight: 600; font-size: 12px; }
.tteam th[scope=row], .tteam thead th:first-child { text-align: left; font-weight: 600; }
.tteam th small { display: block; font-weight: 400; }
.tteam td.bad { color: var(--crit); font-weight: 700; }
.tglance { display: grid; grid-template-columns: repeat(auto-fit, minmax(130px, 1fr)); gap: 8px; }
.tglance a { display: flex; flex-direction: column; padding: 10px 12px; border-radius: 12px; background: var(--surface-2); color: var(--ink); text-decoration: none; }
.tglance a b { font-size: 24px; }
.tglance a span { font-size: 12px; color: var(--muted); }
.tglance a.is-on b { color: var(--navy); }
.tnotice { margin: 0 0 8px; font-size: 14px; }
/* New. */
.newhead h1 { font-size: 22px; margin: 6px 0 14px; }
.newgrid { display: grid; grid-template-columns: repeat(auto-fit, minmax(240px, 1fr)); gap: 10px; }
.newchoice { display: flex; align-items: center; gap: 12px; padding: 14px; border-radius: 14px; border: 1px solid var(--line); background: var(--surface); color: var(--ink); text-decoration: none; min-height: 64px; box-sizing: border-box; }
.newchoice:hover { border-color: var(--navy-line); text-decoration: none; }
.newchoice .ttxt b { white-space: normal; }
.newchoice .ttxt span { white-space: normal; }
.newfold { display: block; padding: 0; }
.newfold > summary { list-style: none; display: flex; align-items: center; gap: 12px; padding: 14px; cursor: pointer; }
.newfold > summary::-webkit-details-marker { display: none; }
.newfold[open] { grid-column: 1 / -1; }
.newform { display: grid; gap: 10px; padding: 0 14px 14px; }
.newtip { margin-top: 14px; }
@media (hover: none) { .newtip { display: none; } }
.newplan { display: grid; gap: 12px; }
.newkinds { border: 0; padding: 0; margin: 0; display: grid; grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); gap: 8px; min-width: 0; }
.newkinds legend { font-size: 13px; font-weight: 600; padding: 0; margin-bottom: 8px; }
.newkind { margin: 0; cursor: pointer; }
.newkind input { position: absolute; opacity: 0; pointer-events: none; }
.newkind span { display: flex; flex-direction: column; gap: 2px; padding: 12px; border-radius: 12px; border: 1px solid var(--line); background: var(--surface); height: 100%; box-sizing: border-box; }
.newkind small { font-weight: 400; color: var(--muted); font-size: 12px; }
.newkind input:checked + span { border: 2px solid var(--navy); background: var(--navy-soft); padding: 11px; }
.newkind input:focus-visible + span { outline: 2px solid var(--navy); outline-offset: 2px; }
/* The keyboard is up (assets/shell.js): the tab bar steps aside, as an app's does. */
@media (max-width: 900px) { html.kb-open body.has-side .tabbar { transform: translateY(110%); pointer-events: none; } body.has-side .tabbar { transition: transform .18s ease; } }
/* The screen check (assets/app.js) */
.screencheck { position: fixed; left: 8px; right: 8px; top: max(60px, calc(env(safe-area-inset-top) + 50px)); z-index: 3000; background: rgba(0,0,0,.86); color: #9ef59e; border-radius: 12px; padding: 10px 12px; font: 11px/1.45 ui-monospace, Menlo, monospace; }
.screencheck pre { margin: 0 0 8px; white-space: pre-wrap; word-break: break-all; font: inherit; }
.screencheck button { font: 600 12px system-ui, sans-serif; border: 0; border-radius: 8px; padding: 6px 10px; background: #fff; color: #000; }

/* Long lists: the first 30, and "Show all" (shell.js, 14 October review). */
.is-more-hidden { display: none !important; }
.more-btn-li { list-style: none; display: flex; justify-content: center; padding: 12px 8px; border-top: 1px solid var(--line-soft); }
.more-btn .note { margin-left: 4px; font-weight: 400; }

/* ===========================================================================
   SECOND REVIEW PASS (14 October): the same thing looks the same everywhere.
   Each rule here answers something the page-by-page review found on many
   pages at once, so it is fixed once rather than page by page.
   =========================================================================== */
/* A checkbox or a radio is 18px and sits level with the first line of its
   words. The control height every field has (36/44px) was reaching them too,
   so a radio was drawn in the middle of a tall box, below its label, and
   shrank to 13px in a flex row. Zero-class specificity: any component that
   hides its input (chips, swatches) still wins. */
input:where([type=checkbox], [type=radio]) { min-height: 0; width: 18px; height: 18px; padding: 0; margin: 2px 0 0; flex: none; accent-color: var(--navy); vertical-align: -3px; }
/* The browser's own "Choose File" button, dressed as ours. */
input[type=file] { padding: 6px; min-height: var(--ctl); line-height: calc(var(--ctl) - 14px); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; color: var(--muted); font-size: var(--fs-3); }
input[type=file]::file-selector-button { font: inherit; font-weight: 600; color: var(--navy); background: var(--surface); border: 1px solid var(--line); border-radius: var(--r-md); padding: 0 14px; min-height: calc(var(--ctl) - 14px); margin-right: 10px; cursor: pointer; }
input[type=file]:hover::file-selector-button { border-color: var(--navy); }
/* Something under a card — a button, a note, a form of its own — is never
   drawn against it. Zero specificity, so any spacing a component sets wins. */
/* (Set as the card's own bottom margin, which collapses with whatever space
   the next thing already asks for — so it only ever adds room, never takes a
   section's larger gap away.) */
.card:has(+ :is(p, .note, form, .btn, .mini, .btnrow, details, .inlineform, .flash, .empty, .hint, h2, h3, a.back, .actions, .rowacts, section, header, .rptotals)):not(:has(+ .card)) { margin-bottom: 16px; }
:is(p, .note, .sub, .hint, .btnrow, .inlineform, summary, header, section):has(+ .card) { margin-bottom: 12px; }
/* A wide table on a phone scrolls inside its own box (shell.js wraps it)
   instead of being cut off by its card. */
.tscroll { overflow-x: auto; max-width: 100%; -webkit-overflow-scrolling: touch; overscroll-behavior-x: contain; }
.tscroll > table { min-width: 100%; }
/* A section's "+ Add" stays on its heading's line, at the right, and the
   heading's note goes underneath, full width — on a phone and a computer
   alike, so a long note never pushes the button onto a line of its own. */
.sechead:has(> .popbtn, > span > .popbtn) > h2, .sechead:has(> .popbtn, > span > .popbtn) > h3,
.wfhead:has(> .popbtn) > h2, .wfhead:has(> .popbtn) > h3 { flex: 1 1 0; min-width: 0; }
.sechead > .popbtn, .sechead > span:has(> .popbtn), .wfhead > .popbtn { order: 2; }
.sechead:has(> .popbtn, > span > .popbtn) > :not(h2, h3, .popbtn, span:has(> .popbtn)),
.wfhead:has(> .popbtn) > :not(h2, h3, .popbtn) { order: 3; flex-basis: 100%; }
/* The page's own "+ Add" sits level with its title, on a phone and a
   computer alike; shell.js places it, and the description below runs the
   full width rather than a narrow column beside the button. */
.pagehead.headact.is-placed { position: relative; display: block; }
.pagehead.headact.is-placed > .popbtn, .pagehead.headact.is-placed > .btn { position: absolute; right: 0; margin: 0; }
/* A page that is not there (lib/view.php not_found). */
.nfpage { background: var(--bg, #f6f6f4); }
.nfbox { max-width: 520px; margin: 18vh auto 0; padding: 0 20px; }
.nfbox h1 { margin: 0 0 8px; }
.nfbox p { color: var(--ink-2); }
.nfbox .btnrow { display: flex; gap: 10px; flex-wrap: wrap; margin-top: 18px; }
/* Rows of filters and tabs on a phone: one line that scrolls sideways, with
   the fade (shell.js). Here, after every page's own stylesheet rule that
   let some of them wrap onto three lines (the Inbox filters, the service
   chips, Prayer's message filters, the print toolbar, a project's stages). */
@media (max-width: 700px) {
  html .ib-chips, html .svc-chips, html .pfilters, html .ci-tabs, html .pr-bar > nav, html .seg, html .phaseline {
    flex-wrap: nowrap; overflow-x: auto; overscroll-behavior-x: contain; scrollbar-width: none; max-width: 100%; -webkit-overflow-scrolling: touch; }
  html :is(.ib-chips, .svc-chips, .pfilters, .ci-tabs, .pr-bar > nav, .seg, .phaseline)::-webkit-scrollbar { display: none; }
  html :is(.ib-chips, .svc-chips, .pfilters, .ci-tabs, .pr-bar > nav, .seg, .phaseline) > * { flex: none; white-space: nowrap; }
}
/* Settings' groups share a class name with ServeSite's "Team members needed"
   heading, and were inheriting its 22px: card titles, the error-log line and
   notes in Settings came out bigger than the headings above them. */
.setmain .sgroup { font-size: var(--fs-4); }
/* Buttons in one row share one height. A small button beside a full-size
   one, or beside a field ("Find" beside the date range, "Spreadsheet" beside
   Find, "Past services" beside "+ Plan"), grows to the row's height. */
:is(div, form, p, span, li):has(> .btn) > :is(.mini, a.mini, button.mini) {
  min-height: var(--ctl); line-height: calc(var(--ctl) - 2px); padding-top: 0; padding-bottom: 0; font-size: var(--fs-3); }
:is(div, form, p, span, li):has(> .btn) > :is(.mini, a.mini, button.mini).sq { min-width: var(--ctl); }
/* On a phone, a field for words takes the whole width: two of them side by
   side were 139px each, too narrow to read what was typed in them, and cut
   their hints off mid-word. Numbers, dates and times keep sharing a line. */
@media (max-width: 600px) {
  .row > .field:has(> :is(input:is([type=text], [type=email], [type=tel], [type=url], [type=search], :not([type])), select, textarea)),
  .row > .field:has(> label + :is(input:is([type=text], [type=email], [type=tel], [type=url], [type=search], :not([type])), select, textarea)) { flex-basis: 100%; }
}
/* A status dot stays on the line it describes. In a settings row the words
   beside it no longer ask for 320px (a phone has 326), which put every dot
   on a line of its own; the Directory's freshness line is a sentence, so it
   is set as one, with its dot in it and "Refresh now" at its end. */
.setrow > .setdot + .setwhat { flex: 1 1 calc(100% - 22px); }
@media (min-width: 701px) { .setrow > .setdot + .setwhat { flex: 1 1 320px; } }
.dirfresh { display: block; line-height: 1.8; }
.dirfresh > .setdot { display: inline-block; vertical-align: 0; margin: 0 6px 0 0; }
.dirfresh > .inlineform { display: inline-block; margin-left: 8px; vertical-align: middle; }

/* A switch beside a long label sits level with its first line, like a box. */
.keepbox:has(> .tgl) { align-items: flex-start; }
.keepbox > .tgl { margin-top: 0; align-self: flex-start; }
/* The dot in a settings row keeps the line it starts; whatever follows it
   takes the rest of that line, on a phone too. */
@media (max-width: 700px) { :is(.setrow, .fgcardrow) > .setdot + * { flex: 1 1 calc(100% - 24px) !important; min-width: 0; } }
/* A state tag is one piece: "Answered prayer · October 2026" never breaks. */
.setstate { white-space: nowrap; display: inline-block; max-width: 100%; overflow: hidden; text-overflow: ellipsis; vertical-align: 1px; }
/* Today's quick-add keeps its compact field and button together. */
html body form.tadd > button.mini { min-height: var(--ctl-sm); line-height: calc(var(--ctl-sm) - 2px); padding-top: 0; padding-bottom: 0; }
/* A sentence with boxes in it ("here [3] of the last [6] weeks") reads as one
   sentence, the boxes sitting in the line. */
.inlinefields { line-height: 2.8; margin: 0 0 12px; }
.inlinefields input { display: inline-block; width: 4.5em; margin: 0 4px; vertical-align: middle; }
/* The Directory on a phone: a name gets its own line, with the phone and
   email under it, instead of "Aaron / Abbott" squeezed beside them. */
@media (max-width: 600px) {
  html body .dirrow, html body .dirrow.pdb-mini { flex-wrap: wrap; row-gap: 4px; }
  html body .dirrow .dirwho, html body .dirrow.pdb-mini .dirwho { flex: 1 1 calc(100% - 50px); }
  html body .dirrow .dirhow { flex-basis: 100%; align-items: flex-start; text-align: left; }
  html body .dirrow.pdb-mini .dirhow { padding-left: 48px; }
}
/* A "Saved" note that has nothing to say yet takes no room. */
.row > .sitesay:empty { display: none; }
/* Maintenance: a request's controls, folded behind one button. */
.reqmore { margin-top: 10px; }
.reqmore > summary { list-style: none; display: inline-flex; align-items: center; cursor: pointer; }
.reqmore > summary::-webkit-details-marker { display: none; }
.reqmore > summary::after { content: "▾"; margin-left: 6px; font-size: 11px; }
.reqmore[open] > summary::after { content: "▴"; }
.reqmore[open] > summary { margin-bottom: 8px; }
/* A page's tabs never sit on the description above them. */
.pagehead .sub + .seg, .pagehead .sub + nav, .pagehead + .seg, .pagehead + nav.seg { margin-top: 14px; }
/* Today's "Needs you": Open is a button like Answer beside it, not a list link. */
html body .ib-acts a.btn.ib-open { display: inline-flex; align-items: center; padding: 0 16px; min-height: 40px; height: auto; line-height: 1.2; }
/* Today: when updates are late, one line says so and links to which; the
   row of lights (a ragged three-line grid on a phone) is for the Health page. */
body:has(.todaygrid) .systems:not(.good) .systems-lights { display: none; }
body:has(.todaygrid) .systems .systems-say { text-align: left; margin-top: 0; margin-left: 0; }
/* My role, on Today: the card already says "My role" — no second box inside it. */
.tcard .myrole { background: none; border: 0; box-shadow: none; padding: 0; }
.tcard .myrole > .eyebrow { display: none; }
/* The month grid: one line per chip, ended with "…", never a word split in
   two ("Somebod / y else's"). The whole name is on hover, and in the day's list. */
html body .calgrid .chip { display: block; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; -webkit-line-clamp: unset; line-clamp: unset; }
/* Room between a page's title block and whatever comes first under it. */
html body .pagehead { margin-bottom: 16px; }
/* Rooms: each part of Find a room and Room panels stands apart from the last. */
section.panel + section.panel { margin-top: 28px; }
/* Forms list on a phone: the name has its line; its state, who and how many
   answers go underneath. */
@media (max-width: 600px) {
  .flistrow { grid-template-columns: minmax(0, 1fr) auto; grid-template-areas: "t t" "p c" "m m"; justify-items: start; }
  .flistrow > .pill { justify-self: start; }
  .flistrow > .flistcount { justify-self: end; }
}
/* "+" means add, everywhere. A fold that only opens says so with an arrow. */
.meetask > summary::before { content: "▸ "; }
.meetask[open] > summary::before { content: "▾ "; }
/* The words under a choice's name are its description, not part of the name:
   regular weight, so a list of switches or option cards can be scanned. */
label .note, label small, label .opt { font-weight: 400; }
/* In a table that scrolls sideways, headings and names keep to one line. */
.tscroll th, .tscroll td:first-child { white-space: nowrap; }
/* Cards side by side in any grid start on one line: the stack's 13px between
   cards (app.css) was dropping every card but the first in a row lower. */
[class*="grid"] > .card + .card { margin-top: 0; }
/* A table of things (Room panels, Panel health) on a phone: one card per
   row, the first cell as its title and each other cell under its heading. */
@media (max-width: 600px) {
  table.tbl-stack, table.tbl-stack tbody, table.tbl-stack tr, table.tbl-stack td { display: block; width: 100% !important; min-width: 0 !important; max-width: 100%; box-sizing: border-box; }
  table.tbl-stack thead { display: none; }
  table.tbl-stack tr { border: 1px solid var(--line-soft); border-radius: var(--radius); padding: 10px 12px; margin: 0 0 10px; background: var(--surface); }
  table.tbl-stack td { border: 0 !important; padding: 3px 0 !important; white-space: normal !important; text-align: right; overflow-wrap: anywhere; }
  table.tbl-stack td::after { content: ""; display: table; clear: both; }
  table.tbl-stack td::before { content: attr(data-label); float: left; margin-right: 12px; color: var(--muted); font-size: var(--fs-3); text-align: left; }
  table.tbl-stack td:not(:first-child) { font-size: var(--fs-4); }
  table.tbl-stack td:not(:first-child) .note { display: inline; }
  table.tbl-stack td:first-child { display: block; text-align: left; font-weight: 600; padding-bottom: 6px !important; }
  table.tbl-stack td:first-child::before { content: none; }
  table.tbl-stack td:last-child:has(button, form) { display: flex; flex-wrap: wrap; justify-content: flex-start; gap: 6px; padding-top: 8px !important; }
  table.tbl-stack td:last-child:has(button, form)::before { flex-basis: 100%; float: none; }
  table.tbl-stack td:last-child:has(button, form)::after { content: none; }
  .card:has(> table.tbl-stack) { overflow: visible !important; background: none; border: 0; box-shadow: none; padding: 0; }
  table.tbl-stack td > * { min-width: 0; }
}
summary { min-height: 24px; }
li.taskrow .t.topen { min-height: 24px; }
label:has(> input[type="checkbox"]), label:has(> input[type="radio"]) { min-height: 24px; }
.tcard > header > a { display: inline-flex; align-items: center; min-height: 24px; }
/* Set up for this date: the boxes save themselves (18 October 2026). */
.fanfoot { display: flex; align-items: center; gap: 12px; margin-top: 10px; min-height: 22px; }
.fansay.is-saving { color: var(--gold-ink); }
.fansay.is-ok { color: var(--good); }
.fansay.is-err { color: var(--crit); }
