/* ===========================================================================
   Classroom Activities as an installed app.
   ---------------------------------------------------------------------------
   Two jobs. On the open web it styles the install-and-save card and the
   connection line. Once the thing is actually installed — `.is-app`, set by
   app.js, with a display-mode query as the belt to its braces — it turns the
   page into something that behaves like an app: no site footer, a bottom bar
   for the thumb, and room left for the phone's own furniture.
   ========================================================================= */

/* --- connection ------------------------------------------------------------ */

.app-net {
  margin: 0;
  padding: 0.7rem var(--sp-4, 1rem);
  background: var(--amber-100);
  border-bottom: 1px solid var(--amber-200);
  color: #6a3b06;
  font-size: var(--step--1);
  font-weight: 600;
  text-align: center;
}
.app-net--back {
  background: color-mix(in srgb, var(--good) 14%, var(--paper));
  border-bottom-color: color-mix(in srgb, var(--good) 30%, var(--paper));
  color: #14503a;
}

/* --- "a newer version is ready" -------------------------------------------- */

.app-update {
  position: fixed;
  left: 50%;
  bottom: calc(1rem + env(safe-area-inset-bottom));
  transform: translateX(-50%);
  z-index: 300;
  display: flex;
  align-items: center;
  gap: 0.9rem;
  max-width: min(94vw, 34rem);
  padding: 0.7rem 0.75rem 0.7rem 1.1rem;
  background: var(--night-800);
  color: var(--night-text);
  /* Not a pill: on a phone the sentence wraps to three lines and a pill radius
     turns the toast into an ellipse. */
  border-radius: var(--r-md);
  box-shadow: var(--shadow-lg);
  font-size: var(--step--1);
}
.app-update .btn {
  --btn-bg: var(--amber-500);
  --btn-fg: #3a1c04;
  flex: none;
}
.is-app .app-update { bottom: calc(4.9rem + env(safe-area-inset-bottom)); }

/* --- the install / save card ----------------------------------------------- */

.appcard {
  display: grid;
  grid-template-columns: auto 1fr auto;
  align-items: center;
  gap: 1.1rem 1.4rem;
  margin: 0 0 var(--sp-6, 2rem);
  padding: 1.25rem 1.4rem;
  background: linear-gradient(135deg, var(--teal-800), var(--teal-700) 60%, var(--teal-600));
  color: var(--white);
  border-radius: var(--r-lg);
  box-shadow: var(--shadow-md);
}
.appcard__mark {
  width: 3.4rem;
  height: 3.4rem;
  border-radius: var(--r-md);
  background: rgb(255 255 255 / 0.1);
  padding: 0.35rem;
}
.appcard h2 {
  margin: 0 0 0.2rem;
  font-size: var(--step-1);
  color: var(--white);
}
.appcard p {
  margin: 0;
  color: color-mix(in srgb, var(--white) 82%, transparent);
  font-size: var(--step--1);
  line-height: 1.5;
  max-width: 48ch;
}
.appcard__actions {
  display: flex;
  flex-wrap: wrap;
  gap: 0.6rem;
  justify-content: flex-end;
}
.appcard .btn { --btn-bg: var(--amber-500); --btn-fg: #3a1c04; }
.appcard .btn--ghost {
  --btn-bg: transparent;
  --btn-fg: var(--white);
  border-color: rgb(255 255 255 / 0.45);
}
.appcard .btn--ghost:hover { background: rgb(255 255 255 / 0.12); }
.appcard--done .appcard__mark { background: rgb(255 255 255 / 0.2); }
/* "Take the activities into the room" is a pitch, and pitching an app to
   somebody already inside it is silly: in the app this is just the setting. */
.appcard__app { display: none; }
.is-app .appcard__web { display: none; }
.is-app .appcard__app { display: inline; }

.appcard__meter {
  grid-column: 1 / -1;
  height: 0.5rem;
  border-radius: var(--r-pill);
  background: rgb(255 255 255 / 0.18);
  overflow: hidden;
}
.appcard__fill {
  display: block;
  height: 100%;
  width: 0;
  border-radius: inherit;
  background: var(--amber-400);
  transition: width 0.25s ease;
}

.appcard__hint {
  grid-column: 1 / -1;
  display: flex;
  align-items: center;
  gap: 0.8rem;
  padding: 0.7rem 0.9rem;
  background: rgb(255 255 255 / 0.12);
  border-radius: var(--r-md);
  font-size: var(--step--1);
}
.appcard__hint p { margin: 0; color: var(--white); }
.appcard__hint button {
  flex: none;
  margin-left: auto;
  background: none;
  border: 0;
  color: color-mix(in srgb, var(--white) 75%, transparent);
  font-size: 1.1rem;
  line-height: 1;
  cursor: pointer;
}
.appcard__hint kbd {
  font: inherit;
  font-weight: 700;
  padding: 0.05em 0.35em;
  border-radius: 5px;
  background: rgb(255 255 255 / 0.18);
}

@media (max-width: 720px) {
  .appcard {
    grid-template-columns: auto 1fr;
    padding: 1.1rem;
  }
  .appcard__actions {
    grid-column: 1 / -1;
    justify-content: stretch;
  }
  .appcard__actions .btn { flex: 1 1 auto; }
}

/* --- the bottom bar -------------------------------------------------------- */

.appbar {
  display: none;
  position: fixed;
  inset: auto 0 0 0;
  z-index: 200;
  padding-bottom: env(safe-area-inset-bottom);
  background: color-mix(in srgb, var(--paper) 94%, transparent);
  backdrop-filter: blur(14px) saturate(1.3);
  border-top: 1px solid var(--line);
}
.appbar__inner {
  display: grid;
  grid-auto-flow: column;
  grid-auto-columns: 1fr;
  max-width: 34rem;
  margin: 0 auto;
}
.appbar a {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.15rem;
  padding: 0.5rem 0.25rem 0.55rem;
  color: var(--ink-faint);
  text-decoration: none;
  font-size: 0.7rem;
  font-weight: 600;
  letter-spacing: 0.01em;
}
.appbar a svg {
  width: 1.45rem;
  height: 1.45rem;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.8;
  stroke-linecap: round;
  stroke-linejoin: round;
}
.appbar a[aria-current="page"] { color: var(--teal-700); }
.appbar a[aria-current="page"] svg { stroke-width: 2.2; }

/* --- the title bar --------------------------------------------------------- */

.apphead {
  display: none;
  position: sticky; top: 0; z-index: 150;
  align-items: center; gap: 0.55rem;
  padding: 0.4rem 0.7rem;
  padding-top: calc(0.4rem + env(safe-area-inset-top));
  background: color-mix(in srgb, var(--paper) 90%, transparent);
  backdrop-filter: blur(14px) saturate(1.4);
  border-bottom: 1px solid var(--line);
}
.apphead__back,
.apphead__action {
  display: inline-flex; align-items: center; justify-content: center;
  width: 2.4rem; height: 2.4rem; flex: none;
  color: var(--teal-700); border-radius: var(--r-pill);
}
.apphead__back svg,
.apphead__action svg {
  width: 1.5rem; height: 1.5rem;
  fill: none; stroke: currentColor; stroke-width: 2;
  stroke-linecap: round; stroke-linejoin: round;
}
.apphead__action svg { stroke-width: 1.7; }
.apphead__back:active,
.apphead__action:active { background: var(--teal-100); }
.apphead__mark {
  width: 1.9rem; height: 1.9rem; flex: none; margin-left: 0.15rem;
  border-radius: 8px;
}
.apphead__what { min-width: 0; flex: 1; }
.apphead__title {
  margin: 0;
  font-family: var(--display); font-size: 1.08rem; font-weight: 600; line-height: 1.2;
  /* One line: a long activity name must not push the bar to two rows. */
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.apphead__sub {
  margin: 0.05rem 0 0;
  font-size: 0.74rem; line-height: 1.25; color: var(--ink-faint); font-weight: 500;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
/* Held back until the screen's own heading has scrolled away; see app.js.
   Without JavaScript `--quiet` is never set and the title is simply there. */
.apphead--quiet .apphead__what { opacity: 0; transition: opacity 0.18s ease; }
.apphead--titled .apphead__what { opacity: 1; }
/* Nothing on the right, so the words are not shoved off-centre by a gap. */
.apphead:not(:has(.apphead__action)) .apphead__what { padding-right: 0.4rem; }

/* --- installed ------------------------------------------------------------- */

/* Everything below is what makes the app an app rather than the website in a
   window without an address bar: the site's own header, menu, breadcrumbs and
   footer go, and the app's title bar and tabs stand in for them. */
.is-app .apphead { display: flex; }
.is-app .appbar { display: block; }
.is-app .site-header { display: none; }
.is-app .site-footer { display: none; }
.is-app .skip-link { display: none; }
.is-app .crumbs { display: none; }
.is-app main { padding-bottom: 4.4rem; }

/* The install card belongs on the catalogue on the open web and on the runs
   screen in the app, where it is the only place the saved copy is managed. */
.is-app .act-section .appcard { display: none; }
html:not(.is-app) .runs-page .appcard { display: none; }

/* The catalogue's opening screen. The web hero introduces the section to a
   stranger; in the app you are already here, so it is a search field and the
   browse rows, and the title bar says where you are. */
.is-app .act-hero { padding: 0.75rem 0 0.9rem; background: var(--paper); }
.is-app .act-hero::before, .is-app .act-hero::after { display: none; }
.is-app .act-hero h1,
.is-app .act-hero__lede { display: none; }
/* One row, always: on the web the search and the dice wrap onto two lines at
   phone width, which in the app is the top of the screen and worth the space. */
.is-app .act-hero__search { margin: 0; flex-wrap: nowrap; align-items: center; gap: 0.5rem; }
.is-app .act-hero__search label { flex: 1 1 auto; min-width: 0; }
.is-app .act-hero__search input { padding: 0.7em 1em; }
.is-app .act-hero__search .btn { flex: none; padding: 0.7rem 1rem; font-size: var(--step--1); }
.is-app .act-hero__search input {
  background: var(--white); color: var(--ink); border-color: var(--line);
}
.is-app .act-hero__search input::placeholder { color: var(--ink-faint); }
.is-app .act-section { padding-top: 0.25rem; }

/* Browse rows scroll sideways instead of wrapping into a wall of tiles that
   pushes the activities themselves off the bottom of a phone. */
.is-app .act-species-row,
.is-app .act-kind-row {
  display: flex; flex-wrap: nowrap;
  overflow-x: auto; scroll-snap-type: x proximity;
  margin-inline: calc(var(--sp-3, 1rem) * -1); padding-inline: var(--sp-3, 1rem);
  scrollbar-width: none;
}
.is-app :is(.act-species-row, .act-kind-row)::-webkit-scrollbar { display: none; }
.is-app .act-species { flex: 0 0 5.8rem; scroll-snap-align: start; }
.is-app .act-kind { flex: 0 0 13rem; scroll-snap-align: start; }
.is-app .act-browse__head p { display: none; }
.is-app .act-browse__head h2 { font-size: 1.02rem; }

/* One column, and the website's calls to action drop away: both have a tab. */
.is-app .act-grid { grid-template-columns: 1fr; }
.is-app .act-make-cta,
.is-app .act-log { display: none; }

/* Phone furniture. Chrome, not content: the activity text stays selectable. */
.is-app {
  -webkit-text-size-adjust: 100%;
  overscroll-behavior-y: contain;
}
.is-app :is(.apphead, .appbar, .act-bar, .act-species, .act-kind, .btn) {
  -webkit-tap-highlight-color: transparent;
  -webkit-touch-callout: none;
  user-select: none;
}

/* Belt to the `.is-app` braces: iOS has reported display-mode late in the
   past, and this way the frame is right on the very first paint. */
@media (display-mode: standalone) {
  .apphead { display: flex; }
  .appbar { display: block; }
  .site-header, .site-footer, .crumbs, .skip-link { display: none; }
  main { padding-bottom: 4.4rem; }
}

/* Moving between screens should feel like one app, not four page loads. The
   browser does nothing with this unless it supports cross-document view
   transitions, and nothing at all if motion is turned down. */
@view-transition { navigation: auto; }

@media (prefers-reduced-motion: reduce) {
  @view-transition { navigation: none; }
}

/* --- saved runs ------------------------------------------------------------ */

.runs {
  display: grid;
  gap: 1rem;
  margin: 0;
  padding: 0;
  list-style: none;
}
.run-card {
  display: grid;
  grid-template-columns: 1fr auto;
  gap: 0.35rem 1rem;
  padding: 1.05rem 1.2rem;
  background: var(--white);
  border: 1px solid var(--line);
  border-left: 5px solid var(--accent, var(--teal-600));
  border-radius: var(--r-md);
  box-shadow: var(--shadow-sm);
}
.run-card__title {
  margin: 0;
  font-family: var(--display);
  font-size: var(--step-1);
  line-height: 1.2;
}
.run-card__title a { color: var(--ink); text-decoration: none; }
.run-card__title a:hover { color: var(--teal-700); text-decoration: underline; }
.run-card__when {
  grid-row: 1;
  grid-column: 2;
  align-self: start;
  color: var(--ink-faint);
  font-size: var(--step--1);
  white-space: nowrap;
}
.run-card__facts {
  grid-column: 1 / -1;
  display: flex;
  flex-wrap: wrap;
  gap: 0.4rem 0.55rem;
  margin: 0.15rem 0 0;
  padding: 0;
  list-style: none;
}
.run-card__facts li {
  padding: 0.2rem 0.6rem;
  background: var(--paper-warm);
  border-radius: var(--r-pill);
  font-size: var(--step--1);
  color: var(--ink-soft);
}
.run-card__note {
  grid-column: 1 / -1;
  margin: 0.4rem 0 0;
  color: var(--ink-soft);
  font-size: var(--step--1);
  line-height: 1.5;
}
.runs-empty {
  padding: 2.5rem 1.5rem;
  text-align: center;
  background: var(--paper-warm);
  border-radius: var(--r-lg);
  color: var(--ink-soft);
}
.runs-tools {
  display: flex;
  flex-wrap: wrap;
  gap: 0.6rem;
  margin: 0 0 1.5rem;
}

@media print {
  .appbar,
  .appcard,
  .app-net,
  .app-update { display: none !important; }
}
