/* ============================================================
   Museum of Osteology — shared kiosk design system + shell
   Import this on every kiosk screen:  <link rel="stylesheet" href="kiosk.css">
   Matches the live Visitor Origins globe (map.skeletonmuseum.com).
   ============================================================ */
:root {
  --ink:   #07090d;
  --ink2:  #0d1118;
  --ink3:  #12171f;
  --bone:  #ece4d2;
  --dim:   #9d968a;
  --brass: #d9a441;
  --brass-lt:#f2d999;
  --brass2:#8a6a2e;
  --line:  rgba(217,164,65,.28);
  --line-soft: rgba(236,228,210,.10);
  --danger:#c2543f;
  --ok:    #6f9e6b;
  --font-display: 'Fraunces', Georgia, serif;
  --font-ui: 'IBM Plex Mono', 'Consolas', monospace;
  --shadow: 0 24px 60px rgba(0,0,0,.55);
  --ease: cubic-bezier(.22,.61,.36,1);
}

* { margin:0; padding:0; box-sizing:border-box; -webkit-tap-highlight-color:transparent; touch-action:manipulation; }
html, body { height:100%; overflow:hidden; }
body {
  /* longhands (not inset:) so old iPad Safari shrink-wraps correctly */
  position:fixed; top:0; right:0; bottom:0; left:0;
  overscroll-behavior:none; -webkit-user-select:none; user-select:none;
  background:var(--ink); color:var(--bone); font-family:var(--font-ui);
  -webkit-font-smoothing:antialiased;
}
body::before { /* shared atmosphere */
  content:''; position:fixed; top:0; right:0; bottom:0; left:0; pointer-events:none; z-index:0;
  background:
    radial-gradient(ellipse 90% 65% at 32% 38%, rgba(40,58,92,.34), transparent 62%),
    radial-gradient(ellipse 70% 60% at 88% 82%, rgba(217,164,65,.06), transparent 60%),
    radial-gradient(ellipse 120% 100% at 50% 50%, transparent 52%, rgba(0,0,0,.6));
}
body::after { /* faint film grain for depth */
  content:''; position:fixed; top:0; right:0; bottom:0; left:0; pointer-events:none; z-index:0; opacity:.035;
  background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='140' height='140'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='2'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E");
}

/* ---- entrance motion (add class to your top container) ---- */
@keyframes k-rise { from { opacity:0; transform:translateY(14px); } to { opacity:1; transform:none; } }
.k-rise { animation:k-rise .6s var(--ease) both; }
.k-rise-2 { animation:k-rise .6s var(--ease) .08s both; }
.k-rise-3 { animation:k-rise .6s var(--ease) .16s both; }

/* ---- type ---- */
.k-kicker { font-size:11px; letter-spacing:.42em; text-transform:uppercase; color:var(--brass); }
.k-display { font-family:var(--font-display); font-weight:380; }

/* ---- buttons ---- */
.k-btn {
  position:relative; font-family:var(--font-ui); font-weight:600; letter-spacing:.28em; text-transform:uppercase;
  color:#2a1e07; background:linear-gradient(180deg,var(--brass-lt),var(--brass) 60%,#c69433);
  border:none; border-radius:4px; cursor:pointer; padding:18px 30px; font-size:14px;
  box-shadow:0 10px 26px rgba(217,164,65,.24), inset 0 1px 0 rgba(255,255,255,.4);
  transition:transform .1s var(--ease), box-shadow .2s var(--ease), filter .2s;
}
.k-btn:hover { box-shadow:0 16px 34px rgba(217,164,65,.34), inset 0 1px 0 rgba(255,255,255,.5); filter:brightness(1.04); }
.k-btn:active { transform:scale(.97); }
.k-btn.ghost { background:none; color:var(--brass); border:1px solid var(--line); box-shadow:none; }
.k-btn.ghost:hover { background:rgba(217,164,65,.08); border-color:var(--brass); }

/* ---- concept-mockup ribbon (remove for production) ---- */
.k-ribbon {
  position:fixed; top:18px; left:-54px; z-index:60; transform:rotate(-45deg);
  background:linear-gradient(180deg,#d15f4a,var(--danger)); color:#fff; font-size:10px; letter-spacing:.24em; font-weight:600;
  padding:6px 60px; box-shadow:0 4px 14px rgba(0,0,0,.45);
}

/* ---- idle "attract" veil (shown by kiosk.js after inactivity) ---- */
#k-attract {
  position:fixed; top:0; right:0; bottom:0; left:0; z-index:70;
  display:none; align-items:center; justify-content:center; flex-direction:column; gap:26px;
  background:radial-gradient(ellipse at center, rgba(13,18,26,.90), rgba(7,9,13,.97)); cursor:pointer; text-align:center;
}
#k-attract.show { display:flex; animation:k-fade .5s var(--ease) both; }
@keyframes k-fade { from { opacity:0 } to { opacity:1 } }
#k-attract .glyph { font-size:64px; filter:drop-shadow(0 0 24px rgba(217,164,65,.4)); animation:k-float 4s ease-in-out infinite; }
@keyframes k-float { 0%,100%{ transform:translateY(0) } 50%{ transform:translateY(-10px) } }
#k-attract .big { font-family:var(--font-display); font-style:italic; font-size:clamp(34px,6vh,60px); }
#k-attract .tap { font-size:12px; letter-spacing:.34em; text-transform:uppercase; color:var(--brass); animation:kpulse 1.8s ease-in-out infinite; }
@keyframes kpulse { 0%,100%{opacity:.4} 50%{opacity:1} }

/* ---- boot spinner ---- */
#k-boot {
  position:fixed; top:0; right:0; bottom:0; left:0; z-index:80;
  display:flex; align-items:center; justify-content:center; flex-direction:column; gap:18px;
  background:radial-gradient(ellipse at center, var(--ink2), var(--ink)); transition:opacity .6s var(--ease);
}
#k-boot.gone { opacity:0; pointer-events:none; }
#k-boot .ring { width:52px; height:52px; border-radius:50%; border:2px solid var(--line); border-top-color:var(--brass);
  animation:kspin 1s linear infinite; box-shadow:0 0 30px rgba(217,164,65,.25); }
#k-boot .bl { font-size:10px; letter-spacing:.4em; text-transform:uppercase; color:var(--dim); }
@keyframes kspin { to { transform:rotate(360deg); } }

/* scrollbars (webkit) — slim, on-brand */
::-webkit-scrollbar { width:8px; height:8px; }
::-webkit-scrollbar-thumb { background:rgba(217,164,65,.28); border-radius:4px; }
::-webkit-scrollbar-track { background:transparent; }

/* ============================================================
   KIOSK-DISTANCE LEGIBILITY + TOUCH
   ------------------------------------------------------------
   A standing 13" panel is read from ~60cm, not 30cm, through smudged glass in
   bright gallery light. Baseline measured 32px-tall species chips and 39px
   period buttons — below the 44pt HIG floor and well below what a child
   reliably hits. These are floors, applied globally so a new control cannot
   ship under-size by omission.
   ============================================================ */
button, a[href], [role="button"], input, select, summary, label.k-tap {
  min-height: 44px;
  min-width: 44px;
}
/* Inline chips inside prose keep their look but gain a hit area. */
.k-chip, .pseg, .opt, .k-swatch {
  position: relative;
  min-height: 48px;
}
.k-chip::after, .pseg::after, .k-swatch::after {
  content: ''; position: absolute; left: 0; right: 0;
  top: 50%; transform: translateY(-50%); height: 48px;
}

/* --dim was the only token at risk against the ink background. Lifted to clear
   WCAG 2.2 AA (4.5:1) for body copy at kiosk sizes; verified from rendered
   pixels by test/suites/contrast.mjs, not from this comment. */
:root { --dim: #b3aa9a; --dim-strong: #cfc6b4; }

/* Focus must be visible — staff use a keyboard on the register surface, and an
   invisible focus ring is an accessibility failure even on a touch kiosk. */
:focus-visible {
  outline: 3px solid var(--brass);
  outline-offset: 3px;
  border-radius: 3px;
}

/* ============================================================
   "STILL THERE?" — the reset gate
   ------------------------------------------------------------
   Nothing resets a guest without this first. Deliberately large and centred:
   a child mid-quiz must be able to cancel it without reading carefully.
   ============================================================ */
#k-stillthere {
  position: fixed; top:0; right:0; bottom:0; left:0; z-index: 90;
  display: none; align-items: center; justify-content: center;
  background: radial-gradient(ellipse at center, rgba(13,18,26,.93), rgba(7,9,13,.97));
}
#k-stillthere.show { display: flex; animation: k-fade .28s var(--ease) both; }
#k-stillthere .k-st-card {
  text-align: center; padding: clamp(28px,5vh,52px) clamp(28px,6vw,72px);
  border: 1px solid var(--line); border-radius: 8px;
  background: rgba(18,23,31,.96); box-shadow: var(--shadow);
  display: flex; flex-direction: column; align-items: center; gap: 16px;
  max-width: 560px;
}
#k-stillthere .k-st-glyph { font-size: 56px; }
#k-stillthere .k-st-title { font-size: clamp(30px,5vh,46px); font-style: italic; }
#k-stillthere .k-st-sub { font-size: 15px; color: var(--dim-strong); line-height: 1.6; }
#k-stillthere .k-st-sub b { color: var(--brass); font-size: 20px; font-variant-numeric: tabular-nums; }
#k-stillthere .k-st-keep { font-size: 16px; padding: 22px 44px; margin-top: 6px; }
#k-stillthere .k-st-done { font-size: 12px; padding: 14px 26px; }

/* ============================================================
   REDUCED MOTION
   ------------------------------------------------------------
   WCAG 2.2. Every transition gets a calm variant rather than being deleted —
   feedback that vanishes entirely reads as an unresponsive screen, which on a
   kiosk makes a guest press harder and repeatedly.
   ============================================================ */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: .01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: .12s !important;
    scroll-behavior: auto !important;
  }
  /* Keep a non-moving affordance where motion used to carry the meaning. */
  #k-attract .glyph { animation: none !important; }
  #k-attract .tap { animation: none !important; opacity: .85 !important; }
  #k-boot .ring { animation: none !important; border-top-color: var(--brass); opacity: .8; }
  .k-rise, .k-rise-2, .k-rise-3 { animation: none !important; opacity: 1 !important; transform: none !important; }
}

/* Screen-reader-only text for controls whose meaning is carried by an icon. */
.k-sr {
  position: absolute !important; width: 1px; height: 1px;
  padding: 0; margin: -1px; overflow: hidden;
  clip: rect(0 0 0 0); clip-path: inset(50%); white-space: nowrap; border: 0;
}

/* A placeholder must read as "art is coming", never as "this is broken".

   The base layer is OPAQUE on purpose. A translucent placeholder takes its
   contrast from whatever happens to be behind it, and a placeholder by
   definition sits where art will go — so on the reveal screen the brass label
   landed on a mid-tone backdrop and measured 4.32:1, under the 4.5 AA floor.
   Opaque means the contrast is a property of this component rather than of
   whatever it is covering. */
.k-placeholder {
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: 10px; text-align: center;
  background:
    repeating-linear-gradient(135deg, rgba(217,164,65,.06) 0 12px, transparent 12px 24px),
    var(--ink3);
  border: 1px dashed var(--line); border-radius: 6px; color: var(--dim-strong);
}
.k-placeholder .k-ph-glyph { font-size: 34px; opacity: .75; }
/* 12px, not 11 — read from ~60cm through gallery glass, uppercase and letter-
   spaced, this is already at the small end of legible. */
.k-placeholder .k-ph-label { font-size: 12px; letter-spacing: .24em; text-transform: uppercase; color: var(--brass-lt); }
.k-placeholder .k-ph-note { font-size: 12px; max-width: 30ch; line-height: 1.5; color: var(--dim-strong); }
