/* ============================================================================
   sharp.css — legibility layer. Loads AFTER theme.css and wins by position.

   WHY THIS FILE EXISTS
   The interface read as "low resolution" next to the other POA systems. It was
   not the font — both this app and ipms.poanexgen.com use Plus Jakarta Sans.
   It was the size. Measured on the running pages with the same script:

       ipms.poanexgen.com   2 text elements below 12px  (~1% of the page)
       this app           110 text elements below 12px  (60% of the page)

   The app was setting text at 8px and 9px in 123 separate rules. At that size a
   glyph has too few pixels to resolve on an ordinary monitor and antialiasing
   smears it — which is exactly what "low pixel" looks like. IPMS never goes
   below 12.5px and does its work at 14.5px.

   So this file raises the floor to match IPMS, lifts the muted greys to a
   contrast that survives daylight, and firms up the hairlines. Nothing is
   restyled and no colour is re-invented: sizes, weights and contrast only.

   MAPPING:  8px -> 12px   9px -> 12.5px   10px -> 13px   11/11.5px -> 13.5px

   Everything carries !important because theme.css sets font-size !important in
   106 places; without it the old sizes win regardless of load order.
   ============================================================================ */

/* ---------------------------------------------------------------------------
   1. The floor — was 8px
   --------------------------------------------------------------------------- */
.brand-sub,
.auth-visual-kicker,
.gh-icon-btn em,
.gh-bar-value,
.gh-date b,
.gh-event small,
.gh-event em,
.gh-activity small,
.gh-progress section p,
.gh-setup li,
.gh-setup li span,
.gh-promo-copy > span,
.gh-footer,
.gh-attention-item small,
.gh-good small,
.gh-journey-mini small,
.gh-birthday-list small,
.gh-action small,
.person-photo-preview span:last-child,
body[data-route="dashboard"] .gh-event small,
body[data-route="dashboard"] .gh-activity small,
body[data-route="dashboard"] .gh-action small,
body[data-route="dashboard"] .gh-promo-copy > span,
body[data-route="dashboard"] .gh-footer {
  font-size: 12px !important;
  letter-spacing: 0 !important;
}

/* The sidebar strapline is set in small caps and needs its tracking kept. At a
   readable size those 27 characters no longer fit the 232px rail on one line,
   and it was only ever fitting because it was 8px — so let it wrap instead of
   shrinking it back below the floor. */
.brand-sub,
#sidebar .brand-sub,
.auth-visual-kicker {
  font-size: 11px !important;
  letter-spacing: .08em !important;
  font-weight: 700 !important;
  white-space: normal !important;
  line-height: 1.35 !important;
}

/* ---------------------------------------------------------------------------
   2. Was 9px
   --------------------------------------------------------------------------- */
#nav .nav-group,
.nav-group,
.gh-church-switch small,
.gh-user small,
.gh-eyebrow,
.gh-verse small,
.gh-kpi i,
.gh-kpi em,
.gh-card-head p,
.gh-axis,
.gh-bar-label,
.gh-activity strong,
.gh-gold-btn,
.gh-promo-copy p,
.gh-promo-copy a,
.gh-select-link,
.gh-link,
.gh-chart-foot,
.gh-attention-item strong,
.gh-birthday-list strong,
.gh-action strong,
.report-bar-value,
.report-bar-label,
#view .report-pie-caption,
.date-range-field span,
.calendar-picker,
.person-photo-copy small,
.search-live-row small,
body[data-route="dashboard"] .gh-footer,
body[data-route="dashboard"] .gh-kpi i,
body[data-route="dashboard"] .gh-kpi em,
body[data-route="dashboard"] .gh-card-head p,
body[data-route="dashboard"] .gh-eyebrow,
body[data-route="dashboard"] .gh-promo-copy p,
body[data-route="dashboard"] .gh-activity strong,
body[data-route="dashboard"] .gh-action strong {
  font-size: 12.5px !important;
}

/* Section headings in the rail are the map of the whole system — they were the
   single smallest thing on screen at 9px. */
#nav .nav-group,
.nav-group {
  font-size: 11.5px !important;
  letter-spacing: .09em !important;
  font-weight: 800 !important;
  color: #8A7A5C !important;
}

/* An eyebrow is deliberately small-caps; keep the style, raise the size. */
.gh-eyebrow,
.report-eyebrow,
#view .report-eyebrow,
#view .eyebrow,
.eyebrow,
body[data-route="dashboard"] .gh-eyebrow {
  font-size: 11.5px !important;
  letter-spacing: .12em !important;
  font-weight: 800 !important;
}

/* ---------------------------------------------------------------------------
   3. Was 10px
   --------------------------------------------------------------------------- */
.gh-avatar,
.gh-kpi small,
.gh-select,
.gh-event strong,
table thead th,
.account-role,
.account-action,
.gh-chart-empty,
.gh-bday-avatar,
.status.good,
.report-pie-caption,
.security-status,
#view table thead th,
#view .report-line-chart .report-axis,
#view .report-bar-value,
#view .report-bar-label,
#view .ws-stat small,
#view .dl dt,
#view .os-timeline-item small,
.search-live-all,
body[data-route="dashboard"] .gh-kpi small,
body[data-route="dashboard"] .gh-event strong {
  font-size: 13px !important;
}

/* Table headers carry the meaning of every column. IPMS sets its own at 12.5px
   uppercase; this matches it rather than the old 10px. */
table thead th,
#view table thead th,
.user-table th,
th {
  font-size: 12.5px !important;
  font-weight: 800 !important;
  letter-spacing: .04em !important;
  color: #4A5670 !important;
}

/* ---------------------------------------------------------------------------
   4. Was 11px / 11.5px
   --------------------------------------------------------------------------- */
.os-kpi-sub,
.journey-stage,
.status-badge,
.auth-visual-features span,
.gh-church-switch strong,
.gh-user strong,
.gh-chart-empty,
.gh-empty,
.gh-progress section strong,
.gh-welcome p,
.gh-chart-foot b,
.gh-progress > div span,
.gh-good strong,
#view .card > h3:first-child,
body:not([data-route="dashboard"]) header.page .sub,
.gh-line-chart .gh-axis,
.report-chart-head p,
#view .status-badge,
#view .journey-stage,
#view .ws-stat span,
#view .task-line .muted,
.person-photo-copy p,
.photo-file,
.search-live-empty,
body[data-route="features"] #view .feature-access-card .status,
.date-range-field > span,
.chart .col .cap,
.tree-label,
.role-slot-name,
.stat .label,
.chart .col .val,
.tree-node .rl,
.demo-hint-title,
.age-pct,
.role-badge,
.flag,
body[data-route="dashboard"] .gh-welcome p,
body[data-route="dashboard"] .gh-card-head p,
body[data-route="dashboard"] .gh-kpi i,
body[data-route="dashboard"] .gh-event strong,
body[data-route="dashboard"] .gh-activity strong,
body[data-route="dashboard"] .gh-action strong,
body[data-route="dashboard"] .gh-promo-copy a {
  font-size: 13.5px !important;
}

/* A giving total is the one KPI that can be long: "19" fits at 31px in a 152px
   tile, "GHS1,250.00" does not and broke onto a second line mid-number, as
   "GHS1,250" over ".00". Fluid sizing keeps one line whatever the amount. */
.gh-kpi strong,
body[data-route="dashboard"] .gh-kpi strong {
  font-size: clamp(19px, 1.55vw, 25px) !important;
  white-space: nowrap !important;
  letter-spacing: -.03em !important;
  display: block;
  /* Deliberately NOT hidden/ellipsis: clipping a money figure to "GHS1,25…"
     is worse than letting it run a few pixels into the tile's own padding. */
  overflow: visible !important;
}

/* The KPI caption under each dashboard number. */
.gh-kpi small,
body[data-route="dashboard"] .gh-kpi small,
.gh-kpi i,
body[data-route="dashboard"] .gh-kpi i {
  font-size: 13px !important;
  font-weight: 700 !important;
}

/* ---------------------------------------------------------------------------
   5. The type scale, copied off IPMS rather than approximated

   Measured on the running page (getComputedStyle, not guesswork):

       body   14px    / 400 / line-height 1.45 / #0F1B2D
       h1     47px    / 800 / letter-spacing -0.025em
       h2     28.7px  / 800 / -0.02em  / line-height 1.15
       h3     17.5px  / 700 / -0.015em / line-height 1.45
       p      16px    / 400 / line-height 1.55
       nav    14px    / 500, 700 when active / padding 8px 13px / radius 9px

   Tight negative tracking on the big weights is most of why IPMS looks cut
   rather than printed — 800 at default spacing reads soft at display sizes.
   --------------------------------------------------------------------------- */
html, body {
  font-size: 15px !important;
  line-height: 1.45 !important;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-rendering: optimizeLegibility;
  font-feature-settings: "kern" 1, "liga" 1;
}

#view h1, header.page #page-title h1 {
  font-size: 28px !important;
  font-weight: 800 !important;
  letter-spacing: -.022em !important;
  line-height: 1.15 !important;
  color: #0F1B2D !important;
}
#view h2, .card > h2 {
  font-size: 19px !important;
  font-weight: 800 !important;
  letter-spacing: -.018em !important;
  line-height: 1.25 !important;
  color: #0F1B2D !important;
}
#view h3, .card > h3 {
  font-size: 17px !important;
  font-weight: 700 !important;
  letter-spacing: -.015em !important;
  line-height: 1.4 !important;
  color: #0F1B2D !important;
}
#view p { line-height: 1.55 !important; }

/* The kiosk is excluded: it sets its own, much larger scale, and these generic
   rules would otherwise shrink its headings back to body size. */
body:not([data-route="kiosk"]) #view table td,
body:not([data-route="kiosk"]) #view table th,
body:not([data-route="kiosk"]) .table td,
body:not([data-route="kiosk"]) .table th,
body:not([data-route="kiosk"]) #view p,
body:not([data-route="kiosk"]) #view li,
body:not([data-route="kiosk"]) #view label,
body:not([data-route="kiosk"]) .small,
body:not([data-route="kiosk"]) .muted.small,
body:not([data-route="kiosk"]) #view .small {
  font-size: 14px !important;
}

/* IPMS's own nav: 14px, 500 at rest and 700 when active, 8px 13px, radius 9px,
   and the active item tinted rather than filled. */
#nav a,
#nav a span {
  font-size: 14px !important;
  font-weight: 500 !important;
  letter-spacing: -.006em !important;
}
#nav a {
  padding: 9px 13px !important;
  border-radius: 9px !important;
  color: #3D4D63 !important;
}
#nav a:hover { background: #EEF3FA !important; }
#nav a.active,
#nav a.active span {
  font-weight: 700 !important;
  color: #0F1B2D !important;
}
#nav a.active { background: #EAF1FB !important; }

/* The whole shell now sits on one type scale, so the buttons match the nav. */
button, .btn, #view button {
  font-family: var(--sans) !important;
  letter-spacing: -.006em !important;
}

/* ---------------------------------------------------------------------------
   6. Neutrals — the cream page was half the reason it looked soft

   Sampled straight off ipms.poanexgen.com, which is the sharpness Prince is
   comparing against:

       page        #F4F7FB   (cool, almost white — not cream)
       cards       #FFFFFF
       hairlines   #E3E9F2   at 1px
       text        #0F1B2D
       radius      14px, shadow rgba(15,33,56,.05) 0 1px 2px

   Cream (#F8F6F0) sits only 3% away from a white card, so card edges barely
   existed and warm grey text on warm paper had nothing to bite against. The
   cool neutral separates paper from page and makes the navy read as ink.
   The gold and green stay: those are the church's colours, not the chrome's.
   --------------------------------------------------------------------------- */
:root {
  --gh-cream: #F4F7FB !important;   /* the page */
  --gh-paper: #FFFFFF !important;   /* cards */
  --gh-line:  #E3E9F2 !important;   /* was #E5E0D6 — warm and invisible */
  --gh-muted: #55637B !important;   /* was #73809A — too pale to read */
  --gh-navy:  #0F1B2D !important;   /* IPMS ink */
}

html, body, #app, #main {
  background: #F4F7FB !important;
  color: #0F1B2D !important;
}

/* Cards become true white with a visible edge, the way IPMS draws them. */
.card, .gh-card, #view .card, .gh-kpi, .feature-access-card,
.gh-chart-card, .report-chart-card, #view .gh-panel {
  background: #FFFFFF !important;
  border: 1px solid #E3E9F2 !important;
  box-shadow: 0 1px 2px rgba(15, 33, 56, .05) !important;
}

/* The rail is white too; only its right edge separates it from the page. */
#sidebar {
  background: #FFFFFF !important;
  border-right: 1px solid #E3E9F2 !important;
}
#sidebar .brand { border-bottom: 1px solid #E3E9F2 !important; }

/* The dashboard hero washes its photo with a warm #FBFAF6 gradient, which was
   the one patch of cream left once the page went cool — restate it in the new
   neutral, same photo, same fade. */
.gh-welcome,
body[data-route="dashboard"] .gh-welcome {
  background:
    linear-gradient(90deg, #FFFFFF 0%, #FFFFFF 68%, rgba(255, 255, 255, .72) 100%),
    url('../assets/gracehub-church.jpg') !important;
  background-repeat: no-repeat !important;
  background-position: center, right center !important;
  background-size: cover, auto 100% !important;
  border: 1px solid #E3E9F2 !important;
  border-radius: 16px !important;
}

/* Warm hovers and warm table headers carried the cream in with them. */
button:not(.primary):hover, .btn:not(.primary):hover,
.age-tile:hover, .account-action, .account-action:hover {
  background: #EEF3FA !important;
  border-color: #D3DDEB !important;
}
table thead th, #view table thead th {
  background: #F7F9FC !important;
  color: #4A5670 !important;
}

.muted,
.sub,
#view .muted,
.gh-card-head p,
.gh-welcome p,
.gh-chart-foot,
.gh-axis,
.gh-bar-label {
  color: #5B6880 !important;
}

/* Chart furniture was the least readable thing on the dashboard. */
.gh-axis,
.gh-line-chart .gh-axis,
#view .report-line-chart .report-axis {
  fill: #5B6880 !important;
  font-weight: 600 !important;
}

.gh-grid-line { stroke: #DCD5C6 !important; }

/* ---------------------------------------------------------------------------
   7. Display type — IPMS sets its hero in Plus Jakarta Sans at weight 800 and
   it reads far crisper than Georgia does on Windows, which renders soft at
   large sizes. The scripture verse keeps its serif: there it is the point.
   --------------------------------------------------------------------------- */
.brand-name,
#sidebar .brand-name,
.gh-welcome h1,
body[data-route="dashboard"] .gh-welcome h1,
body[data-route="dashboard"] .gh-welcome h1 span,
.gh-welcome h1 span,
.os-kpi-value,
.auth-visual-title,
.auth-card .auth-brand,
header.page #page-title h1,
.gh-kpi strong,
body[data-route="dashboard"] .gh-kpi strong,
.gh-journey-mini b,
.gh-promo-copy h3,
body[data-route="dashboard"] .gh-promo-copy h3,
.report-chart-total,
.report-pie-total,
.report-head h2,
.report-head h3,
.stat .value,
body[data-route="reports"] #view .report-section-intro h2 {
  font-family: var(--sans) !important;
  font-weight: 800 !important;
  letter-spacing: -.02em !important;
}

.gh-verse,
body[data-route="dashboard"] .gh-verse {
  font-family: Georgia, 'Times New Roman', serif !important;
  font-size: 14px !important;
}
.gh-verse small { font-size: 12px !important; }

/* ---------------------------------------------------------------------------
   8. Edges — a card should have a visible boundary, not a suggestion of one
   --------------------------------------------------------------------------- */
.card,
.gh-card,
#view .card,
.gh-kpi {
  border-color: #DCD5C6 !important;
}

/* ---------------------------------------------------------------------------
   8b. Reports: the age-distribution legend ran off the card
   .report-pie-wrap is a 412px flex row holding a ~245px donut next to a legend
   with min-width:230px and flex-wrap:nowrap — 475px of content in 412px, so the
   percentages were cut off at the card's edge. Measured with this file disabled
   too, so it is an existing bug rather than something the larger type caused.
   Letting the row wrap puts the legend under the donut when it will not fit.
   --------------------------------------------------------------------------- */
#view .report-pie-wrap {
  flex-wrap: wrap !important;
}
#view .report-pie-wrap .report-legend {
  min-width: 0 !important;
  flex: 1 1 210px !important;
}

/* The build number under the account footer. Small and quiet, but readable —
   it is the one thing that settles "is your browser even running this?". */
/* ---------------------------------------------------------------------------
   The sign-in picture was being cut off

   `.auth-visual` is an empty element whose whole content is gracehub-login.jpg
   as a background, and theme.css sets `background-size: cover`. Cover fills the
   panel by cropping whatever does not fit — fine for a plain photo, wrong for
   this one, because the headline, the body copy and the five icons are baked
   into the picture. Measured on the live page: the image is 840x1024 (aspect
   0.820) in a 443x683 panel (aspect 0.649), so cover was slicing 58px off each
   side, taking the start of "People." and the outer icons with it.

   `contain` shows the whole composition at every size. Anchored to the top so
   the leftover band falls at the bottom, and painted #0F161E, sampled from the
   image's own bottom edge — so the band reads as part of the picture rather
   than as a letterbox.

   The selector has to be theme.css's own, character for character:
   `#auth-screen:not(.has-backdrop) > .auth-card .auth-visual` (specificity
   0,1,3,1) already sets background-size:cover !important. A shorter selector
   here loses even with !important, which is exactly what happened first time:
   the background-colour landed and the size did not.

   Only the built-in picture is treated this way. When a church uploads its own
   sign-in photo, applyBranding() adds `has-backdrop`, this rule stops matching,
   and cover is right again — an ordinary photograph has no artwork to crop.

   Above 860px only. That is theme.css's own breakpoint: below it the card
   stacks to one column and the picture becomes a 250–320px banner. `contain`
   in a box that shape renders the image at 21% — a narrow sliver marooned
   between two dark bands, with text far too small to read. On a phone the
   picture is decoration, so cover is the right answer there and is left alone.

   `contain` alone fixed the cropping but left dark bars down both sides, because
   the picture column is 52% of a 1540px card while the picture is 840x1024.
   Rather than fill those bars with something, the column is sized to the
   picture: theme.css fixes the card's height at min(900px, 100vh - 40px), so
   multiplying that by the image's own aspect ratio (840/1024 = 0.8203) gives a
   column the picture fits exactly — no bars and nothing cropped. The min()
   stops it exceeding its old 52% on a short, wide window; in that one case a
   hairline of #0F161E shows, which is the image's own edge colour. */
@media (min-width: 861px) {
  #auth-screen:not(.has-backdrop) > .auth-card {
    grid-template-columns:
      min(calc(min(900px, 100vh - 40px) * 0.8203), 52%) minmax(0, 1fr) !important;
  }
  /* Anchored to the top, not centred. At the common desktop shapes the picture
     fits its column exactly and this makes no difference; on a narrow, tall
     window the 52% cap leaves a horizontal band, and putting all of it at the
     bottom hides it against the image's own #0F161E lower edge instead of
     splitting it into two visible strips. */
  #auth-screen:not(.has-backdrop) > .auth-card .auth-visual {
    background-size: contain !important;
    background-position: center top !important;
    background-repeat: no-repeat !important;
    background-color: #0F161E !important;
  }
}

.account-build {
  font-size: 11.5px !important;
  font-weight: 700 !important;
  letter-spacing: .04em;
  color: #8A94A6 !important;
  padding: 7px 2px 0;
}

/* ============================================================================
   8b2. The shell topbar

   It moved out of the dashboard view into #shell-topbar so it exists on every
   page. theme.css only ever styled it under body[data-route="dashboard"], so
   the layout is restated here, route-independent.
   ============================================================================ */
#shell-topbar { padding: 0; }

#shell-topbar .gh-topbar {
  display: flex !important;
  align-items: center;
  gap: 14px;
  flex-wrap: wrap;
  padding: 14px clamp(14px, 2.2vw, 28px) !important;
  background: #FFFFFF !important;
  border-bottom: 1px solid #E3E9F2 !important;
  margin: 0 !important;
  position: relative;
  z-index: 40;
}

#shell-topbar .gh-search {
  flex: 1 1 320px;
  min-width: 0;
  position: relative;
  display: flex;
  align-items: center;
  gap: 9px;
  background: #F4F7FB !important;
  border: 1px solid #E3E9F2 !important;
  border-radius: 11px !important;
  padding: 0 10px !important;
  max-width: 560px;
}
#shell-topbar .gh-search input {
  flex: 1 1 auto;
  min-width: 0;
  border: none !important;
  background: transparent !important;
  font-size: 14.5px !important;
  padding: 11px 0 !important;
  color: #0F1B2D !important;
  font-family: var(--sans) !important;
  box-shadow: none !important;
  min-height: 0 !important;
}
#shell-topbar .gh-search input:focus { outline: none !important; }
#shell-topbar .gh-search:focus-within {
  border-color: #B98A32 !important;
  background: #FFFFFF !important;
}
#shell-topbar .gh-search-go {
  border: none !important;
  background: transparent !important;
  color: #55637B !important;
  cursor: pointer;
  padding: 6px 8px !important;
  box-shadow: none !important;
}
#shell-topbar .gh-search-icon {
  flex: 0 0 18px; width: 18px !important; height: 18px !important;
  background: transparent !important; color: #55637B !important;
  display: flex !important; align-items: center; border-radius: 0 !important;
  box-shadow: none !important;
}
#shell-topbar .gh-search-icon svg { width: 17px !important; height: 17px !important; }

#shell-topbar .gh-top-actions {
  display: flex;
  align-items: center;
  gap: 10px;
  margin-left: auto;
}

#shell-topbar .gh-church-switch,
#shell-topbar .gh-user {
  display: flex !important;
  align-items: center;
  gap: 10px;
  background: #FFFFFF !important;
  border: 1px solid #E3E9F2 !important;
  border-radius: 12px !important;
  padding: 7px 12px !important;
  color: #0F1B2D !important;
  text-align: left;
  box-shadow: none !important;
  max-width: 250px;
}
#shell-topbar .gh-church-switch:hover,
#shell-topbar .gh-user:hover,
#shell-topbar .gh-icon-btn:hover { background: #EEF3FA !important; }

#shell-topbar .gh-church-switch strong,
#shell-topbar .gh-user strong {
  display: block; font-size: 14px !important; font-weight: 700 !important;
  line-height: 1.25; white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
  letter-spacing: -.01em;
}
#shell-topbar .gh-church-switch small,
#shell-topbar .gh-user small {
  display: block; font-size: 12.5px !important; color: #55637B !important;
  line-height: 1.25; white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
#shell-topbar .gh-church-switch > span:nth-child(2),
#shell-topbar .gh-user > span:nth-child(2) { min-width: 0; }
#shell-topbar .gh-church-switch b,
#shell-topbar .gh-user b {
  flex: 0 0 auto; color: #8A94A6 !important; font-size: 14px !important; font-weight: 700;
}

#shell-topbar .gh-icon-btn {
  position: relative;
  display: flex !important;
  align-items: center;
  justify-content: center;
  width: 42px; height: 42px;
  background: #FFFFFF !important;
  border: 1px solid #E3E9F2 !important;
  border-radius: 12px !important;
  box-shadow: none !important;
  padding: 0 !important;
}
#shell-topbar .gh-icon-btn em {
  position: absolute; top: -6px; right: -6px;
  background: #C0392B; color: #fff;
  font-style: normal; font-size: 11.5px !important; font-weight: 800 !important;
  min-width: 19px; height: 19px; border-radius: 999px;
  display: flex; align-items: center; justify-content: center;
  border: 2px solid #fff;
}
#shell-topbar .gh-dash-glyph {
  width: 20px !important; height: 20px !important;
  background: transparent !important; color: #0F1B2D !important;
  display: flex !important; align-items: center; justify-content: center;
  border-radius: 0 !important; box-shadow: none !important;
}
#shell-topbar .gh-dash-glyph svg { width: 19px !important; height: 19px !important; }
#shell-topbar .gh-church-mark {
  flex: 0 0 34px; width: 34px; height: 34px;
  background: #F4F7FB !important; border-radius: 9px !important;
  display: flex !important; align-items: center; justify-content: center;
}

/* The page header now sits under the topbar, not at the top of the window. */
header.page { border-bottom: 1px solid #E3E9F2 !important; }

@media (max-width: 860px) {
  #shell-topbar .gh-church-switch small,
  #shell-topbar .gh-user small { display: none !important; }
  #shell-topbar .gh-church-switch,
  #shell-topbar .gh-user { max-width: 180px; }
  #shell-topbar .gh-search { flex: 1 1 100%; order: 3; max-width: none; }
}
@media (max-width: 560px) {
  #shell-topbar .gh-church-switch strong { display: none !important; }
  #shell-topbar .gh-church-switch { max-width: none; padding: 7px 9px !important; }
  /* theme.css hides `.gh-user span` on a phone, which takes the AVATAR with it
     and leaves a box containing nothing but a chevron. The avatar is the whole
     control at this width — hide the name, keep the face. */
  #shell-topbar .gh-user .gh-avatar,
  #shell-topbar .gh-church-switch .gh-church-mark {
    display: flex !important;
  }
  #shell-topbar .gh-user > span:not(.gh-avatar) { display: none !important; }
  #shell-topbar .gh-user { max-width: none; padding: 5px 9px !important; }
}

/* "Age" in a 46px column was breaking one letter per line once uppercase and
   letter-spacing were added to table headers, so headers never wrap now.

   That has a cost worth naming: with table-layout:auto, headers that refuse to
   wrap take their width from whatever else will yield — and the name column
   yielded all the way down to 13px, stacking "Abena Boateng" one letter per
   line, because theme.css sets overflow-wrap:anywhere on person links. So the
   name column gets a floor, and names are told to break on spaces like names. */
table thead th, #view table thead th, .user-table th, th {
  white-space: nowrap !important;
}
#view table td:first-child,
#view table th:first-child { min-width: 148px !important; }

#view .person-link,
#view .person-link .nm {
  overflow-wrap: normal !important;
  word-break: normal !important;
}
#view .person-link .nm { min-width: 0 !important; }

/* ============================================================================
   8c. Header menus — church, notifications, account

   These three were links wearing a ⌄. Now the arrow opens a panel instead of
   navigating, so the dashboard stays put while you look.
   ============================================================================ */
.gh-menu { position: relative; }

.gh-menu > button {
  cursor: pointer;
  font-family: var(--sans) !important;
}

.gh-menu-panel {
  position: absolute;
  top: calc(100% + 8px);
  right: 0;
  z-index: 80;
  min-width: 268px;
  max-width: 340px;
  max-height: min(70vh, 480px);
  overflow-y: auto;
  background: #FFFFFF;
  border: 1px solid #E3E9F2;
  border-radius: 14px;
  box-shadow: 0 12px 34px rgba(15, 33, 56, .16), 0 2px 6px rgba(15, 33, 56, .06);
  padding: 8px;
  text-align: left;
}
.gh-menu-panel[hidden] { display: none; }

.gh-menu-head {
  padding: 10px 12px 12px;
  border-bottom: 1px solid #EDF1F7;
  margin-bottom: 6px;
}
.gh-menu-head strong { display: block; font-size: 15px !important; font-weight: 800 !important; color: #0F1B2D; }
.gh-menu-head small { display: block; font-size: 13px !important; color: #55637B; margin-top: 2px; }

.gh-menu-label {
  font-size: 11.5px !important;
  font-weight: 800 !important;
  letter-spacing: .09em;
  text-transform: uppercase;
  color: #8A94A6;
  padding: 8px 12px 4px;
}

.gh-menu-item {
  display: flex !important;
  align-items: center;
  gap: 11px;
  width: 100%;
  padding: 10px 12px !important;
  border: none !important;
  border-radius: 10px !important;
  background: transparent !important;
  color: #0F1B2D !important;
  font-size: 14.5px !important;
  font-weight: 600 !important;
  font-family: var(--sans) !important;
  text-decoration: none;
  text-align: left;
  cursor: pointer;
  box-shadow: none !important;
}
.gh-menu-item:hover { background: #EEF3FA !important; }
.gh-menu-item.danger { color: #A4342B !important; }
.gh-menu-item.danger:hover { background: #FDECEA !important; }
.gh-menu-item > span { min-width: 0; }
.gh-menu-item b { display: block; font-weight: 700; font-size: 14px; }
.gh-menu-item i {
  display: block; font-style: normal; font-size: 13px !important;
  color: #55637B; margin-top: 1px;
}
/* Icons.icon() returns a tinted <span class="ico"> whose SVG has no intrinsic
   size — theme.css sizes it per context (nav a .ico, .gh-kpi-icon .ico …) and a
   class it does not know collapses to 0×0. So this menu sizes its own. */
.gh-menu-glyph {
  flex: 0 0 22px !important;
  width: 22px !important;
  height: 22px !important;
  display: flex !important;
  align-items: center;
  justify-content: center;
  background: transparent !important;
  color: #55637B !important;
  border-radius: 0 !important;
  box-shadow: none !important;
}
.gh-menu-glyph svg {
  width: 19px !important;
  height: 19px !important;
  stroke: currentColor !important;
}
.gh-menu-item:hover .gh-menu-glyph { color: #0F1B2D !important; }
.gh-menu-item.danger .gh-menu-glyph { color: #A4342B !important; }

.gh-menu-sep { height: 1px; background: #EDF1F7; margin: 6px 4px; }
.gh-menu-empty {
  padding: 18px 12px; text-align: center;
  font-size: 14px !important; color: #55637B;
}

@media (max-width: 720px) {
  .gh-menu-panel { min-width: 240px; right: -4px; }
}

/* ============================================================================
   8d. Settings tabs — the seven Admin pages folded into one
   ============================================================================ */
.admin-tabs {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  padding: 5px;
  background: #FFFFFF;
  border: 1px solid #E3E9F2;
  border-radius: 14px;
  margin-bottom: 18px;
}
.admin-tab {
  border: none !important;
  background: transparent !important;
  color: #55637B !important;
  font-family: var(--sans) !important;
  font-size: 14px !important;
  font-weight: 700 !important;
  padding: 10px 15px !important;
  border-radius: 10px !important;
  cursor: pointer;
  box-shadow: none !important;
  white-space: nowrap;
}
.admin-tab:hover { background: #EEF3FA !important; color: #0F1B2D !important; }
/* After :hover, and matching it too — otherwise the pointer resting on the tab
   you just opened repaints it pale with white text on it, i.e. invisible. */
.admin-tab.active,
.admin-tab.active:hover {
  background: #0F1B2D !important;
  color: #FFFFFF !important;
}

@media (max-width: 720px) {
  .admin-tabs { overflow-x: auto; flex-wrap: nowrap; }
}

/* ============================================================================
   8e. The feature switches
   A switch has to look like it moves, or it is just a label again.
   ============================================================================ */
.gh-switch {
  display: inline-flex !important;
  align-items: center;
  gap: 10px;
  margin-left: auto;
  border: none !important;
  background: transparent !important;
  padding: 4px !important;
  cursor: pointer;
  box-shadow: none !important;
  font-family: var(--sans) !important;
}
.gh-switch-track {
  display: block;
  width: 48px;
  height: 28px;
  border-radius: 999px;
  background: #CFD8E6;
  position: relative;
  transition: background .18s cubic-bezier(.32, .72, 0, 1);
  flex: 0 0 48px;
}
.gh-switch-knob {
  position: absolute;
  top: 3px; left: 3px;
  width: 22px; height: 22px;
  border-radius: 50%;
  background: #FFFFFF;
  box-shadow: 0 1px 3px rgba(15, 33, 56, .3);
  transition: transform .18s cubic-bezier(.32, .72, 0, 1);
}
.gh-switch.on .gh-switch-track { background: #2F6E57; }
.gh-switch.on .gh-switch-knob { transform: translateX(20px); }
.gh-switch-text {
  font-size: 13.5px !important;
  font-weight: 800 !important;
  color: #55637B !important;
  min-width: 24px;
}
.gh-switch.on .gh-switch-text { color: #2F6E57 !important; }
.gh-switch:focus-visible .gh-switch-track {
  outline: 2px solid #B98A32;
  outline-offset: 2px;
}

.feature-access-card .row { align-items: center; }

/* ============================================================================
   9. Attendance kiosk
   Its own screen, meant for a tablet propped at the door. Everything here is
   deliberately large: it is read at arm's length by someone standing up, and
   tapped by people who are not staff.
   ============================================================================ */
/* #shell-topbar joined this list in v46: the topbar is global now, and a search
   box and an account menu over a door kiosk is exactly what a kiosk must not
   have — anyone walking in would be one tap from the church's records. */
body[data-route="kiosk"] #sidebar,
body[data-route="kiosk"] #mobile-bar,
body[data-route="kiosk"] header.page,
body[data-route="kiosk"] #shell-topbar,
body[data-route="kiosk"] #nav-scrim { display: none !important; }

body[data-route="kiosk"] #main {
  margin: 0 !important;
  padding: 0 !important;
  width: 100% !important;
  max-width: none !important;
  flex-basis: 100% !important;
}
body[data-route="kiosk"] #view { padding: 0 !important; max-width: none !important; }
body[data-route="kiosk"] { overflow-x: hidden; }

.kiosk {
  min-height: 100vh;
  background: linear-gradient(170deg, #132B52 0%, #1B3A63 55%, #24406A 100%);
  color: #fff;
  padding: 26px clamp(16px, 4vw, 54px) 40px;
  display: flex;
  flex-direction: column;
  gap: 20px;
}

.kiosk-top {
  display: flex;
  align-items: center;
  gap: 16px;
  flex-wrap: wrap;
}
/* Everything below carries !important for the same reason the type floor does:
   theme.css styles bare `button` and `#view p` with !important, and the kiosk
   is a different kind of screen that has to escape those defaults. */
.kiosk-top .kiosk-church {
  font-size: 24px !important;
  font-weight: 800 !important;
  letter-spacing: -.02em;
  color: #fff !important;
  margin: 0;
}
.kiosk-top .kiosk-service {
  font-size: 15px !important;
  color: #C7D3E8 !important;
  margin: 3px 0 0;
}
.kiosk-spacer { flex: 1 1 auto; }

.kiosk-exit {
  background: rgba(255, 255, 255, .14) !important;
  color: #fff !important;
  border: 1px solid rgba(255, 255, 255, .3) !important;
  border-radius: 12px !important;
  padding: 12px 20px !important;
  font-size: 15px !important;
  font-weight: 700 !important;
  cursor: pointer;
  box-shadow: none !important;
}
.kiosk-exit:hover { background: rgba(255, 255, 255, .24) !important; }

.kiosk-counts {
  display: flex;
  gap: 12px;
  flex-wrap: wrap;
}
.kiosk-count {
  background: rgba(255, 255, 255, .10) !important;
  border: 1px solid rgba(255, 255, 255, .16) !important;
  border-radius: 14px;
  padding: 12px 20px;
  min-width: 124px;
}
.kiosk-count strong {
  display: block; font-size: 32px !important; font-weight: 800 !important;
  line-height: 1.1; color: #fff !important;
}
.kiosk-count span {
  display: block; font-size: 13.5px !important; color: #C7D3E8 !important;
  margin-top: 3px; font-weight: 600 !important;
}

/* The search box is the whole interface. It is sized to be hit accurately by
   somebody standing over a tablet, and it keeps focus after every render. */
.kiosk-search-wrap { position: relative; }
.kiosk-search {
  width: 100% !important;
  font-size: 27px !important;
  font-weight: 600 !important;
  padding: 22px 24px !important;
  border-radius: 18px !important;
  border: 2px solid rgba(255, 255, 255, .25) !important;
  background: #fff !important;
  color: #132B52 !important;
  font-family: var(--sans) !important;
  min-height: 0 !important;
  box-shadow: 0 6px 18px rgba(0, 0, 0, .22) !important;
}
.kiosk-search::placeholder { color: #8894AC !important; font-weight: 500; }
.kiosk-search:focus {
  outline: none !important;
  border-color: #D1A64D !important;
  box-shadow: 0 0 0 5px rgba(209, 166, 77, .32) !important;
}

/* 400px, not 330px: at 330 a 768px tablet gets two columns and a surname is
   pushed under the "Tap to check in" pill. One wide column on a tablet is also
   an easier target for somebody standing over it. */
.kiosk-results {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(400px, 1fr));
  gap: 14px;
}

.kiosk-person {
  display: flex !important;
  align-items: center;
  gap: 16px;
  background: #fff !important;
  color: #132B52 !important;
  border-radius: 16px !important;
  padding: 16px 18px !important;
  border: none !important;
  width: 100% !important;
  text-align: left;
  cursor: pointer;
  font-family: var(--sans) !important;
  transition: transform .12s cubic-bezier(.32, .72, 0, 1), box-shadow .12s;
  box-shadow: 0 2px 6px rgba(0, 0, 0, .18) !important;
}
.kiosk-person:hover { transform: translateY(-2px); box-shadow: 0 10px 24px rgba(0, 0, 0, .26); }
.kiosk-person:active { transform: scale(.985); }
.kiosk-person[disabled] { opacity: .62; cursor: default; transform: none; box-shadow: none; }

.kiosk-face {
  width: 58px; height: 58px; flex: 0 0 58px;
  border-radius: 50%;
  background: #E8EEF8;
  color: #2F4E80;
  display: grid; place-items: center;
  font-size: 20px; font-weight: 800;
  overflow: hidden;
}
.kiosk-face img { width: 100%; height: 100%; object-fit: cover; }

/* min-width:0 alone is not enough — without the overflow trio a long name slides
   out of the flex item and under the pill instead of ending in an ellipsis. */
.kiosk-who { min-width: 0; flex: 1 1 auto; overflow: hidden; }
.kiosk-who b {
  display: block; font-size: 20px !important; font-weight: 700 !important;
  letter-spacing: -.01em; color: #132B52 !important;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.kiosk-who span {
  display: block; font-size: 14.5px !important; color: #5B6880 !important; margin-top: 2px;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}

.kiosk-mark {
  font-size: 14px !important;
  font-weight: 800 !important;
  padding: 9px 15px;
  border-radius: 999px;
  background: #132B52;
  color: #fff !important;
  white-space: nowrap;
}
.kiosk-person[disabled] .kiosk-mark { background: #2F6E57; }

.kiosk-hint {
  background: rgba(255, 255, 255, .08);
  border: 1px dashed rgba(255, 255, 255, .28);
  border-radius: 16px;
  padding: 44px 24px;
  text-align: center;
}
.kiosk-hint strong {
  display: block; font-size: 22px !important; font-weight: 700 !important;
  margin-bottom: 8px; color: #fff !important;
}
.kiosk-hint span { font-size: 15.5px !important; color: #C7D3E8 !important; }

.kiosk-guest {
  display: flex; align-items: center; gap: 14px; flex-wrap: wrap;
  background: rgba(255, 255, 255, .08);
  border: 1px solid rgba(255, 255, 255, .18);
  border-radius: 16px;
  padding: 16px 20px;
}
.kiosk-guest p {
  margin: 0; font-size: 14.5px !important; color: #C7D3E8 !important; flex: 1 1 240px;
}
.kiosk-guest b { color: #fff !important; font-size: 15px !important; }
.kiosk-guest button {
  background: #D1A64D !important; color: #241A06 !important;
  border: none !important; border-radius: 12px !important;
  padding: 13px 22px !important; font-size: 15.5px !important; font-weight: 800 !important;
  cursor: pointer; font-family: var(--sans) !important; box-shadow: none !important;
}
.kiosk-guest button:hover { background: #E0B961 !important; }
.kiosk-guest button.ghost {
  background: rgba(255, 255, 255, .14) !important; color: #fff !important;
}

/* The confirmation that a person has just been marked present. Large, brief,
   and impossible to miss from a step back. */
.kiosk-flash {
  position: fixed;
  left: 50%; bottom: 40px;
  transform: translateX(-50%);
  background: #2F6E57;
  color: #fff;
  padding: 20px 38px;
  border-radius: 999px;
  font-size: 22px;
  font-weight: 800;
  box-shadow: 0 16px 40px rgba(0, 0, 0, .4);
  z-index: 9999;
  animation: kioskPop .25s cubic-bezier(.32, .72, 0, 1);
  pointer-events: none;
}
@keyframes kioskPop {
  from { opacity: 0; transform: translateX(-50%) translateY(14px) scale(.94); }
  to   { opacity: 1; transform: translateX(-50%) translateY(0) scale(1); }
}

@media (max-width: 720px) {
  .kiosk { padding: 18px 14px 32px; }
  .kiosk-search { font-size: 21px !important; padding: 17px 18px; }
  .kiosk-results { grid-template-columns: 1fr; }
  .kiosk-top .kiosk-church { font-size: 18px; }
  .kiosk-count { flex: 1 1 calc(50% - 6px); min-width: 0; }
}

@media print { .kiosk { display: none; } }
