/* The design system. Tokens come from the preliminary design (00-head.html);
   a client with other colors overrides the brand tokens (partials/theme).
   Type is in rem so the phone's text size setting and the "Aa" large text
   mode scale everything. Class reference: docs/CONVENTIONS.md. */

@font-face { font-family: "Atkinson Hyperlegible"; font-style: normal; font-weight: 400; font-display: swap; src: url("../fonts/atkinson-400.woff2") format("woff2"); }
@font-face { font-family: "Atkinson Hyperlegible"; font-style: normal; font-weight: 700; font-display: swap; src: url("../fonts/atkinson-700.woff2") format("woff2"); }
@font-face { font-family: "Atkinson Hyperlegible"; font-style: italic; font-weight: 400; font-display: swap; src: url("../fonts/atkinson-400-italic.woff2") format("woff2"); }
@font-face { font-family: "Atkinson Hyperlegible"; font-style: italic; font-weight: 700; font-display: swap; src: url("../fonts/atkinson-700-italic.woff2") format("woff2"); }

:root {
  --ink: #2B2320; --brown: #5A4B42; --brown-2: #8A7A70; --muted: #6E6057;
  --line: #E4DED3; --line-2: #EFEAE1;
  --paper: #FBFAF6; --cream: #F5F1E8; --card: #FFFFFF; --sand: #EDE8DE;
  --leaf: #81B63A; --leaf-d: #5E8F24; --forest: #00401B; --pine: #00713D; --pine-d: #005A30; --sage: #467C5E; --mint: #EAF3DD;
  --fit: #5F9E2F; --sharp: #1F8A8C; --engaged: #D4812A; --involved: #8A4F7D;
  --fit-bg: #EAF4DF; --sharp-bg: #DFF1F0; --engaged-bg: #FBEBD8; --involved-bg: #F2E4EE;
  --fit-ink: #3F6D1C; --sharp-ink: #155F61; --engaged-ink: #8A4E12; --involved-ink: #6A3560;
  --alert: #F4E7B8; --alert-ink: #5E470C; --danger: #B4432F; --danger-bg: #F8E2DC; --ok-bg: #E6F2DA; --ok-ink: #2F5A12;
  --info-bg: #E1F0F8; --info-ink: #1E5F82;
  --dp: #0A9BDB; --dp-d: #0775A8;
  /* Brand tints. A client with its own colors overrides these and pine, forest,
     leaf and mint in a <style> from partials/head.html (web.Theme). */
  --tint: #F3F8EC; --tint-2: #F7FBF2; --tint-row: #F0F6E8; --select: #CDE7A8; --mint-line: #C9DDB0;
  --mark-a: #9BCB55; --mark-b: #4E8F2A;
  --side-ink: #DCE8D8; --side-muted: #A9C7A3; --side-accent: var(--leaf); --navpill: rgba(129,182,58,.25);
  --accent: var(--pine);
  --serif: "Iowan Old Style", "Palatino Linotype", "Palatino", "Book Antiqua", Georgia, serif;
  --sans: "Atkinson Hyperlegible", "Avenir Next", "Helvetica Neue", Arial, sans-serif;
  --radius: 0.875rem; --radius-lg: 1.125rem; --radius-sm: 0.5rem;
  --tap: 3rem;            /* 48px minimum target */
  --shadow: 0 1px 2px rgba(60, 40, 20, .06);
  --shadow-lg: 0 10px 30px rgba(40, 30, 20, .14);
  /* The page's side margin: 1rem, but never more than 4.5vw, so large text
     keeps the width of a phone for words instead of margins. */
  --gutter: min(1rem, 4.5vw);
  --card-px: 1.125rem;    /* a card's side padding (narrower at large text in the app) */
  --tabbar-h: 4.75rem;
}

*, *::before, *::after { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; text-size-adjust: 100%; }
html.lt { font-size: 125%; }           /* "Aa" large text */
body { margin: 0; background: var(--paper); color: var(--ink); font-family: var(--sans); font-size: 1rem; line-height: 1.45;
  -webkit-font-smoothing: antialiased; text-rendering: optimizeLegibility; overflow-wrap: break-word; }
img, svg { max-width: 100%; }
h1, h2, h3, h4 { margin: 0; font-weight: 600; line-height: 1.2; }
h1, .h1 { font-family: var(--serif); font-size: 1.75rem; letter-spacing: -.005em; }
h2, .h2 { font-family: var(--serif); font-size: 1.375rem; }
h3, .h3 { font-family: var(--sans); font-size: 1.125rem; font-weight: 700; }
p { margin: 0 0 .75em; }
a { color: var(--pine); text-underline-offset: .15em; }
a:hover { color: var(--pine-d); }
button, input, select, textarea { font: inherit; color: inherit; }
:focus-visible { outline: 3px solid var(--dp); outline-offset: 2px; border-radius: 4px; }
::selection { background: var(--select); }
hr { border: 0; border-top: 1px solid var(--line); margin: 1rem 0; }
code, kbd { font-family: ui-monospace, "SF Mono", Menlo, monospace; font-size: .92em; }

[hidden] { display: none !important; }
.sr-only { position: absolute !important; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0; }
.skip { position: absolute; left: .5rem; top: -4rem; z-index: 100; background: var(--ink); color: #fff; padding: .75rem 1rem; border-radius: var(--radius-sm); }
.skip:focus { top: .5rem; color: #fff; }

svg.ico { width: 1.25em; height: 1.25em; fill: none; stroke: currentColor; stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; flex: none; vertical-align: -.25em; }

/* ---------- utilities ---------- */
.stack > * + * { margin-top: var(--stack, 1rem); }
.stack-sm { --stack: .5rem; } .stack-lg { --stack: 1.5rem; }
.row { display: flex; align-items: center; gap: .75rem; }
.row-top { align-items: flex-start; }
.between { justify-content: space-between; }
.wrap { flex-wrap: wrap; }
.cluster { display: flex; flex-wrap: wrap; gap: .5rem; align-items: center; }
.grow { flex: 1; min-width: 0; }
.grid-2, .grid-3, .grid-4 { display: grid; gap: .75rem; }
.grid-2 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
.grid-3 { grid-template-columns: repeat(3, minmax(0, 1fr)); }
.grid-4 { grid-template-columns: repeat(4, minmax(0, 1fr)); }
.center { text-align: center; }
.right { text-align: right; }
.muted { color: var(--muted); }
.small { font-size: .875rem; }
.lead { font-size: 1.125rem; color: var(--brown); }
.nowrap { white-space: nowrap; }
.ell { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.mt-0 { margin-top: 0 !important; } .mt-1 { margin-top: .5rem; } .mt-2 { margin-top: 1rem; } .mt-3 { margin-top: 1.5rem; }
.mb-0 { margin-bottom: 0 !important; } .mb-1 { margin-bottom: .5rem; } .mb-2 { margin-bottom: 1rem; } .mb-3 { margin-bottom: 1.5rem; }
.hidden { display: none !important; }

.eyebrow { font-family: var(--sans); font-size: .9375rem; font-weight: 700; letter-spacing: .08em; text-transform: uppercase; color: var(--muted); }

/* ---------- buttons ---------- */
.btn { display: inline-flex; align-items: center; justify-content: center; gap: .5rem; min-height: var(--tap); padding: .75rem 1.25rem;
  border-radius: var(--radius); border: 1.5px solid transparent; font-family: var(--sans); font-size: 1.0625rem; font-weight: 700; line-height: 1.15;
  text-decoration: none; cursor: pointer; background: #fff; color: var(--ink); border-color: var(--line); text-align: center; }
.btn:hover { color: var(--ink); background: var(--cream); }
.btn-primary, .btn.pri { background: var(--pine); border-color: var(--pine); color: #fff; }
.btn-primary:hover, .btn.pri:hover { background: var(--pine-d); border-color: var(--pine-d); color: #fff; }
.btn-secondary, .btn.sec { background: #fff; border-color: var(--line); color: var(--ink); }
.btn-danger { background: #fff; border-color: #E2B6AB; color: var(--danger); }
.btn-danger:hover { background: var(--danger-bg); color: var(--danger); }
.btn-ghost { background: transparent; border-color: transparent; color: var(--pine); }
.btn-ghost:hover { background: var(--mint); color: var(--pine-d); }
.btn-block { display: flex; width: 100%; }
.btn-lg { min-height: 3.5rem; font-size: 1.1875rem; }
.btn-sm { min-height: 2.25rem; padding: .375rem .75rem; font-size: .875rem; border-radius: var(--radius-sm); }
/* In the resident, staff and public shells a small button is still a 48px target with 17px words. */
.shell-app .btn-sm, .shell-public .btn-sm { min-height: var(--tap); padding: .5rem .875rem; font-size: 1.0625rem; }
.btn[disabled], .btn:disabled { opacity: .55; cursor: not-allowed; }
.btn .ico { width: 1.3em; height: 1.3em; }
.linkbtn { background: none; border: 0; padding: 0; color: var(--pine); text-decoration: underline; cursor: pointer; font: inherit; }
.inline-form { display: inline; margin: 0; }

.iconbtn { position: relative; display: inline-grid; place-items: center; width: var(--tap); height: var(--tap); border-radius: 50%; background: #fff;
  border: 1px solid var(--line); color: var(--brown); text-decoration: none; cursor: pointer; font-family: var(--serif); font-weight: 700; font-size: 1.125rem; padding: 0; }
.iconbtn:hover { background: var(--cream); color: var(--ink); }
.iconbtn .ico { width: 1.4rem; height: 1.4rem; }
.iconbtn[aria-pressed="true"] { background: var(--mint); color: var(--pine-d); border-color: var(--mint-line); }
.badge { position: absolute; top: -.2rem; right: -.2rem; min-width: 1.35rem; height: 1.35rem; border-radius: .7rem; background: var(--danger); color: #fff;
  font: 700 .8125rem/1.35rem var(--sans); text-align: center; padding: 0 .3rem; border: 2px solid var(--paper); }

/* ---------- cards, lists, chips ---------- */
.card { background: var(--card); border: 1px solid var(--line-2); border-radius: var(--radius-lg); box-shadow: var(--shadow); padding: 1rem var(--card-px); }
.card-flush { padding: 0; overflow: hidden; }
.card-title { font-family: var(--serif); font-size: 1.4375rem; font-weight: 600; line-height: 1.2; margin: .5rem 0 .4rem; }
.card-link { display: block; color: inherit; text-decoration: none; }
.card-link:hover { color: inherit; border-color: var(--line); background: #FFFEFB; }
.card + .card { margin-top: .75rem; }

.list { list-style: none; margin: 0; padding: 0; }
.list > li { border-top: 1px solid var(--line-2); }
.list > li:first-child { border-top: 0; }
.list-item { display: flex; align-items: center; gap: .75rem; min-height: 3.5rem; padding: .625rem 1rem; color: inherit; text-decoration: none; }
a.list-item:hover { background: var(--cream); color: inherit; }
.list-item .title { font-weight: 700; font-size: 1.0625rem; }
.list-item .sub { color: var(--muted); font-size: .9375rem; }
.list-item > .ico:last-child { color: var(--brown-2); }

.chip { display: inline-flex; align-items: center; gap: .4rem; font-weight: 700; font-size: .875rem; line-height: 1; padding: .4rem .65rem; border-radius: 1rem;
  white-space: nowrap; background: var(--cream); color: var(--brown); }
.chip i { width: .55rem; height: .55rem; border-radius: 50%; display: inline-block; background: currentColor; }
.c-fit { background: var(--fit-bg); color: var(--fit-ink); } .c-fit i { background: var(--fit); }
.c-sharp { background: var(--sharp-bg); color: var(--sharp-ink); } .c-sharp i { background: var(--sharp); }
.c-engaged { background: var(--engaged-bg); color: var(--engaged-ink); } .c-engaged i { background: var(--engaged); }
.c-involved { background: var(--involved-bg); color: var(--involved-ink); } .c-involved i { background: var(--involved); }
.c-staff { background: #E7EEF6; color: #2F5F86; }
.pdot { width: .55rem; height: .55rem; border-radius: 50%; display: inline-block; margin-right: .35rem; vertical-align: .08em; }
.pillar-fit { --pillar: var(--fit); } .pillar-sharp { --pillar: var(--sharp); } .pillar-engaged { --pillar: var(--engaged); } .pillar-involved { --pillar: var(--involved); }

.stat { display: inline-flex; align-items: center; gap: .3rem; font-weight: 700; font-size: .8125rem; line-height: 1; padding: .3rem .5rem; border-radius: .7rem; white-space: nowrap; }
.st-ok { background: var(--ok-bg); color: #3C6B1A; } .st-warn { background: #FBEBD2; color: #7E4C0F; } .st-off { background: #EEEAE3; color: #6B5F57; }
.st-blue { background: var(--info-bg); color: var(--info-ink); } .st-danger { background: var(--danger-bg); color: #9A3523; }

.avatar { border-radius: 50%; display: inline-grid; place-items: center; color: #fff; font-weight: 700; font-size: 1rem; flex: none;
  width: 2.75rem; height: 2.75rem; letter-spacing: .02em; overflow: hidden; }
.avatar img { width: 100%; height: 100%; object-fit: cover; }
.avatar-sm { width: 2rem; height: 2rem; font-size: .75rem; } .avatar-lg { width: 5rem; height: 5rem; font-size: 1.6rem; }
.av1 { background: #6F8F6C; } .av2 { background: #96714F; } .av3 { background: #5E7890; } .av4 { background: #8C6A87; }
.av5 { background: #9A7B35; } .av6 { background: #4F7D75; } .av7 { background: #8A5F4E; } .av8 { background: #6B6E96; }

.bar { height: .45rem; border-radius: .25rem; background: #EEEAE2; overflow: hidden; }
.bar > i { display: block; height: 100%; border-radius: .25rem; background: var(--leaf); }
.bar-fit > i { background: var(--fit); } .bar-sharp > i { background: var(--sharp); } .bar-engaged > i { background: var(--engaged); }
.bar-involved > i { background: var(--involved); } .bar-warn > i { background: var(--engaged); } .bar-danger > i { background: var(--danger); }

/* ---------- notices ---------- */
.alert { display: flex; gap: .75rem; align-items: flex-start; border-radius: var(--radius); padding: .875rem 1rem; background: var(--alert); color: var(--alert-ink); }
.alert .ico { width: 1.5rem; height: 1.5rem; margin-top: .1rem; }
.alert-title { font-weight: 700; font-size: 1.0625rem; line-height: 1.3; }
.alert-body { margin-top: .2rem; }
.alert > :not(.ico) { flex: 1 1 auto; min-width: 0; }
.alert-urgent { background: var(--danger-bg); color: #7C2A1A; border-left: 5px solid var(--danger); }
.alert-info { background: var(--info-bg); color: var(--info-ink); }
.alert-ok { background: var(--ok-bg); color: var(--ok-ink); }
a.alert { text-decoration: none; }
/* A link on a tinted notice is the brand's darker shade, so it keeps 4.5:1 on every tint (WCAG AA). */
.alert a:not(.btn), .flash a:not(.btn) { color: var(--pine-d); }
.flashes { display: grid; gap: .5rem; margin-bottom: 1rem; }
.flash { border-radius: var(--radius); padding: .75rem 1rem; font-weight: 700; background: var(--ok-bg); color: var(--ok-ink); }
.flash-warn { background: #FBEBD2; color: #6E420C; } .flash-error { background: var(--danger-bg); color: #8E2E1D; } .flash-info { background: var(--info-bg); color: var(--info-ink); }
/* "Not you? Sign out" after an invitation's sign in (partials/flash, web.Ctx.FlashSignOut): the page's own sign out
   form, on the message's line, a full tap target. High contrast keeps it through contrast.css's flash .linkbtn. */
.flash .linkbtn { color: var(--pine-d); }
.flash-out { display: inline; }
.flash-out .linkbtn { min-height: var(--tap); font-weight: 700; }

/* ---------- forms ---------- */
.field { margin-bottom: 1rem; }
.field > label, .label { display: block; font-weight: 700; margin-bottom: .4rem; }
.help { color: var(--muted); font-size: .9375rem; margin-top: .3rem; }
.error-text { color: var(--danger); font-weight: 700; margin-top: .3rem; }
.input, input[type=text], input[type=email], input[type=tel], input[type=number], input[type=search], input[type=url],
input[type=date], input[type=time], input[type=datetime-local], input[type=password], select, textarea {
  width: 100%; min-height: var(--tap); padding: .625rem .875rem; border: 1.5px solid #D8D0C4; border-radius: var(--radius-sm);
  background: #fff; font-size: 1.0625rem; line-height: 1.3; }
textarea { min-height: 7rem; resize: vertical; }
input[type=file] { max-width: 100%; }
/* A file field in the resident, staff and public shells is a 48px button
   ("Choose photo") with the chosen file's name beside it. :where() keeps
   these at no specificity, so a module's own file field (drawn as its label,
   the input itself hidden) keeps its rules. */
:where(.shell-app, .shell-public) :where(input[type=file]) { display: block; width: 100%; min-height: var(--tap); font-size: 1.0625rem; line-height: 1.3; }
:where(.shell-app, .shell-public) :where(input[type=file])::file-selector-button {
  min-height: var(--tap); margin: 0 .75rem 0 0; padding: .625rem 1.1rem; border: 1.5px solid var(--line); border-radius: var(--radius);
  background: #fff; color: var(--ink); font: inherit; font-weight: 700; cursor: pointer; }
:where(.shell-app, .shell-public) :where(input[type=file])::file-selector-button:hover { background: var(--cream); }
input:focus, select:focus, textarea:focus { outline: 3px solid rgba(10, 155, 219, .35); border-color: var(--dp); }
.input-code { font-size: 1.75rem; letter-spacing: .4em; text-align: center; font-weight: 700; font-family: var(--sans); }
.check { display: flex; align-items: center; gap: .75rem; min-height: var(--tap); cursor: pointer; }
.check input { width: 1.5rem; height: 1.5rem; accent-color: var(--pine); flex: none; }
.choices { display: grid; gap: .5rem; }
.choice { display: flex; align-items: center; gap: .875rem; min-height: 3.5rem; padding: .75rem 1rem; border: 1.5px solid var(--line); border-radius: var(--radius);
  background: #fff; cursor: pointer; }
.choice input { width: 1.4rem; height: 1.4rem; accent-color: var(--pine); flex: none; margin: 0; }
.choice:has(input:checked) { border-color: var(--pine); background: var(--tint); }
.choice .title { font-weight: 700; }
.choice .sub { color: var(--muted); font-size: .9375rem; }
/* The screen style choice on More (partials/style; SPEC 2, "Two styles"):
   Modern and High contrast one under the other, below the three text size
   buttons (partials/textsize, css/textsize.css), each a full width button at
   least 56px tall, marked like a chosen .choice when it is the page's style
   (aria-pressed: the chosen border and tint, a check in a filled circle). */
.stylechoices { display: grid; gap: .5rem; }
.style-changed { margin: .75rem 0 0; }
.stylechoice { width: 100%; display: flex; align-items: center; gap: min(.75rem, 3.2vw); min-height: 3.5rem; margin: 0;
  padding: .75rem min(1rem, 4.2vw); border: 1.5px solid var(--line); border-radius: var(--radius); background: #fff; color: var(--ink);
  font: inherit; line-height: 1.25; text-align: left; overflow-wrap: normal; cursor: pointer; }
.stylechoice:hover { background: var(--cream); }
.stylechoice[aria-pressed="true"] { border-color: var(--pine); background: var(--tint); box-shadow: inset 0 0 0 1.5px var(--pine); }
.stylechoice .title { font-weight: 700; }
.stylechoice .sub { color: var(--muted); font-size: 1.0625rem; }
.stylemark { flex: none; display: inline-flex; align-items: center; justify-content: center; width: min(1.6rem, 7.5vw); height: min(1.6rem, 7.5vw);
  border: 2px solid var(--brown-2); border-radius: 50%; background: #fff; }
.stylemark .ico { width: 70%; height: 70%; stroke-width: 3; visibility: hidden; }
.stylechoice[aria-pressed="true"] .stylemark { border-color: var(--pine); background: var(--pine); color: #fff; }
.stylechoice[aria-pressed="true"] .stylemark .ico { visibility: visible; }

.seg { display: flex; flex-wrap: wrap; background: var(--sand); border-radius: .75rem; padding: .2rem; gap: .2rem; }
.seg a, .seg button, .seg label { flex: 1; display: flex; align-items: center; justify-content: center; min-height: 2.75rem; border-radius: .6rem;
  font-weight: 700; color: var(--brown); text-decoration: none; border: 0; background: transparent; cursor: pointer; padding: .4rem .5rem; text-align: center; }
.seg a[aria-current], .seg .on, .seg label:has(input:checked) { background: #fff; color: var(--ink); box-shadow: 0 1px 3px rgba(0,0,0,.12); }
.seg input { position: absolute; opacity: 0; pointer-events: none; }
/* Resident, staff and public shells: every choice is a 48px target, and when
   the choices do not fit on one line (large text) they wrap to the next one
   whole, never cut inside a word. */
.shell-app .seg a, .shell-app .seg button, .shell-app .seg label, .shell-public .seg a, .shell-public .seg button, .shell-public .seg label {
  min-height: var(--tap); flex: 1 1 auto; min-width: min-content; overflow-wrap: normal; }

.searchbox { display: flex; align-items: center; gap: .6rem; min-height: var(--tap); border: 1.5px solid var(--line); border-radius: .75rem; background: #fff;
  padding: 0 .875rem; color: var(--muted); }
.searchbox input { border: 0; padding: 0; min-height: calc(var(--tap) - 4px); outline: 0; background: transparent; }
.searchbox:focus-within { outline: 3px solid rgba(10, 155, 219, .35); border-color: var(--dp); }
/* A button inside a search box (Find) keeps its word whole at every text size: the field gives way, never the
   button ("Find" broke over two lines at Large and Huge on the staff Reach pages, 2026-10-28). */
.shell-app .searchbox input { min-width: 0; }
.shell-app .searchbox > .btn { flex: none; }

/* ---------- tables (admin) ---------- */
table.t { width: 100%; border-collapse: collapse; font-size: .9375rem; }
table.t th { text-align: left; font-size: .75rem; font-weight: 700; letter-spacing: .06em; text-transform: uppercase; color: var(--muted);
  padding: .65rem .75rem; border-bottom: 1px solid var(--line); white-space: nowrap; }
table.t td { padding: .6rem .75rem; border-bottom: 1px solid var(--line-2); vertical-align: middle; }
table.t tr:last-child td { border-bottom: 0; }
table.t tr.selrow td { background: var(--tint-row); }
table.t tr.selrow a:not(.btn):not(.abtn) { color: var(--pine-d); }
table.t .num { text-align: right; font-variant-numeric: tabular-nums; }
/* position: relative keeps absolutely positioned bits inside the scroll box (an .sr-only label in a header
   cell), so a wide table scrolls here instead of widening the whole page. */
.table-wrap { overflow-x: auto; -webkit-overflow-scrolling: touch; position: relative; }

/* ---------- empty states ---------- */
.empty { text-align: center; color: var(--muted); padding: 2rem 1rem; }
.empty .ico { width: 2.5rem; height: 2.5rem; color: var(--brown-2); margin-bottom: .5rem; }
.empty h2, .empty h3 { color: var(--ink); margin-bottom: .35rem; }

/* ---------- the presenter's Back to me (SPEC 6.5.4) ---------- */
/* No demo banner (Eric 2026-10-22: "yea make that go away"). A persona
   session a presenter picked shows one quiet Back to me at the top of every
   page, in the page's own colors: muted words, 17px, a 48px target, nothing
   yellow and nothing worded like a warning. */
.presenter-bar .in { max-width: 72rem; margin: 0 auto; padding: 0 var(--gutter); display: flex; justify-content: flex-end; }
.shell-admin .presenter-bar .in { max-width: none; padding: 0 1rem; }
.presenter-bar form { margin: 0; }
.presenter-back { display: inline-flex; align-items: center; gap: .4rem; min-height: var(--tap); padding: 0 .25rem; font: 600 1.0625rem/1.2 var(--sans);
  color: var(--muted); background: none; border: 0; cursor: pointer; }
.presenter-back:hover { color: var(--ink); text-decoration: underline; text-underline-offset: .2em; }
.presenter-back .ico { width: 1.15em; height: 1.15em; }

/* ================= Resident and staff shells ================= */
/* Text residents read never goes below 17px (CONVENTIONS 7.8): the shared
   small classes grow in the resident, staff and public shells. */
.shell-app .eyebrow, .shell-public .eyebrow, .shell-app .help, .shell-public .help, .shell-app .small, .shell-public .small,
.shell-app .choice .sub, .shell-public .choice .sub, .shell-app .list-item .sub, .shell-public .persona .sub,
.shell-public .public-foot { font-size: 1.0625rem; }
/* Chips, status pills and the staff pill are words residents and staff read
   too (the console keeps its compact sizes). They may wrap at large sizes. */
.shell-app .chip, .shell-public .chip, .shell-app .stat, .shell-public .stat { font-size: 1.0625rem; line-height: 1.15; white-space: normal; max-width: 100%; overflow-wrap: normal; }
/* Large text (Aa, the phone's largest text sizes) never makes a page wider
   than the phone: a word that cannot fit its line breaks inside it, and flex
   and grid items may shrink below their longest word. Layouts stack at large
   sizes so ordinary words always fit (tests/e2e/a11y-sweep.mjs checks both). */
.shell-app, .shell-public { overflow-wrap: anywhere; }
.shell-app { --card-px: min(1.125rem, 4.7vw); font-size: 1.1875rem; padding-bottom: calc(var(--tabbar-h) + env(safe-area-inset-bottom)); }
/* At large text sizes the pictures beside words (avatars, tile icons, round
   buttons) stop growing at a share of the phone's width, and cards and list
   rows keep narrow side padding, so the words get the room. At the normal
   size on a phone nothing changes. :where() keeps the shell out of the
   specificity, so a module's own size for its avatar or icon still applies. */
:where(.shell-app) .avatar { width: min(2.75rem, 12vw); height: min(2.75rem, 12vw); font-size: min(1rem, 4.4vw); }
:where(.shell-app) .avatar-sm { width: min(2rem, 9vw); height: min(2rem, 9vw); font-size: min(.75rem, 3.4vw); }
:where(.shell-app) .avatar-lg { width: min(5rem, 21vw); height: min(5rem, 21vw); font-size: min(1.6rem, 7.5vw); }
:where(.shell-app) .iconbtn { width: max(48px, min(var(--tap), 13vw)); height: max(48px, min(var(--tap), 13vw)); }
.shell-app .list-item { padding-left: min(1rem, 4.2vw); padding-right: min(1rem, 4.2vw); gap: min(.75rem, 3.2vw); }
/* Large text: a list row's words keep at least 6.5rem; what follows them (a
   status pill, a button) goes to the next line rather than squeezing them. */
html.lt .shell-app .list-item, html.lt .shell-app .row { flex-wrap: wrap; row-gap: .35rem; }
html.lt .shell-app .list-item > .grow { flex: 1 1 6.5rem; }
html.lt .shell-app .list-item > .ico:last-child { margin-left: auto; }
/* Huge: a card link's decorative icon tile (Invite a family member, Your
   photos ...) goes, so its words get the row (about 60px more on a 375px
   phone) and a word like "announcements" no longer breaks. */
html.ts-huge .card-link .row > .ti[aria-hidden="true"] { display: none; }
.shell-app .choice { padding-left: min(1rem, 4.2vw); padding-right: min(1rem, 4.2vw); gap: min(.875rem, 3.5vw); }
.shell-app .choice input { width: min(1.4rem, 7vw); height: min(1.4rem, 7vw); }
.shell-app .page { max-width: 40rem; margin: 0 auto; padding: .25rem var(--gutter) 1.5rem; }
.topbar { position: sticky; top: 0; z-index: 20; background: rgba(251, 250, 246, .96); backdrop-filter: saturate(1.4) blur(8px); border-bottom: 1px solid transparent; }
.topbar .in { max-width: 40rem; margin: 0 auto; padding: .625rem var(--gutter); display: flex; align-items: center; justify-content: space-between; gap: .75rem; min-height: 4.25rem; }
.topbar .brand-logo { display: flex; align-items: center; gap: .5rem; min-width: 0; min-height: var(--tap); flex: 0 1 auto; text-decoration: none; }
/* The logo and the round buttons grow with the text but never past a share of
   the phone's width, so the top bar stays one row at every text size. */
.topbar .brand-logo img { height: min(2.1rem, 9vw); width: auto; max-width: min(11.5rem, 42vw); min-width: 0; flex: 0 1 auto; object-fit: contain; object-position: left center; display: block; }
.shell-staff .topbar .brand-logo img { max-width: min(9rem, 36vw); height: min(1.8rem, 8vw); }
/* A community without a logo shows its name in the logo's place, never a broken image. */
.topbar .brand-name { min-width: 0; font-family: var(--serif); font-weight: 700; font-size: min(1.25rem, 6vw); line-height: 1.1; color: var(--ink); overflow-wrap: anywhere; }
.topbar .iconbtn { width: max(48px, min(var(--tap), 13vw)); height: max(48px, min(var(--tap), 13vw)); font-size: min(1.125rem, 7.5vw); }
.topbar .iconbtn .ico { width: min(1.4rem, 6.5vw); height: min(1.4rem, 6.5vw); }
.topbar .actions { flex: none; }
.topbar .actions { display: flex; gap: .625rem; align-items: center; }
/* The resident top bar's Back button (partials/backbutton, CONVENTIONS 7.11):
   the first circle, at the upper left, before the logo. It never shrinks; the
   logo is what gives way when the row is tight (360 px and below, Aa, large
   text), and the bell and Aa stay at the right. */
.topbar .topback { flex: none; }
.shell-resident .topbar .actions { margin-left: auto; }
/* The bell's unread count stops growing at 17px, so at Huge it covers a corner of the bell, not half of it (a .8125rem
   count was 35px wide over a 23 to 28px bell). The same on the staff top bar (10/27: the staff bell's count still
   covered about half of it at Huge). High contrast's own count rule (contrast.css) comes later and wins. */
.shell-resident .topbar .badge, .shell-staff .topbar .badge { font-size: min(.8125rem, 17px); min-width: 1.6em; height: 1.6em; line-height: calc(1.6em - 4px); padding: 0 .3em; border-radius: .8em; top: -.4em; right: -.4em; }
/* The resident shell's hidden Skip to content link sits just above the page by its own height, not at top: -4rem:
   at the largest text sizes (55 and 62 px roots, and from 50 px at 320 px wide) it wraps taller than 4rem and its
   foot covered the top bar's Back, logo, bell and Aa. Its foot is at the top edge by layout (bottom: 100%), not by
   a transform, which would paint a fractional foot into the first pixel row. Focused, as above. Only the link
   itself, the body's first child: a survey's missed answer is also class "skip" (assessments/review). */
.shell-resident > a.skip { top: auto; bottom: 100%; }
.shell-resident > a.skip:focus { top: .5rem; bottom: auto; }
/* The STAFF badge grows with the chosen text size like every other word (17,
   21.25 and 27.2px at Normal, Large and Huge). At Large and Huge, when the
   logo at its full size and the badge no longer fit side by side (on every
   phone from 360 to 430px wide), the badge goes under the logo: the logo keeps
   its width (a 27px badge beside it once squeezed the logo to 9px words) and
   nothing reaches the bell or the account button. At Normal the two stay side
   by side, as before. */
.pill-staff { flex: none; font-weight: 700; font-size: 1.0625rem; line-height: 1.1; letter-spacing: .06em; text-transform: uppercase; background: var(--forest); color: #fff; padding: .3rem .5rem; border-radius: .45rem; }
html.lt .shell-staff .topbar .brand-logo { flex-wrap: wrap; align-content: center; row-gap: .125rem; }
/* Desktop view (View.DesktopView; README "Desktop view and Phone view"): the staff top bar's way to the admin
   console, for someone the console lets in. Its words are always beside the icon (Eric 2026-10-30: "Not sure what
   'go to app' means"), 17px and growing with the chosen size like every word, in a target as tall as the round
   buttons beside it (at least 48px, growing with the text only up to 13% of the screen's width, so at Huge on a phone
   it is 53px tall, its icon and words, not 77px, and what stays pinned over the page stays small). The top bar is a size
   container (em = its 19px text at Normal, so the widths follow the chosen size). Where the logo at its full
   size, the Staff badge, the bell, the account button and Desktop view fit in one row (a tablet or a computer), it
   sits last, after the account button. Narrower (every phone, at every size: at 320px the badge, the words, the bell
   and the account button alone are wider than the bar), the row above stays exactly as it was and Desktop view takes
   a row of its own under it, at the right, so neither the logo nor the words are squeezed. Either way it is where it
   comes in the page (last in the bar), so a screen reader and the Tab key reach it in the order it shows. */
.shell-staff .topbar { container: staffbar / inline-size; }
.topbar .deskview { display: inline-flex; align-items: center; gap: .35em; flex: none; min-height: max(48px, min(var(--tap), 13vw)); padding: .3rem .75rem; border-radius: var(--radius);
  border: 1.5px solid var(--line); background: #fff; color: var(--ink); font-family: var(--sans); font-size: 1.0625rem; font-weight: 700; line-height: 1.15;
  text-decoration: none; white-space: nowrap; }
.topbar .deskview:hover { background: var(--cream); color: var(--ink); }
.topbar .deskview .ico { width: 1.3em; height: 1.3em; color: var(--brown); }
@container staffbar (max-width: 32em) {
  .shell-staff .topbar .in:has(.deskview) { display: grid; grid-template-columns: minmax(0, 1fr) auto auto; grid-template-areas: "brand . ." "desk desk desk";
    column-gap: .625rem; row-gap: .375rem; }
  .shell-staff .topbar .in:has(.deskview) .actions { display: contents; }
  .shell-staff .topbar .in:has(.deskview) .brand-logo { grid-area: brand; justify-self: start; max-width: 100%; margin-right: .125rem; }
  .shell-staff .topbar .deskview { grid-area: desk; justify-self: end; }
}
/* A pointer from a staff page into Desktop view (partials/desktoplink, README "Desktop view and Phone view", item 7):
   a full width secondary button with the top bar's screen icon, and under it the line saying what Desktop view asks
   first. Its own block, so it never sits in a row of other buttons. */
.desklink { margin: .75rem 0; }
.desklink .btn .ico { color: var(--brown); }
.desklink .desklink-note { margin: .35rem 0 0; }
.backlink { display: inline-flex; align-items: center; gap: .25rem; min-height: var(--tap); font-weight: 700; color: var(--pine); text-decoration: none; margin-left: -.35rem; }
.backlink .ico { width: 1.6rem; height: 1.6rem; }
/* A link on a line of its own, outside a sentence (Cancel under a form, See every scheduled tour, Edit beside a
   heading, a phone number in a list of facts): a 48px target in the resident, staff and public shells, its words and
   colors as they were (CONVENTIONS 17, older eyes and hands, rule 2; the accessibility sweeps, 2026-10-28). */
.shell-app .tap-link, .shell-public .tap-link { display: inline-flex; align-items: center; gap: .35rem; min-height: var(--tap); }
.page-title { font-family: var(--serif); font-size: 2rem; font-weight: 600; line-height: 1.1; margin: .25rem 0 1rem; }

/* The tab bar's labels are 17px and grow with the text like every other word.
   It is a size container (em below = the label size): when four labels no
   longer fit side by side (a small phone, Aa, the largest text sizes) it
   becomes two rows of two, with the icon beside the word while there is room
   and the word alone after that. A row is at least 48px tall and the two rows
   fill --tabbar-h, which grows to fit them. */
.tabbar { position: fixed; left: 0; right: 0; bottom: 0; z-index: 30; background: #fff; border-top: 1px solid var(--line);
  padding-bottom: env(safe-area-inset-bottom); container-type: inline-size; font-size: 1.0625rem; }
.tabbar ul { list-style: none; margin: 0 auto; padding: .375rem 0 0; max-width: 40rem; display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); }
.tabbar li { min-width: 0; }
/* The staff tab bar shows only the tabs the person can open (View.StaffTabBar, data-tabs = how many): fewer than
   four share the row. :where() keeps these as specific as the two rows of two below, which still win when the
   labels no longer fit. */
.shell-staff .tabbar ul:where([data-tabs="3"]) { grid-template-columns: repeat(3, minmax(0, 1fr)); }
.shell-staff .tabbar ul:where([data-tabs="2"]) { grid-template-columns: repeat(2, minmax(0, 1fr)); }
.shell-staff .tabbar ul:where([data-tabs="1"]) { grid-template-columns: minmax(0, 1fr); }
.tabbar a { display: flex; flex-direction: column; align-items: center; justify-content: center; gap: .2rem; min-height: 4.25rem; color: #6F635B;
  text-decoration: none; font-weight: 700; font-size: 1em; line-height: 1.1; border-radius: .75rem; padding: .25rem .1rem .4rem; text-align: center;
  overflow-wrap: normal; }
.tabbar a .ico { width: 1.85rem; height: 1.85rem; stroke-width: 1.9; }
/* The unread count after a tab's word (the prospect tab bar's Messages), in the line with it. Its line is the
   pill's height less the 2px border above and below (as the bell's count does), so the number sits in the middle
   of the pill, not 2px low. */
.tabbar .badge { position: static; display: inline-block; margin-left: .3em; vertical-align: .1em; line-height: calc(1.35rem - 4px); }
html.lt { --tabbar-h: max(4.75rem, 104px); }
@media (max-width: 369px) { :root { --tabbar-h: max(4.75rem, 104px); } }
@container (max-width: 18em) {
  .shell-resident .tabbar ul { grid-template-columns: repeat(2, minmax(0, 1fr)); padding: 0 .25rem; }
  .shell-resident .tabbar a { flex-direction: row; gap: .3em; min-height: max(48px, calc((var(--tabbar-h) - 2px) / 2)); padding: .1rem .25rem; }
  .shell-resident .tabbar a .ico { width: 1.2em; height: 1.2em; }
}
@container (max-width: 21.5em) {
  .shell-staff .tabbar ul { grid-template-columns: repeat(2, minmax(0, 1fr)); padding: 0 .25rem; }
  .shell-staff .tabbar a { flex-direction: row; gap: .3em; min-height: max(48px, calc((var(--tabbar-h) - 2px) / 2)); padding: .1rem .25rem; }
  .shell-staff .tabbar a .ico { width: 1.2em; height: 1.2em; }
}
@container (max-width: 14.5em) {
  .shell-app .tabbar a .ico { display: none; }
}
.tabbar a[aria-current="page"] { color: var(--pine); }
.tabbar a[aria-current="page"] .ico { stroke-width: 2.3; }
.tabbar a:hover { color: var(--ink); background: var(--cream); }

/* Resident Home (design page 3) */
.greeting { padding: .25rem 0 1rem; }
.greeting h1 { font-size: 1.75rem; }
.greeting .when { display: flex; align-items: center; flex-wrap: wrap; gap: .4rem .5rem; margin-top: .5rem; font-size: 1.0625rem; color: var(--brown); }
.greeting .when .ico { width: 1.5rem; height: 1.5rem; }
.home-slot > * + * { margin-top: .75rem; }
.home-slot:not(:empty) { margin-bottom: .875rem; }
.upnext > .row { flex-wrap: wrap; row-gap: .4rem; }
.upnext .meta { display: flex; flex-wrap: wrap; gap: .4rem 1rem; color: var(--brown); font-size: 1.0625rem; }
.upnext .meta span { display: inline-flex; align-items: center; gap: .35rem; }
.upnext .going { display: flex; align-items: center; gap: .4rem; margin-top: .75rem; font-weight: 700; color: var(--pine); }
.tiles { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: .625rem; margin: 0; padding: 0; list-style: none; font-size: 1.0625rem; }
/* Home's tiles: three across at the normal text size, two with Aa, one at the
   very largest sizes (a column is never narrower than 5.6 labels' em, which
   holds "Documents"). */
.shell-app .tiles { grid-template-columns: repeat(auto-fill, minmax(min(100%, 5.6em), 1fr)); }
.tile { display: flex; flex-direction: column; align-items: center; justify-content: center; gap: .5rem; min-height: 6.25rem; padding: .75rem .25rem;
  background: #fff; border: 1px solid var(--line-2); border-radius: 1rem; box-shadow: var(--shadow); color: var(--ink); text-decoration: none;
  font-weight: 700; font-size: 1em; text-align: center; line-height: 1.15; overflow-wrap: normal; }
.tile:hover { color: var(--ink); border-color: var(--line); background: #FFFEFB; }
.ti { width: 2.75rem; height: 2.75rem; border-radius: .8rem; display: grid; place-items: center; flex: none; }
.ti .ico { width: 1.5rem; height: 1.5rem; }
/* In the app the tile icon stops growing at 12vw (the avatar caps above say why). */
:where(.shell-app) .ti { width: min(2.75rem, 12vw); height: min(2.75rem, 12vw); }
:where(.shell-app) .ti .ico { width: min(1.5rem, 6.5vw); height: min(1.5rem, 6.5vw); }
.tone-mint { background: var(--mint); color: var(--pine); } .tone-blue { background: #E6EEF4; color: #2F5F86; }
.tone-amber { background: #FBEBD8; color: #8A5112; } .tone-clay { background: #F1E7E1; color: #7A4B35; }
.tone-violet { background: #EDEAF4; color: #5A4D8A; } .tone-rose { background: #F4E4EC; color: #8A3F63; }
.tone-teal { background: var(--sharp-bg); color: var(--sharp-ink); } .tone-gold { background: #F6EED3; color: #7A5E12; }
.frontdesk { margin-top: .875rem; }

/* Staff Home (design page 6) */
.commchip { display: inline-flex; align-items: center; gap: .35rem; font-weight: 700; background: #fff; border: 1.5px solid var(--line); border-radius: 1.2rem;
  padding: .45rem .75rem; min-height: 2.75rem; }
.commchip select { border: 0; min-height: auto; padding: 0 1.25rem 0 0; font-weight: 700; background: transparent; width: auto; font-size: 1.0625rem; }
/* A community picker drawn as a chip: the select fills the chip and is the 48px target. */
.shell-app .commchip:has(> select) { padding-top: 0; padding-bottom: 0; }
.shell-app .commchip > select { min-height: var(--tap); }
/* The staff community switcher: the whole chip is the select's tap area. */
.commswitch { display: inline-flex; align-items: center; gap: .5rem; flex-wrap: wrap; margin: 0; }
.commchip-select { position: relative; padding: 0; min-height: var(--tap); }
.commchip-select select { -webkit-appearance: none; appearance: none; min-height: var(--tap); padding: 0 2.25rem 0 2.6rem; border-radius: 1.2rem;
  font-size: 1.0625rem; cursor: pointer; }
.commchip-select .ico { position: absolute; top: 50%; transform: translateY(-50%); pointer-events: none; color: var(--brown); width: 1.15rem; height: 1.15rem; }
.commchip-select .ico:first-child { left: .85rem; }
.commchip-select .ico:last-child { right: .8rem; }
/* At Huge a long community name fits the phone: the switcher, its chip and the select shrink to the row and the name
   ends in an ellipsis, so Staff Home never scrolls sideways (the office: "Hollyhock Green" made the page 409px on a
   375 phone; text-sizes.mjs, office-home). */
.commswitch { max-width: 100%; }
.commchip-select, .commchip-select select { max-width: 100%; min-width: 0; }
.commchip-select select { text-overflow: ellipsis; }
.attention { border-left: 5px solid var(--danger); }
.attention .eyebrow { color: var(--danger); }
.qlinks { display: flex; flex-wrap: wrap; gap: .5rem; }
.qlink { display: inline-flex; align-items: center; gap: .4rem; min-height: var(--tap); padding: .5rem .875rem; background: #fff; border: 1px solid var(--line);
  border-radius: .75rem; font-weight: 700; color: var(--ink); text-decoration: none; }
.qlink:hover { background: var(--cream); color: var(--ink); }
.qlink .ico { width: 1rem; height: 1rem; color: var(--brown-2); }
/* In the shells a quick link's side padding, gaps and icons stop growing at a share of the phone's width, as the
   avatar and tile icon caps above do (CONVENTIONS 17, older eyes and hands, rules 4 and 5), so at Large and Huge
   its words get the row: in rem they took 118 of the 341px on a 375px phone at Huge, and Home's "News: N new
   announcements" broke "announcements" mid word (10/31, text-sizes.mjs home). At the normal size on a phone 360px
   or wider nothing changes. :where() keeps the shell out of the specificity, as above. */
:where(.shell-app) .qlink { padding-left: min(.875rem, 3.9vw); padding-right: min(.875rem, 3.9vw); gap: min(.4rem, 1.8vw); }
:where(.shell-app) .qlink .ico { width: min(1rem, 4.45vw); height: min(1rem, 4.45vw); }
/* Someone else does these here (web.NavAsk, usability R17.6 and R17.12): the job, then who to ask. A mark and words,
   no link: the job is not the person's to open. */
.asks-list { list-style: none; margin: 0; padding: 0; display: grid; gap: .75rem; }
.ask { display: flex; gap: .75rem; align-items: flex-start; }
.ask-ic { display: inline-grid; place-items: center; width: 2.25rem; height: 2.25rem; border-radius: .75rem; background: var(--cream); color: var(--brown); flex: none; }
.ask-ic .ico { width: 1.15rem; height: 1.15rem; }
.ask-txt { min-width: 0; overflow-wrap: anywhere; }
.ask-t { display: block; font-weight: 700; color: var(--ink); }
.ask-who { display: block; color: var(--brown); }
/* What the person does themselves (NavItem.Part, usability R30.2), and a staff tool choice that keeps the job from them
   with who can turn it on (web.TurnOn, R29.2). */
.ask-mine { display: block; color: var(--ink); }
.ask-on { display: block; margin-top: .25rem; }
.turnon { display: inline-flex; gap: .4rem; align-items: flex-start; color: var(--brown); }
.turnon .ico { width: 1rem; height: 1rem; flex: none; margin-top: .2rem; }
.turnons-list { list-style: none; margin: 0; padding: 0; display: grid; gap: .75rem; }
.turnons-list .ask-t { margin-bottom: .1rem; }
.callb { display: inline-grid; place-items: center; width: var(--tap); height: var(--tap); border-radius: 50%; background: var(--mint); color: var(--pine); flex: none; }
:where(.shell-app) .callb { width: max(48px, min(var(--tap), 13vw)); height: max(48px, min(var(--tap), 13vw)); }

/* More tab */
.section { margin-top: 1.5rem; }
.section > h2 { font-size: 1.375rem; margin-bottom: .625rem; }
.steps { margin: .25rem 0 0; padding-left: 1.4rem; }
.steps li { margin: .35rem 0; }
.me-card { display: flex; gap: .875rem; align-items: center; }

/* ================= Public and sign in ================= */
.shell-public { min-height: 100vh; min-height: 100dvh; display: flex; flex-direction: column; font-size: 1.125rem; }
.public-top { padding: 1.25rem var(--gutter) .5rem; }
.public-top .in { max-width: 30rem; margin: 0 auto; display: flex; align-items: center; justify-content: space-between; gap: .75rem 1rem; flex-wrap: wrap; }
.public-main { flex: 1; padding: .5rem var(--gutter) 2rem; }
.public-main .in { max-width: 30rem; margin: 0 auto; }
.public-wide .public-main .in, .public-wide .public-top .in { max-width: 56rem; }
.public-foot { padding: 1.25rem var(--gutter) 2rem; color: var(--muted); font-size: .9375rem; text-align: center; text-wrap: balance; }
.public-foot-app, .public-foot-co { display: block; max-width: 30rem; margin: 0 auto; }
.public-foot-co { margin-top: .2rem; font-weight: 700; }
.lm-brand { display: inline-flex; align-items: center; gap: .6rem; text-decoration: none; color: var(--ink); min-width: 0; flex: 1 1 auto; min-height: var(--tap); }
.lm-mark { width: 2.5rem; height: 2.5rem; border-radius: .75rem; background: linear-gradient(150deg, var(--mark-a), var(--mark-b)); display: grid; place-items: center; color: #fff; flex: none; }
.lm-mark .ico { width: 1.6rem; height: 1.6rem; }
.lm-name { font-family: var(--serif); font-size: 1.5rem; font-weight: 600; letter-spacing: .005em; min-width: 0; overflow-wrap: anywhere; line-height: 1.15; }
.lm-by { display: block; font-family: var(--sans); font-size: 1.0625rem; font-weight: 700; letter-spacing: .02em; color: var(--pine); }
.signin-card { padding: 1.5rem 1.25rem; }
.signin-card h1 { font-size: 1.875rem; margin-bottom: .4rem; }
.qr { display: block; width: 15rem; max-width: 100%; height: auto; margin: 0 auto; image-rendering: pixelated; border: 1px solid var(--line); border-radius: .5rem; background: #fff; }
.secret { font-family: ui-monospace, "SF Mono", Menlo, monospace; font-size: 1.05rem; letter-spacing: .05em; background: var(--cream); padding: .5rem .75rem; border-radius: .5rem; word-break: break-all; }

/* ================= Admin console (design page 7) ================= */
.shell-admin { font-size: .9375rem; background: #F7F5F0; }
.admin-wrap { display: grid; grid-template-columns: 15rem minmax(0, 1fr); min-height: 100vh; min-height: 100dvh; }
.side { background: var(--forest); color: var(--side-ink); padding: 1rem .75rem 1.5rem; display: flex; flex-direction: column; gap: .125rem; }
.side-head { display: flex; align-items: flex-start; justify-content: space-between; gap: .5rem; }
.side .brand { display: flex; align-items: center; gap: .6rem; padding: .25rem .4rem 1rem; color: #fff; text-decoration: none; min-width: 0; }
.side .brand .lm-mark { width: 2rem; height: 2rem; border-radius: .6rem; }
.side .brand .lm-mark .ico { width: 1.3rem; height: 1.3rem; }
.side .brand .lm { font-family: var(--serif); font-size: 1.1875rem; font-weight: 600; line-height: 1; }
.side .brand small { display: block; font-size: .75rem; font-weight: 700; letter-spacing: .14em; text-transform: uppercase; color: var(--side-accent); margin-top: .3rem; }
.viewing { margin: 0 0 .75rem; padding: .5rem .625rem; border-radius: .6rem; background: rgba(255,255,255,.1); border: 1px solid rgba(255,255,255,.16); }
.viewing label, .viewing .vlabel { display: block; font-size: .75rem; font-weight: 700; letter-spacing: .1em; text-transform: uppercase; color: var(--side-ink); margin-bottom: .2rem; }
.viewing .vrow { display: flex; align-items: center; gap: .4rem; }
.viewing .vrow .ico { width: 1rem; height: 1rem; color: var(--side-muted); }
.viewing select { background: transparent; color: #fff; border: 0; padding: 0; min-height: 1.75rem; font-weight: 700; font-size: 1rem; width: 100%; }
.viewing select option { color: var(--ink); }
.viewing .static { color: #fff; font-weight: 700; }
.viewing .vgo { margin-top: .4rem; min-height: 2rem; background: rgba(255,255,255,.14); border-color: rgba(255,255,255,.3); color: #fff; }
/* "Show <community>" once a community is chosen without a pointer (usability R32.7.4): the whole width, its words wrap. */
.viewing .vgo:not([hidden]) { display: block; width: 100%; white-space: normal; text-align: center; }
.nav { display: flex; align-items: center; gap: .625rem; min-height: 2.5rem; padding: .45rem .65rem; border-radius: .5rem; color: #D2E1CE; text-decoration: none; font-weight: 500; }
.nav .ico { width: 1.1rem; height: 1.1rem; stroke-width: 1.9; opacity: .9; }
.nav:hover { background: rgba(255,255,255,.08); color: #fff; }
.nav[aria-current="page"] { background: rgba(255,255,255,.14); color: #fff; font-weight: 700; }
.nav .navpill { margin-left: auto; font-size: .6875rem; font-weight: 700; letter-spacing: .06em; padding: .2rem .35rem; border-radius: .25rem; background: var(--navpill); color: var(--select); }
/* The sidebar's small labels use the brand's sidebar tokens (AA on the dark
   sidebar for Cascade Group and the show client), never a fixed green. */
.navlbl { font-size: .75rem; font-weight: 700; letter-spacing: .14em; text-transform: uppercase; color: var(--side-muted); padding: .75rem .65rem .35rem; }
.navsep { height: 1px; background: rgba(255,255,255,.12); margin: .5rem .4rem; }
.side .logged { margin-top: auto; padding: 1rem .65rem 0; font-size: .8125rem; color: var(--side-muted); display: flex; gap: .4rem; align-items: center; }
.side .logged .ico { width: .95rem; height: .95rem; }
.amain { min-width: 0; display: flex; flex-direction: column; }
/* The phone drawer's controls (Menu, the brand in the top bar, Close, the shade): shown under 900px only. */
.amenu, .abrand, .aclose, .aback { display: none; }
.atop { position: sticky; top: 0; z-index: 15; min-height: 3.75rem; background: #fff; border-bottom: 1px solid var(--line); display: flex; align-items: center; gap: .75rem; padding: .5rem 1.25rem; }
.asearch { flex: 1; max-width: 26rem; display: flex; align-items: center; gap: .5rem; background: #F4F1EB; border-radius: .5rem; padding: 0 .65rem; color: var(--muted); min-height: 2.5rem; }
.asearch input { border: 0; background: transparent; min-height: 2.4rem; padding: 0; font-size: 1rem; outline: 0; }
.asearch:focus-within { outline: 3px solid rgba(10, 155, 219, .35); }
.abtn { display: inline-flex; align-items: center; gap: .4rem; min-height: 2.5rem; padding: .4rem .875rem; border-radius: .5rem; font-weight: 700; font-size: .9375rem;
  text-decoration: none; border: 1px solid var(--line); background: #fff; color: var(--ink); cursor: pointer; white-space: nowrap; }
.abtn:hover { background: var(--cream); color: var(--ink); }
.abtn.pri, .abtn-primary { background: var(--pine); border-color: var(--pine); color: #fff; }
.abtn.pri:hover, .abtn-primary:hover { background: var(--pine-d); color: #fff; }
.abtn .ico { width: 1rem; height: 1rem; }
.menu { position: relative; }
.menu > summary { list-style: none; }
.menu > summary::-webkit-details-marker { display: none; }
.menu-list { position: absolute; right: 0; top: calc(100% + .35rem); z-index: 40; min-width: 14rem; background: #fff; border: 1px solid var(--line); border-radius: .75rem;
  box-shadow: var(--shadow-lg); padding: .35rem; list-style: none; margin: 0; }
.menu-list a, .menu-list button { display: flex; align-items: center; gap: .6rem; width: 100%; min-height: 2.5rem; padding: .45rem .65rem; border-radius: .5rem; color: var(--ink);
  text-decoration: none; background: none; border: 0; cursor: pointer; font-size: .9375rem; text-align: left; }
.menu-list a:hover, .menu-list button:hover { background: var(--cream); }
.menu-list .ico { width: 1.05rem; height: 1.05rem; color: var(--brown); }
.me { display: flex; align-items: center; gap: .5rem; font-weight: 700; font-size: .875rem; line-height: 1.2; text-align: left; }
.me small { display: block; font-weight: 500; color: var(--muted); font-size: .8125rem; }
.me summary { display: flex; align-items: center; gap: .5rem; cursor: pointer; border-radius: .5rem; padding: .2rem .35rem; }
.abody { padding: 1.25rem; max-width: 84rem; width: 100%; }
.abody.wide { max-width: none; }
.ahead { display: flex; justify-content: space-between; align-items: flex-end; gap: 1rem; flex-wrap: wrap; margin-bottom: 1rem; }
.ahead h1 { font-size: 1.625rem; }
.ahead .sub { color: var(--muted); margin-top: .25rem; }
.period { display: flex; gap: .5rem; align-items: center; margin: 0; }
.shell-admin .period select { width: auto; min-height: 2.5rem; }
.atop .iconbtn { width: 2.5rem; height: 2.5rem; }
/* Phone view (View.PhoneView; README "Desktop view and Phone view"): the console top bar's way to the staff side of
   the app, its words always beside the icon, before the bell. On a phone it is placed in the grid below. In the page
   it stays before the bell, the order it shows in on a computer, the console's main size; under 560px a screen
   reader reaches it before the second row it shows under, as it reaches the account menu (first row there) last. */
.atop .aphone { flex: none; }
.atop .aphone .ico { color: var(--brown); }
.afoot { margin-top: 2rem; padding: 1rem 1.25rem 1.5rem; color: var(--muted); font-size: .875rem; display: flex; gap: .4rem; align-items: center; border-top: 1px solid var(--line); }
.afoot .ico { width: 1rem; height: 1rem; }
.panel { background: #fff; border: 1px solid var(--line); border-radius: .75rem; }
.panel-pad { padding: 1rem; }
.phead { display: flex; align-items: center; justify-content: space-between; gap: .75rem; padding: .75rem 1rem; border-bottom: 1px solid var(--line-2); font-weight: 700; }
.phead a { font-size: .875rem; font-weight: 700; text-decoration: none; }
.kpi { padding: 1rem 1.1rem; }
.kpi .lbl { font-size: .72rem; font-weight: 700; letter-spacing: .08em; text-transform: uppercase; color: var(--muted); }
.kpi .val { font-family: var(--serif); font-size: 2rem; font-weight: 600; line-height: 1; margin: .6rem 0 .45rem; }
.kpi .sub { font-size: .875rem; color: var(--brown); margin-top: .45rem; }
.kpi .up { color: var(--pine); font-weight: 700; }
.kpi .down { color: var(--danger); font-weight: 700; }
.metrics { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: .75rem; margin-bottom: 1rem; }
.dash-row { display: grid; grid-template-columns: 1.45fr 1fr; gap: .75rem; margin-bottom: 1rem; }
.dash-panels { display: grid; grid-template-columns: 1fr 1fr; gap: .75rem; }
.nlist { list-style: none; margin: 0; padding: 0; }
.nlist li { display: flex; gap: .65rem; align-items: center; padding: .65rem 1rem; border-top: 1px solid var(--line-2); }
.nlist li:first-child { border-top: 0; }
.nlist .ic { width: 1.75rem; height: 1.75rem; border-radius: .5rem; display: grid; place-items: center; flex: none; }
.nlist .ic .ico { width: 1rem; height: 1rem; }
.nlist a { font-weight: 700; white-space: nowrap; text-decoration: none; }
.dash-more { border-top: 1px solid var(--line-2); }
.dash-more > summary { cursor: pointer; padding: .65rem 1rem; font-weight: 700; color: var(--pine); min-height: 2.75rem; display: flex; align-items: center; }
.dash-more > summary:hover { text-decoration: underline; }
.dash-more[open] > summary { border-bottom: 1px solid var(--line-2); }
.tone-warn { background: #FBEBD2; color: #8A5412; } .tone-info { background: var(--info-bg); color: #1E6A91; } .tone-neutral { background: #EEEAE3; color: #6B5F57; }
.tone-ok { background: var(--ok-bg); color: #3C6B1A; } .tone-danger { background: var(--danger-bg); color: #9A3523; }
.erow { display: grid; grid-template-columns: 1fr 7rem; gap: .75rem; align-items: center; padding: .65rem 1rem; border-top: 1px solid var(--line-2); }
.erow:first-child { border-top: 0; }
.erow .nm { font-weight: 700; }
.erow .sb { font-size: .8125rem; color: var(--muted); margin-top: .15rem; }
.erow .cap { font-size: .8125rem; font-weight: 700; color: var(--brown); text-align: right; margin-bottom: .3rem; }
.admin-tabs { display: flex; gap: .25rem; border-bottom: 1px solid var(--line); margin-bottom: 1rem; overflow-x: auto; position: relative; }
.admin-tabs a { padding: .65rem .875rem; text-decoration: none; color: var(--brown); font-weight: 700; border-bottom: 3px solid transparent; white-space: nowrap; }
.admin-tabs a[aria-current] { color: var(--ink); border-bottom-color: var(--pine); }
.toolbar { display: flex; flex-wrap: wrap; gap: .5rem; align-items: center; margin-bottom: .75rem; }
.toolbar .grow { flex: 1; }
.shell-admin .field > label { font-size: .72rem; letter-spacing: .06em; text-transform: uppercase; color: var(--muted); }
.shell-admin input[type=text], .shell-admin input[type=email], .shell-admin input[type=tel], .shell-admin input[type=number], .shell-admin input[type=search],
.shell-admin input[type=url], .shell-admin input[type=date], .shell-admin input[type=time], .shell-admin input[type=datetime-local], .shell-admin select, .shell-admin textarea {
  min-height: 2.5rem; font-size: 1rem; padding: .45rem .7rem; }
.shell-admin .btn { min-height: 2.5rem; font-size: .9375rem; padding: .45rem 1rem; }
.idle-warn { position: fixed; left: 50%; bottom: 1.25rem; transform: translateX(-50%); z-index: 60; background: var(--ink); color: #fff; border-radius: .75rem;
  padding: .75rem 1rem; display: flex; gap: .75rem; align-items: center; box-shadow: var(--shadow-lg); max-width: calc(100% - 2rem); }
.idle-warn .btn { min-height: 2.25rem; }

/* ================= Print layouts ================= */
.shell-print { background: #fff; color: #000; font-size: 12pt; }
.print-page { padding: .4in; }
.print-head { display: flex; align-items: center; justify-content: space-between; gap: 1rem; border-bottom: 2px solid var(--ink); padding-bottom: .5rem; margin-bottom: .75rem; }
.print-head img { height: .55in; width: auto; }
.print-head h1 { font-size: 22pt; }
.print-foot { margin-top: .5rem; font-size: 9pt; color: #555; display: flex; justify-content: space-between; }
.print-actions { position: sticky; top: 0; background: var(--cream); padding: .5rem 1rem; display: flex; gap: .5rem; align-items: center; border-bottom: 1px solid var(--line); }
@media print {
  .no-print, .print-actions, .presenter-bar, .tabbar, .topbar, .side, .atop, .afoot, .idle-warn { display: none !important; }
  body { background: #fff !important; padding: 0 !important; }
  .shell-app .page, .abody { max-width: none; padding: 0; }
  .admin-wrap { display: block; }
  a { color: inherit; text-decoration: none; }
  .card, .panel { box-shadow: none; break-inside: avoid; }
  * { -webkit-print-color-adjust: exact; print-color-adjust: exact; }
}
@page landscape { size: letter landscape; margin: .4in; }
@page portrait { size: letter portrait; margin: .5in; }
.print-landscape { page: landscape; }
.print-portrait { page: portrait; }

/* ================= Lobby screens (1920x1080) ================= */
.shell-screen { width: 1920px; height: 1080px; overflow: hidden; background: var(--forest); color: #fff; font-size: 2rem; }
.screen { width: 1920px; height: 1080px; display: grid; grid-template-columns: 1.4fr 1fr; gap: 2rem; padding: 3rem 3.5rem; }
.screen h1 { font-size: 3.5rem; color: #fff; }
.screen .panel { background: rgba(255,255,255,.08); border-color: rgba(255,255,255,.16); color: #fff; border-radius: 1.25rem; padding: 1.5rem 1.75rem; }

/* ================= Device pages (/tv: in room TV, kiosks) ================= */
/* A 10 foot layout for interactive device pages: big type, big focus ring,
   no fixed size and no automatic refresh (layout "device"). Passive lobby
   screens use the 1920x1080 "screen" layout above. */
.shell-device { min-height: 100vh; min-height: 100dvh; background: var(--paper); font-size: clamp(1.25rem, .5rem + 1.5vw, 2.25rem); }
.device-main { padding: 2rem 3rem; }
.shell-device :focus-visible { outline-width: 5px; outline-offset: 4px; }

/* ================= Responsive ================= */
@media (max-width: 1100px) {
  .metrics { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .dash-row, .dash-panels { grid-template-columns: minmax(0, 1fr); }
}
/* Admin console under 900px (phones and small tablets at the booth): the sidebar is a drawer behind the top
   bar's Menu button, the top bar is two rows (Menu, brand, bell, account; then search and New), and nothing on
   the page is wider than the screen. Tables scroll inside .table-wrap (or their own box), forms and two column
   layouts stack, and module pages keep to minmax(0, 1fr) columns. admin.js opens and closes the drawer
   (body.nav-open); without scripts the Menu link opens it through :target. */
@media (max-width: 900px) {
  .admin-wrap { display: block; min-height: 0; }
  .side { position: fixed; top: 0; bottom: 0; left: 0; z-index: 70; width: min(20rem, 86vw); overflow-y: auto; overscroll-behavior: contain;
    padding: .75rem .75rem 2rem; padding-top: max(.75rem, env(safe-area-inset-top)); transform: translateX(-102%); visibility: hidden;
    box-shadow: var(--shadow-lg); }
  /* The drawer slides only when Menu or Close moves it (admin.js adds nav-closing while it slides shut). A window
     narrowing past 900px puts it away at once: it slid out over the page's left edge (usability R25.5). */
  .nav-open .side, body:not(.drawer-js) .side:target { transform: none; visibility: visible; transition: transform .2s ease; }
  .nav-closing .side { transition: transform .2s ease, visibility 0s linear .2s; }
  .aback { position: fixed; inset: 0; z-index: 65; background: rgba(20, 16, 12, .45); }
  .nav-open .aback, body:not(.drawer-js) .side:target + .aback { display: block; }
  .nav-open { overflow: hidden; }
  .side .brand { padding: .25rem .4rem .75rem; }
  .aclose { display: inline-flex; align-items: center; gap: .35rem; flex: none; min-height: 2.75rem; padding: .35rem .75rem; border-radius: .6rem;
    color: #fff; text-decoration: none; font-weight: 700; background: rgba(255,255,255,.12); border: 1px solid rgba(255,255,255,.25); }
  .aclose:hover { color: #fff; background: rgba(255,255,255,.2); }
  .aclose .ico { width: 1.1rem; height: 1.1rem; }
  .side .nav { min-height: 2.75rem; }
  .viewing select { min-height: 2.5rem; }

  .atop { position: static; display: grid; grid-template-columns: auto minmax(0, 1fr) auto auto; grid-template-areas: "menu brand brand me" "search search bell new";
    align-items: center; gap: .5rem; padding: .5rem 1rem; padding-top: max(.5rem, env(safe-area-inset-top)); }
  .atop:not(:has(.anew)) { grid-template-areas: "menu brand brand me" "search search search bell"; }
  /* Phone view goes in the first row, between the brand and the account menu (a tablet); under 560px it takes a
     row of its own at the right (below). */
  .atop:has(.aphone) { grid-template-areas: "menu brand phone me" "search search bell new"; }
  .atop:has(.aphone):not(:has(.anew)) { grid-template-areas: "menu brand phone me" "search search search bell"; }
  .atop > .aphone { grid-area: phone; justify-self: end; }
  .atop:has(.aphone) > .iconbtn { justify-self: end; } /* the bell, under Phone view's wider column, beside New */
  .atop > .grow { display: none; }
  .amenu { grid-area: menu; display: inline-flex; align-items: center; gap: .4rem; min-height: 2.75rem; padding: .35rem .8rem; border-radius: .6rem;
    border: 1px solid var(--line); background: #fff; color: var(--ink); font-weight: 700; text-decoration: none; }
  .amenu:hover { background: var(--cream); color: var(--ink); }
  .amenu .ico { width: 1.25rem; height: 1.25rem; }
  .abrand { grid-area: brand; display: flex; align-items: center; gap: .5rem; min-width: 0; min-height: 2.75rem; color: var(--ink); text-decoration: none; }
  .abrand .lm-mark { width: 2rem; height: 2rem; border-radius: .6rem; }
  .abrand .lm-mark .ico { width: 1.3rem; height: 1.3rem; }
  .abrand .lm { font-family: var(--serif); font-size: 1.125rem; font-weight: 600; min-width: 0; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
  .atop > .iconbtn { grid-area: bell; width: 2.75rem; height: 2.75rem; }
  .atop > .me { grid-area: me; justify-self: end; }
  .atop > .anew { grid-area: new; justify-self: end; }
  .atop .abtn, .me summary { min-height: 2.75rem; }
  .asearch { grid-area: search; max-width: none; min-width: 0; min-height: 2.75rem; }
  .asearch input { min-height: 2.65rem; min-width: 0; }
  .menu-list { max-width: calc(100vw - 2rem); }

  .abody { padding: 1rem; }
  /* Panels and cards inside module grids may shrink to the column: a wide table in one scrolls in its
     .table-wrap instead of stretching the column (and the page) to the table's width. */
  .abody .panel, .abody .card, .abody form, .abody fieldset, .abody section { min-width: 0; }
  .afoot { margin-top: 1rem; padding: 1rem; }
  .ahead { align-items: flex-start; }
  .ahead > * { min-width: 0; max-width: 100%; }
  .toolbar > * { min-width: 0; max-width: 100%; }
  .abody .abtn { white-space: normal; max-width: 100%; }
  /* Any console table not already in a .table-wrap scrolls inside its own box instead of widening the page. */
  .abody table.t:not(.table-wrap table) { display: block; overflow-x: auto; -webkit-overflow-scrolling: touch; position: relative; }
  .abody .table-wrap { max-width: 100%; }
  .abody pre { white-space: pre-wrap; overflow-wrap: anywhere; }
  .abody img, .abody video, .abody iframe { max-width: 100%; }
}
/* Print pages opened on a phone (rosters, letters, flyers) fit the screen; paper is unchanged. */
@media screen and (max-width: 600px) {
  .print-page { padding: 1rem; }
  .print-head { flex-wrap: wrap; }
  .print-head img { max-width: 100%; height: auto; max-height: .55in; }
  .print-head > * { min-width: 0; }
  .print-actions { flex-wrap: wrap; }
}
@media (max-width: 560px) {
  .metrics { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .grid-3, .grid-4 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .shell-admin .grid-2 { grid-template-columns: minmax(0, 1fr); }
  .me .who { display: none; }
  /* A phone: the menu, the brand and the account menu keep the first row and search, the bell and New the second, as
     before; Phone view, its words beside the icon, is a third row at the right (in the first row at 390px it would
     leave the brand 27px, less than its mark). */
  .atop:has(.aphone) { grid-template-areas: "menu brand brand me" "search search bell new" "phone phone phone phone"; }
  .atop:has(.aphone):not(:has(.anew)) { grid-template-areas: "menu brand brand me" "search search search bell" "phone phone phone phone"; }
  .shell-admin .period { flex-wrap: wrap; }
  /* Rows of a panel head or list wrap their last items under the first when a larger text size needs it. */
  .shell-admin .phead, .shell-admin .nlist li { flex-wrap: wrap; }
  /* A row's words keep a 10rem column, so its action link ("Review take down requests") goes under them instead of
     squeezing them to a word a line ("Recordings" broke on a 375px phone, text-sizes 2026-10-28). */
  .shell-admin .nlist li > .grow { flex: 1 1 10rem; }
  .shell-admin .phead > * { min-width: 0; }
  .shell-admin .period select { max-width: 100%; }
}
@media (max-width: 360px) {
  .tiles { gap: .5rem; }
  .tile { min-height: 5.75rem; }
}
@media (min-width: 700px) {
  .shell-app .page { padding-top: .75rem; }
}
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { animation: none !important; transition: none !important; scroll-behavior: auto !important; }
}
@media (prefers-contrast: more) {
  :root { --muted: #4E4038; --line: #BDB2A4; --line-2: #D6CEC2; }
}
