/*
  Shared page chrome for the Play MVP: reset, app shell, top bar, page
  background, card style, buttons, bottom sheet base, modal base.
  Depends on css/tokens.css being loaded first.
*/

*, *::before, *::after { box-sizing: border-box; }
html, body { min-height: 100%; }
body {
  margin: 0;
  font-family: var(--font-family);
  font-weight: var(--font-weight-body);
  font-size: var(--text-base);
  line-height: 1.5;
  color: var(--ink);
  background: var(--plum);
}
h1, h2, h3, h4 { margin: 0; font-weight: var(--font-weight-heading); }
p { margin: 0; }
button { font: inherit; color: inherit; background: none; border: none; cursor: pointer; }
a { color: var(--royal); }
img { max-width: 100%; display: block; }
ul, ol { margin: 0; padding: 0; list-style: none; }

:focus-visible {
  outline: var(--focus-ring-width) solid var(--focus-ring-color);
  outline-offset: 2px;
  border-radius: var(--radius-sm);
}

/* ---------- App shell ---------- */

.app {
  min-height: 100dvh;
  height: 100dvh;
  display: flex;
  flex-direction: column;
  background: var(--bg);
  position: relative;
  overflow: hidden;
}

/* ---------- Top bar (56px plum, back + title + optional overflow) ---------- */

.topbar {
  flex: none;
  display: flex;
  align-items: center;
  gap: 4px;
  min-height: 56px;
  background: var(--plum);
  color: #fff;
  padding: 4px 6px;
  z-index: 5;
}
.topbar .tbtn {
  width: var(--tap-min);
  height: var(--tap-min);
  flex: none;
  display: grid;
  place-items: center;
  border-radius: var(--radius-md);
  font-size: var(--text-lg);
  transition: transform .1s;
}
.topbar .tbtn:active { transform: scale(var(--press-scale)); }
.topbar .tbtn.is-hidden { visibility: hidden; }
.topbar h1 {
  flex: 1;
  min-width: 0;
  font-size: var(--text-md);
  padding-left: 4px;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.topbar .mode-mark {
  flex: none;
  font-size: var(--text-xs);
  font-weight: var(--font-weight-heading);
  background: rgba(255, 255, 255, .16);
  border-radius: 999px;
  padding: 4px 10px;
  margin-right: 2px;
  white-space: nowrap;
}

/* ---------- Scrollable content area ---------- */

.scroll {
  flex: 1;
  overflow-y: auto;
  overscroll-behavior: contain;
  padding: 14px 14px 24px;
  display: grid;
  gap: 14px;
  align-content: start;
}

/* ---------- Card ---------- */

.card {
  background: var(--card);
  border-radius: var(--radius-lg);
  border: var(--card-border-width) solid var(--card-border-color);
  box-shadow: var(--card-shadow);
  padding: 16px;
}

/* ---------- Stat tiles ---------- */

/*
  A row of small numbers with a label under each. Shared: the trophy shelf's
  department totals, and a guardian's own "Deg mot X" tab. Design from
  Bots/Screens/vokter-trofehylla.html.
*/
.statgrid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 8px; }
.statgrid.two { grid-template-columns: repeat(2, 1fr); }
.stat {
  background: #f4f1f6;
  border-radius: var(--radius-md);
  padding: 9px 6px;
  text-align: center;
}
.stat b { display: block; font-size: var(--text-xl); color: var(--ink); }
.stat span { font-size: 11.5px; font-weight: 800; color: var(--muted); }

/* ---------- Mode block ---------- */

/*
  One block per game mode, the same shape and weight for both, holding stat
  tiles. Shared by the trophy shelf's totals and a guardian's Loggboka tab.

  The tint is the mode's own colour at its quietest: the beach ball's blue for
  Lekekamp, the medal's gold for Ekte kamp, so the two are told apart before
  either label is read. They weigh the same on purpose (owner, 2026-08-22):
  Lekekamp is where a child trains, and a page that counted only Ekte kamp was
  telling them the training did not count.
*/
.modeblock { border-radius: var(--radius-md); padding: 10px; }
.modeblock + .modeblock { margin-top: 10px; }
.modeblock.leke { background: #eaf7fd; }
.modeblock.ekte { background: #fdf6e6; }
.modeblock .mhead {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-bottom: 8px;
  font-size: var(--text-sm);
  font-weight: var(--font-weight-heading);
  color: var(--ink);
}
.modeblock .mhead svg { display: block; flex: none; }
.modeblock .stat { background: #fff; }

/*
  A streak, on its own row under the tiles rather than as a third tile. As a
  tile labelled "best uten tap" it read as neither a streak nor a number anyone
  could place: it never said what it counted, and showing only the all-time
  best hid where a child stands right now (owner, 2026-08-22). So: the flame
  says "streak" the way every app has taught, the CURRENT run is the number,
  and the best sits behind it as context.
*/
.streak {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-top: 8px;
  padding: 8px 10px;
  background: #fff;
  border-radius: var(--radius-md);
  font-size: var(--text-sm);
  font-weight: 700;
  color: var(--ink);
}
.streak svg { display: block; flex: none; }
.streak .lines { display: grid; gap: 1px; min-width: 0; }
.streak .now b { font-size: var(--text-lg); font-weight: var(--font-weight-heading); }
/* The Lekekamp streak is the same size as the Ekte one. Only the colour tells
   them apart, and that is enough (owner, 2026-08-22): shrinking it as well was
   saying twice over that it matters less. */
.streak .best {
  font-size: var(--text-xs);
  font-weight: 800;
  color: var(--muted);
}
.streak .best b { font-weight: 800; }
/* No run going: the bolt greys out, and the row is there to hold the record
   so a child can see what there is to beat. */
.streak.is-cold { color: var(--muted); }
.streak.is-cold svg { filter: grayscale(1); opacity: .55; }

/* ---------- Buttons ---------- */

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  min-height: var(--tap-min);
  padding: 10px 20px;
  border-radius: var(--radius-btn);
  font-size: var(--text-base);
  font-weight: var(--font-weight-heading);
  transition: transform .1s, opacity .1s;
}
.btn:active { transform: scale(var(--press-scale)); }
.btn:disabled { opacity: .5; cursor: not-allowed; }
.btn:disabled:active { transform: none; }
.btn-block { width: 100%; }

.btn-primary {
  background: var(--royal);
  color: #fff;
  box-shadow: 0 2px 6px rgba(10, 36, 177, .3);
}
.btn-secondary {
  background: var(--card);
  color: var(--royal);
  border: 2px solid var(--royal);
}
.btn-ghost {
  background: transparent;
  color: var(--royal);
  min-height: var(--tap-min);
}
.btn-danger {
  background: var(--red);
  color: #fff;
  box-shadow: 0 2px 6px rgba(175, 17, 22, .3);
}

/* ---------- Bottom sheet base ---------- */

/*
  Hold the page still behind an open sheet or modal. On the pages that run the
  site chrome the WINDOW scrolls now, so without this the page slid around
  under a sheet that is fixed to the viewport. The gutter is reserved always,
  so locking it does not shift the layout sideways.
*/
html { scrollbar-gutter: stable; }
html:has(.sheet.is-open),
html:has(.sheet-backdrop.is-open),
html:has(.app-modal.is-open) { overflow: hidden; }

.sheet-backdrop {
  position: fixed;
  inset: 0;
  background: rgba(46, 47, 66, .4);
  opacity: 0;
  pointer-events: none;
  transition: opacity .2s ease;
  z-index: 20;
}
.sheet-backdrop.is-open {
  opacity: 1;
  pointer-events: auto;
}

.sheet {
  position: fixed;
  left: 0;
  right: 0;
  bottom: 0;
  z-index: 21;
  background: var(--card);
  border-radius: var(--radius-lg) var(--radius-lg) 0 0;
  box-shadow: 0 -4px 20px rgba(0, 0, 0, .25);
  padding: 12px 16px calc(16px + env(safe-area-inset-bottom));
  max-height: 85dvh;
  overflow-y: auto;
  transform: translateY(100%);
  transition: transform .25s ease;
}
.sheet.is-open { transform: translateY(0); }
.sheet .grabber {
  width: 40px;
  height: 4px;
  border-radius: 2px;
  background: var(--track);
  margin: 0 auto 12px;
}
.sheet .shead {
  display: flex;
  align-items: center;
  gap: 12px;
  margin-bottom: 12px;
}
.sheet .shead h3 { font-size: var(--text-lg); }
.sheet .shead small { display: block; font-size: var(--text-xs); color: var(--muted); font-weight: 700; }

/* ---------- Modal base ---------- */

.app-modal {
  position: fixed;
  inset: 0;
  z-index: 30;
  display: none;
  align-items: center;
  justify-content: center;
  padding: 20px;
  background: rgba(46, 47, 66, .4);
}
.app-modal.is-open { display: flex; }
.app-modal .modal-card {
  position: relative;
  width: 100%;
  max-width: 420px;
  background: var(--bg);
  border-radius: var(--radius-md);
  padding: 24px 20px 20px;
  animation: modal-slide-down .2s ease;
}
.app-modal .modal-close {
  position: absolute;
  top: -14px;
  right: -14px;
  width: 40px;
  height: 40px;
  border-radius: 50%;
  background: #fff;
  box-shadow: 0 2px 8px rgba(0, 0, 0, .25);
  display: grid;
  place-items: center;
  font-size: var(--text-md);
}
@keyframes modal-slide-down {
  from { transform: translateY(-16px); opacity: 0; }
  to { transform: translateY(0); opacity: 1; }
}

/* ---------- Desktop breakpoint (768+) ---------- */

@media (min-width: 768px) {
  .scroll {
    width: 100%;
    max-width: var(--content-max);
    margin: 0 auto;
    padding: 24px 24px 40px;
  }
  .topbar h1 { font-size: var(--text-lg); }
}

/* ---------- Reduced motion ---------- */

@media (prefers-reduced-motion: reduce) {
  * {
    animation-duration: .001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: .001ms !important;
    scroll-behavior: auto !important;
  }
}
