/* =====================================================================
 * Theodore Roosevelt Presidential Library — Donor Wall Kiosk
 * Stylesheet. Designed for a 3840 x 2160 horizontal touchscreen.
 * Sized in vw / vh so it scales gracefully if previewed on smaller
 * displays. The reference target is 4K landscape.
 *
 * Typography and color follow the TRPL Brand Identity System:
 *   - Dharma Gothic E:  display font, all caps, calls to action & titles
 *   - ITC Clearface:    secondary face, body copy and donor names
 *   - Color palette:    Night Sky / Dark Gray / Sand / Sunset accents
 * ===================================================================== */

/* ----- Brand fonts (loaded from /fonts) ------------------------------ */
@font-face {
  font-family: 'Dharma Gothic E';
  src: url('../fonts/Dharma%20Type%20-%20DharmaGothicE-Bold.otf') format('opentype');
  font-weight: 700;
  font-style: normal;
  font-display: block;
}
@font-face {
  font-family: 'Dharma Gothic E';
  src: url('../fonts/Dharma%20Type%20-%20DharmaGothicE-ExBold.otf') format('opentype');
  font-weight: 800;
  font-style: normal;
  font-display: block;
}
@font-face {
  font-family: 'ITC Clearface';
  src: url('../fonts/ClearfaceStd-Regular.otf') format('opentype');
  font-weight: 400;
  font-style: normal;
  font-display: block;
}
@font-face {
  font-family: 'ITC Clearface';
  src: url('../fonts/ClearfaceStd-Bold.otf') format('opentype');
  font-weight: 700;
  font-style: normal;
  font-display: block;
}
@font-face {
  font-family: 'ITC Clearface';
  src: url('../fonts/ClearfaceStd-Heavy.otf') format('opentype');
  font-weight: 800;
  font-style: normal;
  font-display: block;
}
@font-face {
  font-family: 'ITC Clearface';
  src: url('../fonts/ClearfaceStd-Black.otf') format('opentype');
  font-weight: 900;
  font-style: normal;
  font-display: block;
}
@font-face {
  font-family: 'ITC Clearface';
  src: url('../fonts/ClearfaceStd-Italic.otf') format('opentype');
  font-weight: 400;
  font-style: italic;
  font-display: block;
}

/* ----- Design tokens ------------------------------------------------- */
:root {
  /* Palette — drawn directly from the TRPL brand guidelines. */
  --c-night-sky:    #092A4D;   /* primary background blue */
  --c-dark-gray:    #25282A;   /* primary background gray */
  --c-dark-forest:  #1B4532;
  --c-sand:         #D1CCBD;   /* warm off-white grounding */
  --c-deep-orange:  #E7805D;
  --c-gray-sky:     #99ADC5;
  --c-sunset-pink:  #F36079;
  --c-sunset-orange:#FC924E;
  --c-sunset-yellow:#F9D635;
  --c-spring-green: #87BB41;
  --c-bright-forest:#8FC895;

  /* Warm gold accents — used as the kiosk's primary accent in place
     of Sunset Yellow. Sits comfortably alongside the brand palette
     and reads as a premium donor-recognition tone on the night sky. */
  --c-gold:         #D8B25A;
  --c-gold-bright:  #F0CD7A;

  /* Surfaces */
  --bg-deep:        #050810;                       /* deeper than Night Sky for the body fallback */
  --ink-primary:    var(--c-sand);                 /* body / donor names */
  --ink-secondary:  rgba(209, 204, 189, 0.85);
  --ink-muted:      rgba(209, 204, 189, 0.60);
  --accent:         var(--c-gold);                 /* society headings, CTA, focus, founder mark */
  --accent-warm:    var(--c-gold-bright);          /* lighter highlight / top-tier emphasis */
  --line:           rgba(216, 178, 90, 0.35);
  --rule:           rgba(209, 204, 189, 0.18);
  --card-bg:        rgba(9, 17, 32, 0.94);
  --card-border:    rgba(216, 178, 90, 0.40);
  --shadow:         0 0.6vw 2.4vw rgba(0, 0, 0, 0.55);

  /* Type families. Per brand: Dharma Gothic for display/headings only,
     all caps. Clearface for body and donor names. */
  --font-display: 'Dharma Gothic E', 'Trade Gothic Bold Condensed',
                  'Oswald', Impact, 'Arial Narrow Bold', sans-serif;
  --font-body:    'ITC Clearface', 'Iowan Old Style', 'Palatino Linotype',
                  Palatino, Georgia, 'Times New Roman', serif;

  /* Spatial scale, in vh / vw so layout scales with display dimensions.
     1 vh on the target = 21.6 px; 1 vw on the target = 38.4 px. */
  --pad-bottom: 1.85vh;   /* 40 px from bottom at 4K — required by spec */
  --pad-side:   1.04vw;   /* 40 px from left/right at 4K */
  --bar-height: 7.4vh;    /* ~160 px at 4K — height of search input pill,
                             also used by the corner brand-mark and legend */

  /* On-screen keyboard footprint. The keyboard is allowed to cover the
     Library building / horizon when it slides up. */
  --kb-height:  46vh;
  --kb-margin:  1.4vh;    /* gap between keyboard and search bar above it */
}

/* ----- Reset --------------------------------------------------------- */
*, *::before, *::after { box-sizing: border-box; }
html, body { margin: 0; padding: 0; height: 100%; }
body {
  font-family: var(--font-body);
  color: var(--ink-primary);
  background: var(--bg-deep);
  overflow: hidden;          /* the kiosk should never scroll the body */
  user-select: none;         /* no accidental text selection on touch */
  -webkit-user-select: none;
  -webkit-tap-highlight-color: transparent;
  /* For production kiosk, restore: cursor: none; (hidden during dev for testing) */
}
button {
  font: inherit;
  color: inherit;
  background: none;
  border: 0;
  padding: 0;
  cursor: pointer;
}
input { font: inherit; color: inherit; }
::-webkit-scrollbar { width: 0.6vw; height: 0.6vw; }
::-webkit-scrollbar-thumb { background: var(--line); border-radius: 0.4vw; }
::-webkit-scrollbar-track { background: transparent; }

/* ----- Root layout --------------------------------------------------- */
#kiosk {
  position: fixed;
  inset: 0;
  overflow: hidden;
}

#background {
  position: absolute;
  inset: 0;
  background-image: url("../image/night-sky.jpg");
  background-size: cover;
  background-position: center bottom;
  z-index: 0;
  /* Subtle ken-burns-style drift to keep the image alive and reduce the
     risk of static-pixel burn-in. 60s cycle, very small movement. */
  animation: bg-drift 60s ease-in-out infinite alternate;
}
@keyframes bg-drift {
  0%   { transform: scale(1.02) translate(-0.4%,  0.2%); }
  100% { transform: scale(1.04) translate( 0.4%, -0.2%); }
}

/* All three screens stack at the same position. Layout is always live
   (visibility-based show/hide rather than display) so flipping between
   states is paint-only — no 10K-row relayout cost on CTA tap. The
   per-screen display values below establish the desired flex/block
   layout exactly once, during boot. */
.screen {
  position: absolute;
  inset: 0;
  z-index: 1;
  visibility: hidden;
  pointer-events: none;
}
#loading-screen { display: flex; align-items: center; justify-content: center; }
#attract-screen { display: block; }
#browse-screen  { display: block; }

#kiosk[data-state="loading"]  #loading-screen,
#kiosk[data-state="attract"]  #attract-screen,
#kiosk[data-state="browse"]   #browse-screen {
  visibility: visible;
  pointer-events: auto;
}

/* ----- Loading screen — intentionally blank; progress bar at top
   communicates progress. ------------------------------------------------ */
#loading-screen {}

/* ----- Top progress bar --------------------------------------------- */
#progress-bar {
  position: absolute;
  top: 0; left: 0; right: 0;
  height: 0.4vh;                    /* ~9 px on 4K */
  z-index: 50;
  background: rgba(216, 178, 90, 0.10);
  transition: opacity 500ms ease 200ms;
  pointer-events: none;
}
#progress-bar .bar-fill {
  height: 100%;
  width: 0%;
  background: var(--accent);
  box-shadow: 0 0 0.8vw rgba(216, 178, 90, 0.7);
  transition: width 180ms ease-out;
}
#progress-bar.is-done { opacity: 0; }

/* =====================================================================
 *  ATTRACT MODE
 * ===================================================================== */

#attract-screen {
  --upper-region-end: 40%;   /* names live above this line — pure sky;
                                the gratitude message sits below them */
}

#attract-stage {
  position: absolute;
  inset: 0 0 auto 0;
  height: var(--upper-region-end);
  pointer-events: none;
  overflow: hidden;
}

/* Each donor name is positioned absolutely inside the stage. */
.attract-name {
  position: absolute;
  font-family: var(--font-body);
  font-weight: 400;
  color: var(--ink-primary);
  text-align: center;
  white-space: nowrap;
  letter-spacing: 0.02em;
  text-shadow:
    0 0 1.2vw rgba(209, 204, 189, 0.35),
    0 0 0.4vw rgba(209, 204, 189, 0.55);
  opacity: 0;
  transform: translate(-50%, -50%);
  animation: name-life 7000ms ease-in-out forwards;
  will-change: opacity, transform;
}
@keyframes name-life {
  0%   { opacity: 0; transform: translate(-50%, -50%) scale(0.94); }
  18%  { opacity: 1; transform: translate(-50%, -50%) scale(1.00); }
  78%  { opacity: 1; transform: translate(-50%, -50%) scale(1.02); }
  100% { opacity: 0; transform: translate(-50%, -50%) scale(1.04); }
}
.attract-name.tier-top {
  font-size: 3.8vh;
  font-weight: 800;
  color: var(--accent-warm);            /* gold-bright — top-tier emphasis */
  letter-spacing: 0.01em;
  text-shadow:
    0 0 1.8vw rgba(240, 205, 122, 0.55),
    0 0 0.6vw rgba(240, 205, 122, 0.65);
}
.attract-name.tier-major {
  font-size: 3.0vh;
  font-weight: 700;
  color: var(--accent);                 /* gold */
  text-shadow:
    0 0 1.4vw rgba(216, 178, 90, 0.42),
    0 0 0.4vw rgba(216, 178, 90, 0.55);
}
.attract-name.tier-mid {
  font-size: 2.4vh;
  color: var(--ink-primary);
}
.attract-name.tier-base {
  font-size: 1.9vh;
  color: var(--ink-secondary);
}

.attract-name .founder-mark {
  display: inline-block;
  margin-right: 0.4em;
  color: var(--accent);
  text-shadow: 0 0 0.6vw rgba(216, 178, 90, 0.9);
}

/* Gratitude message — centered between the drifting names and the CTA. */
#attract-message {
  position: absolute;
  left: 50%;
  top: 46%;
  transform: translate(-50%, -50%);
  width: 80%;
  text-align: center;
  z-index: 2;
  pointer-events: none;
}
.attract-eyebrow {
  font-family: var(--font-display);
  font-weight: 700;
  font-size: 3.0vh;
  letter-spacing: 0.40em;
  text-transform: uppercase;
  color: var(--ink-secondary);
  margin: 0 0 0.4vh 0;
  text-indent: 0.40em;        /* balance the trailing letter-spacing */
}
.attract-headline {
  font-family: var(--font-display);
  font-weight: 800;
  font-size: 11vh;
  line-height: 0.96;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--c-sand);
  margin: 0;
  text-shadow: 0 0 2.2vw rgba(0, 0, 0, 0.45);
}
.attract-tagline {
  font-family: var(--font-body);
  font-style: italic;
  font-size: 2.7vh;
  line-height: 1.4;
  color: var(--ink-secondary);
  white-space: nowrap;        /* one line on the 4K target */
  margin: 2.0vh auto 0 auto;
}
.attract-recognizing {
  font-family: var(--font-body);     /* ITC Clearface — "Proudly Recognizing Our" */
  font-weight: 400;
  font-size: 1.8vh;
  line-height: 1.55;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--ink-secondary);
  text-indent: 0.18em;
  margin: 2.6vh 0 0 0;
}
/* "Benefactor Society Members" — Dharma display, a little larger. */
.attract-recognizing .attract-society-line {
  display: inline-block;
  font-family: var(--font-display);
  font-weight: 700;
  font-size: 2.9vh;
  letter-spacing: 0.10em;
  text-indent: 0.10em;
  color: var(--ink-secondary);
  margin-top: 0.8vh;
}

/* CTA pinned 40 px from the bottom (== 1.85vh on 4K). */
#attract-cta-wrap {
  position: absolute;
  left: 0; right: 0;
  bottom: var(--pad-bottom);
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 1.0vh;
  z-index: 2;
}
.cta-primary {
  font-family: var(--font-display);
  font-weight: 800;          /* Dharma Gothic E ExBold */
  font-size: 3.4vh;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  white-space: nowrap;
  padding: 1.5vh 4.0vw;
  border-radius: 999px;
  border: 0.18vh solid var(--accent);
  background: rgba(9, 17, 32, 0.60);
  color: var(--accent);
  backdrop-filter: blur(0.6vw);
  -webkit-backdrop-filter: blur(0.6vw);
  box-shadow:
    0 0 1.6vw rgba(216, 178, 90, 0.30),
    inset 0 0 0.8vw rgba(216, 178, 90, 0.16);
  animation: cta-pulse 4.2s ease-in-out infinite;
  transition: transform 120ms ease, background 120ms ease;
}
.cta-primary:active {
  transform: scale(0.98);
  background: rgba(216, 178, 90, 0.20);
}
@keyframes cta-pulse {
  0%, 100% {
    box-shadow:
      0 0 1.6vw rgba(216, 178, 90, 0.28),
      inset 0 0 0.8vw rgba(216, 178, 90, 0.16);
  }
  50% {
    box-shadow:
      0 0 2.6vw rgba(216, 178, 90, 0.58),
      inset 0 0 1.2vw rgba(216, 178, 90, 0.30);
  }
}
/* (Attract-mode CTA stands on its own — no subtitle below it.) */

/* =====================================================================
 *  BROWSE MODE
 *
 *  The donor list lives in the upper "sky" portion of the background
 *  photograph. The Library building silhouette and horizon glow stay
 *  visible underneath. Search is pinned to the baseline (40px above
 *  the bottom edge), matching the Attract-mode CTA position.
 * ===================================================================== */

#browse-screen {
  /* Full-bleed; no flex layout — children are absolutely positioned. */
}

/* Benefactor list panel — clipped to the upper sky region. The
   internal left/right padding is intentionally generous: those rails
   are part of the scrollable surface but contain no rows, so visitors
   can press there to drag the list without accidentally tapping a
   benefactor row and triggering the detail card. */
/* ----- Browse top bar: Home control + screen title ------------------ */
#browse-topbar {
  position: absolute;
  top: var(--pad-bottom);
  left: 4vw;
  right: 4vw;
  height: 6vh;
  display: flex;
  align-items: center;
  gap: 2vw;
  z-index: 5;
}
.browse-home {
  display: inline-flex;
  align-items: center;
  gap: 0.3vw;
  font-family: var(--font-display);
  font-weight: 700;
  font-size: 2.2vh;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--ink-secondary);
  padding: 0.8vh 1.6vw 0.8vh 1.1vw;
  border: 0.14vh solid var(--line);
  border-radius: 999px;
  background: rgba(9, 17, 32, 0.55);
}
.browse-home:active { color: var(--accent); border-color: var(--accent); background: rgba(216,178,90,0.16); }
.browse-home .home-glyph { font-size: 3.0vh; line-height: 0; transform: translateY(-0.1vh); }
#browse-title {
  font-family: var(--font-display);
  font-weight: 800;
  font-size: 3.2vh;
  letter-spacing: 0.10em;
  text-transform: uppercase;
  color: var(--c-sand);
  margin: 0;
}

/* ----- Level filter: All Levels + one chip per society -------------- */
#level-filter {
  position: absolute;
  top: 9vh;
  left: 4vw;
  right: 4vw;
  z-index: 5;
  display: flex;
  flex-wrap: wrap;
  gap: 0.7vw 0.7vw;
}
.level-chip {
  font-family: var(--font-display);
  font-weight: 700;
  font-size: 1.85vh;
  letter-spacing: 0.10em;
  text-transform: uppercase;
  color: var(--ink-secondary);
  padding: 0.85vh 1.4vw;
  border: 0.14vh solid var(--line);
  border-radius: 999px;
  background: rgba(9, 17, 32, 0.45);
  white-space: nowrap;
  transition: color 120ms ease, background 120ms ease, border-color 120ms ease;
}
.level-chip:active { transform: scale(0.98); }
.level-chip.is-active {
  color: #0a0d18;
  background: var(--accent);
  border-color: var(--accent);
}

/* ----- A–Z "Find Your Name" index, pinned to the right edge ---------
   Two columns (All/#/A–L and M–Z) so every key is a comfortable touch
   target (≥ ~100 px tall × ~110 px wide at 4K), well above the 88 px
   minimum. */
#alpha-index {
  position: absolute;
  top: 20vh;
  bottom: 11vh;
  right: 0.8vw;
  width: 6.6vw;
  z-index: 5;
  display: grid;
  grid-auto-flow: column;
  grid-template-rows: repeat(14, 1fr);
  grid-template-columns: 1fr 1fr;
  gap: 0.3vh 0.4vw;
}
.alpha-key {
  min-height: 0;
  font-family: var(--font-display);
  font-weight: 700;
  font-size: 2.4vh;
  letter-spacing: 0.04em;
  color: var(--ink-secondary);
  background: rgba(9, 17, 32, 0.45);
  border: 0.12vh solid var(--line);
  border-radius: 0.5vw;
  display: flex;
  align-items: center;
  justify-content: center;
  transition: color 100ms ease, background 100ms ease, border-color 100ms ease;
}
.alpha-key[data-letter="all"] { font-size: 1.5vh; letter-spacing: 0.10em; }
.alpha-key:active { background: rgba(216, 178, 90, 0.20); }
.alpha-key.is-active {
  color: #0a0d18;
  background: var(--accent);
  border-color: var(--accent);
}

#donor-list-panel {
  position: absolute;
  top: 20vh;
  left: 4vw;
  right: 9vw;              /* clear the two-column A–Z index on the right */
  bottom: 11vh;            /* clear the wordmark / donate QR corners */
  overflow-y: auto;
  scroll-behavior: smooth;
  -webkit-overflow-scrolling: touch;
  padding: 2vh 5vw 4vh 5vw;
  transition: bottom 240ms ease;
  /* Dark scrim behind the list so Sand-colored names stay legible where
     the list overlaps the bright sunset horizon. The scrim is anchored to
     the panel (a scroll container's background doesn't scroll with its
     content) and deepens toward the bottom, where the glow is strongest. */
  background:
    linear-gradient(to bottom,
      rgba(5, 9, 16, 0.00) 0%,
      rgba(5, 9, 16, 0.34) 24%,
      rgba(5, 9, 16, 0.60) 64%,
      rgba(5, 9, 16, 0.82) 100%);
  border-radius: 1.4vw;
  /* Soft fade at top + bottom so list content doesn't hard-cut into
     either the screen edge or the horizon below. */
  -webkit-mask-image: linear-gradient(to bottom,
    transparent 0%, black 6%, black 92%, transparent 100%);
          mask-image: linear-gradient(to bottom,
    transparent 0%, black 6%, black 92%, transparent 100%);
}

/* When the on-screen keyboard is open, raise the bottom edge so the
   panel sits above the search bar (which itself sits above the keyboard). */
#kiosk.kb-open #donor-list-panel {
  bottom: calc(var(--kb-height) + var(--bar-height) + var(--kb-margin) + var(--pad-bottom));
}

/* ----- Scroll hint --------------------------------------------------
   Right-aligned tooltip just below the benefactor-list panel. The icon
   is image/scrolling.png used as a CSS mask so we can paint it in the
   accent gold; a subtle vertical bob suggests interactivity. */
#scroll-hint {
  position: absolute;
  top: 52vh;                        /* just below the benefactor-list panel */
  right: 6vw;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.9vh;
  z-index: 4;
  pointer-events: none;
  opacity: 0;
  transition: opacity 600ms ease;
}
#scroll-hint.is-visible { opacity: 1; }
#kiosk.kb-open #scroll-hint {
  opacity: 0 !important;
  transition: opacity 200ms ease;
}
.scroll-hint-icon {
  display: block;
  width: 4.34vh;       /* 30% smaller — 70% of the original 6.2vh */
  height: 4.34vh;
  background-color: var(--accent);
  -webkit-mask-image: url('../image/scrolling.png');
          mask-image: url('../image/scrolling.png');
  -webkit-mask-size: contain;
          mask-size: contain;
  -webkit-mask-repeat: no-repeat;
          mask-repeat: no-repeat;
  -webkit-mask-position: center;
          mask-position: center;
  filter: drop-shadow(0 0.2vh 0.4vw rgba(0, 0, 0, 0.55));
  animation: scroll-hint-bob 1.7s ease-in-out infinite;
}
@keyframes scroll-hint-bob {
  0%, 100% { transform: translateY(2px); }
  50%      { transform: translateY(-8px); }
}
.scroll-hint-text {
  font-family: var(--font-display);
  font-weight: 700;
  font-size: 1.6vh;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  color: var(--ink-secondary);
  text-shadow: 0 0.2vh 0.6vw rgba(0, 0, 0, 0.55);
}

.search-row {
  position: relative;
  display: flex;
  align-items: center;
}
.search-input {
  width: 100%;
  height: var(--bar-height);
  padding: 0 2.4vw;
  font-family: var(--font-body);
  font-weight: 400;
  font-size: 2.8vh;
  letter-spacing: 0.01em;
  color: var(--ink-primary);
  background: rgba(9, 17, 32, 0.78);
  border: 0.16vh solid var(--line);
  border-radius: 999px;
  outline: none;
  caret-color: var(--accent);
  backdrop-filter: blur(0.6vw);
  -webkit-backdrop-filter: blur(0.6vw);
}
.search-input::placeholder { color: var(--ink-muted); font-style: italic; }
.search-input:focus {
  border-color: var(--accent);
  box-shadow: 0 0 0 0.3vh rgba(216, 178, 90, 0.20);
}
/* Belt-and-suspenders: kill any browser-rendered clear/decoration
   glyphs inside the input so they can never overlap our custom × button. */
.search-input::-webkit-search-cancel-button,
.search-input::-webkit-search-decoration,
.search-input::-webkit-search-results-button,
.search-input::-webkit-search-results-decoration {
  -webkit-appearance: none;
  appearance: none;
  display: none;
}
.search-input::-ms-clear,
.search-input::-ms-reveal {
  display: none;
  width: 0; height: 0;
}
.search-clear {
  position: absolute;
  right: 1.0vw;
  width: 4.8vh;
  height: 4.8vh;
  font-size: 3.0vh;
  color: var(--ink-muted);
  display: none;
  align-items: center;
  justify-content: center;
  border-radius: 50%;
}
.search-clear.is-visible { display: flex; }
.search-clear:active { color: var(--accent); background: rgba(216, 178, 90, 0.15); }

/* Search bar pinned to the baseline (40 px = 1.85vh from bottom).
   We reserve 28vw of clearance on each side so the bottom-corner UI
   (wordmark, donate-qr) can never collide with the search input. */
#search-bar {
  position: absolute;
  left: 28vw;
  right: 28vw;
  bottom: var(--pad-bottom);
  display: flex;
  justify-content: center;
  pointer-events: none;       /* let the children own pointer events */
  transition: bottom 240ms ease, left 240ms ease, right 240ms ease;
}
#search-bar > .search-row {
  width: 100%;
  max-width: 1400px;
  pointer-events: auto;
}

/* Keyboard open: float search bar up to sit just above the keyboard,
   and let it span more of the width since wordmark / QR are hidden. */
#kiosk.kb-open #search-bar {
  bottom: calc(var(--kb-height) + var(--kb-margin));
  left: 8vw;
  right: 8vw;
}

/* (No "Done" button on the browse screen — the 2-minute idle timeout
   handles the return to attract mode automatically.) */

/* Society section */
.society-section { margin: 0 0 3.5vh 0; }
.society-section.is-empty { display: none; }
/* Used during the 12-hour auto-reload: replacement sections are built
   alongside the visible ones but hidden until the atomic swap. */
.society-section.is-pending { display: none; }

.society-heading {
  display: flex;
  align-items: baseline;
  gap: 1.5vw;
  padding-bottom: 0.8vh;
  margin: 0 0 1.4vh 0;
  border-bottom: 1px solid var(--line);
}
.society-name {
  font-family: var(--font-display);
  font-weight: 800;        /* Dharma Gothic E ExBold */
  font-size: 3.6vh;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--accent);
  margin: 0;
  line-height: 1.0;
}
.society-threshold {
  font-family: var(--font-display);
  font-weight: 700;
  font-size: 1.8vh;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--accent);
}
.society-count {
  font-family: var(--font-display);
  font-weight: 700;
  font-size: 1.6vh;
  letter-spacing: 0.20em;
  text-transform: uppercase;
  color: var(--ink-muted);
  margin-left: auto;        /* push the count to the right of the heading */
}

/* Anonymous benefactors render in soft italics within their tier. */
.donor-row.is-anonymous .donor-name {
  font-style: italic;
  color: var(--ink-muted);
}

/* Donor grid: column flow keeps alphabetical order top-to-bottom,
   then left-to-right. Column widths grow with the screen. */
.donor-grid {
  column-count: 4;
  column-gap: 3vw;
  column-rule: 1px solid var(--rule);
}

.donor-row {
  display: flex;
  align-items: baseline;
  gap: 0.6vw;
  padding: 0.55vh 0;
  font-family: var(--font-body);
  font-size: 1.7vh;
  color: var(--ink-primary);
  break-inside: avoid;
  line-height: 1.25;
  border-bottom: 1px dotted transparent;
  transition: color 120ms ease, background 120ms ease;
}
/* Names are display-only in v2 (no detail card), so no press affordance.
   The drop shadow keeps Sand-colored names readable anywhere they land,
   including over the brightest part of the sunset horizon. */
.donor-row .donor-name {
  flex: 1 1 auto;
  white-space: normal;
  text-shadow:
    0 0.15vh 0.45vh rgba(0, 0, 0, 0.85),
    0 0 0.9vh rgba(0, 0, 0, 0.55);
}

/* Tier-driven type sizes: big donors get larger names. */
.donor-grid.tier-foundational .donor-row { font-size: 2.5vh; }
.donor-grid.tier-keystone     .donor-row { font-size: 2.3vh; }
.donor-grid.tier-principal    .donor-row { font-size: 2.1vh; }
.donor-grid.tier-club26       .donor-row { font-size: 2.0vh; }
.donor-grid.tier-leadership   .donor-row { font-size: 1.9vh; }
/* The very large bottom tiers use more columns to fit thousands of names. */
.donor-grid.tier-vp,
.donor-grid.tier-governor,
.donor-grid.tier-founding,
.donor-grid.tier-supporter    { column-count: 6; }
.donor-grid.tier-vp           .donor-row,
.donor-grid.tier-governor     .donor-row,
.donor-grid.tier-founding     .donor-row,
.donor-grid.tier-supporter    .donor-row { font-size: 1.45vh; }

/* Override column count at section level so the "tier-..." class on the
   grid wins over the default. */
.donor-grid.tier-foundational  { column-count: 2; }
.donor-grid.tier-keystone      { column-count: 3; }
.donor-grid.tier-principal     { column-count: 3; }
.donor-grid.tier-club26        { column-count: 4; }

.no-results {
  text-align: center;
  font-family: var(--font-body);
  font-size: 2.2vh;
  color: var(--ink-muted);
  margin: 6vh 0;
}

/* =====================================================================
 *  CORNER & TOP UI
 *    top-center   — Founding Benefactor legend (key for the gold ★)
 *    bottom-left  — TRPL wordmark
 *    bottom-right — Donate QR + invitation to join the roster
 *
 *  All three are persistent across attract and browse states. They
 *  read as a clean rectangular frame around the active content.
 * ===================================================================== */

#brand-mark,
#donate-qr,
#legend-founder {
  position: absolute;
  z-index: 3;
  pointer-events: none;     /* purely decorative — visitors scan with phones */
  display: flex;
  align-items: center;
}

/* --- TRPL wordmark — bottom-left, baseline aligned to search bar --- */
#brand-mark {
  left: var(--pad-side);
  bottom: var(--pad-bottom);
  height: var(--bar-height);
  /* Generous interior padding (≈10% per side, 20% total) so the logo
     has visible breathing room within its baseline-aligned block. */
  padding: 0.74vh 0.6vw;
  box-sizing: border-box;
}
#brand-mark img {
  height: 100%;
  width: auto;
  display: block;
  filter: drop-shadow(0 0.2vh 0.6vw rgba(0, 0, 0, 0.55));
}

/* --- Donate QR + caption — bottom-right, baseline aligned -------- */
#donate-qr {
  right: var(--pad-side);
  bottom: var(--pad-bottom);
  height: var(--bar-height);
  gap: 0.7vw;
}
#donate-qr .qr-card {
  height: 100%;
  aspect-ratio: 1 / 1;
  background: #FFFFFF;
  border-radius: 0.4vw;
  padding: 0.5vh;
  box-sizing: border-box;
  box-shadow: 0 0.2vh 0.6vw rgba(0, 0, 0, 0.45);
  flex: 0 0 auto;
}
#donate-qr .qr-card img {
  width: 100%;
  height: 100%;
  display: block;
}
#donate-qr .donate-caption {
  display: flex;
  flex-direction: column;
  justify-content: center;
  gap: 0.6vh;
  text-align: right;
}
#donate-qr .donate-title {
  font-family: var(--font-display);
  font-weight: 800;
  font-size: 2.2vh;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--accent);
  line-height: 1;
}
#donate-qr .donate-subtitle {
  font-family: var(--font-body);
  font-style: italic;
  font-size: 1.5vh;
  color: var(--ink-muted);
  line-height: 1;
  letter-spacing: 0.02em;
}

/* --- Founding Benefactor legend — top-center, key for the gold ★ - */
#legend-founder {
  top: var(--pad-bottom);
  left: 50%;
  transform: translateX(-50%);
  gap: 0.7vw;
  padding: 0.4vh 1.4vw;
  font-family: var(--font-display);
  font-weight: 700;
  font-size: 1.7vh;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  color: var(--ink-secondary);
  background: rgba(9, 17, 32, 0.40);
  border-radius: 999px;
  backdrop-filter: blur(0.4vw);
  -webkit-backdrop-filter: blur(0.4vw);
}
#legend-founder .legend-glyph {
  font-size: 2.6vh;
  color: var(--accent);
  text-shadow: 0 0 0.6vw rgba(216, 178, 90, 0.85);
  line-height: 1;
}
#legend-founder .legend-text {
  display: inline-block;
}

/* Hide all corner UI (and progress bar fades to attract) during loading. */
#kiosk[data-state="loading"] #brand-mark,
#kiosk[data-state="loading"] #donate-qr,
#kiosk[data-state="loading"] #legend-founder {
  display: none;
}

/* Wordmark + donate-QR fade out while the keyboard is up — the
   keyboard takes their footprint, and they'd visually compete
   with the floated search bar. The legend at top-center stays. */
#brand-mark,
#donate-qr {
  transition: opacity 200ms ease;
}
#kiosk.kb-open #brand-mark,
#kiosk.kb-open #donate-qr {
  opacity: 0;
  pointer-events: none;
}

/* =====================================================================
 *  ON-SCREEN VIRTUAL KEYBOARD
 *
 *  Slides up from the bottom when the search field is tapped. While
 *  open it is allowed to cover the Library building / horizon in the
 *  background photograph. Keys are touch-friendly (≥120 px tall at 4K)
 *  and laid out as a standard QWERTY with numbers above and a wide
 *  space bar below.
 * ===================================================================== */

#keyboard {
  position: absolute;
  left: 0; right: 0;
  bottom: 0;
  height: var(--kb-height);
  padding: 1.4vh 1.6vw;
  background: rgba(5, 9, 17, 0.92);
  border-top: 0.14vh solid var(--rule);
  box-shadow: 0 -0.6vh 2.4vw rgba(0, 0, 0, 0.55);
  backdrop-filter: blur(0.8vw);
  -webkit-backdrop-filter: blur(0.8vw);
  transform: translateY(102%);     /* fully off-screen by default */
  transition: transform 240ms ease;
  z-index: 20;
  display: flex;
  flex-direction: column;
  gap: 0.7vh;
  visibility: hidden;
  pointer-events: none;
}
#kiosk.kb-open #keyboard {
  transform: translateY(0);
  visibility: visible;
  pointer-events: auto;
}

.kb-row {
  display: flex;
  gap: 0.5vw;
  flex: 1 1 auto;
}

.kb-key {
  flex: 1 1 0;
  height: 100%;
  font-family: var(--font-body);
  font-weight: 700;
  font-size: 3.6vh;
  line-height: 1;
  color: var(--ink-primary);
  background: rgba(20, 28, 42, 0.85);
  border: 0.14vh solid rgba(216, 178, 90, 0.18);
  border-radius: 0.6vw;
  padding: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  text-transform: lowercase;
  transition: background 80ms ease, color 80ms ease, border-color 80ms ease, transform 80ms ease;
  -webkit-tap-highlight-color: transparent;
}
.kb-key:active {
  background: var(--accent);
  color: #0a0d18;
  border-color: var(--accent);
  transform: scale(0.97);
}
/* Letters render uppercase visually when shift is on. */
#keyboard.is-shift .kb-key:not(.kb-key--special) { text-transform: uppercase; }

/* Special keys — Dharma small caps, gold accent. */
.kb-key--special {
  font-family: var(--font-display);
  font-weight: 800;
  font-size: 2.6vh;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--accent);
  background: rgba(20, 28, 42, 0.65);
  border-color: rgba(216, 178, 90, 0.30);
}
.kb-key--shift,
.kb-key--backspace {
  font-family: var(--font-body);
  font-size: 3.4vh;
  letter-spacing: 0;
  text-transform: none;
}
.kb-key--shift.is-active {
  background: rgba(216, 178, 90, 0.30);
  color: var(--accent-warm);
  border-color: var(--accent);
}
.kb-key--space {
  font-family: var(--font-display);
  font-weight: 700;
  font-size: 2.0vh;
  letter-spacing: 0.20em;
  text-transform: uppercase;
  color: var(--ink-secondary);
}
.kb-key--done {
  background: rgba(216, 178, 90, 0.18);
  color: var(--accent);
  border-color: var(--accent);
}
.kb-key--done:active {
  background: var(--accent);
  color: #0a0d18;
}

/* =====================================================================
 *  DETAIL CARD
 * ===================================================================== */

.detail-overlay {
  position: absolute;
  inset: 0;
  display: none;
  align-items: center;
  justify-content: center;
  background: rgba(2, 4, 10, 0.55);
  backdrop-filter: blur(0.8vw);
  -webkit-backdrop-filter: blur(0.8vw);
  z-index: 10;
}
.detail-overlay.is-open { display: flex; }
.detail-card {
  position: relative;
  width: 50vw;
  max-width: 1100px;
  padding: 5vh 5vw 5vh 5vw;
  background: var(--card-bg);
  border: 0.18vh solid var(--card-border);
  border-radius: 1.2vw;
  box-shadow: var(--shadow);
  animation: card-in 220ms ease forwards;
}
@keyframes card-in {
  0%   { opacity: 0; transform: translateY(2vh) scale(0.985); }
  100% { opacity: 1; transform: translateY(0)   scale(1.000); }
}
.detail-close {
  position: absolute;
  top: 1.2vh;
  right: 1.0vw;
  width: 5vh;
  height: 5vh;
  font-size: 4vh;
  line-height: 1;
  color: var(--ink-muted);
  border-radius: 50%;
}
.detail-close:active {
  color: var(--accent);
  background: rgba(216, 178, 90, 0.15);
}
.detail-society-tag {
  font-family: var(--font-display);
  font-weight: 800;
  font-size: 2.0vh;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--accent);
  margin-bottom: 1.6vh;
}
.detail-name {
  font-family: var(--font-body);
  font-weight: 700;          /* Clearface Bold */
  font-size: 4.6vh;
  letter-spacing: 0.01em;
  margin: 0 0 1.0vh 0;
  color: var(--ink-primary);
  line-height: 1.1;
}
.detail-name .founder-mark {
  color: var(--accent);
  margin-right: 0.4em;
  font-size: 0.7em;
  vertical-align: 0.2em;
}
.detail-location {
  font-family: var(--font-body);
  font-style: italic;
  font-size: 2.0vh;
  color: var(--ink-secondary);
  margin: 0 0 2.4vh 0;
  letter-spacing: 0.02em;
}
.detail-bio {
  font-family: var(--font-body);
  font-weight: 400;
  font-size: 2.2vh;
  line-height: 1.55;
  color: var(--ink-primary);
  margin: 0;
}
.detail-bio:empty { display: none; }
