/* Turn on the Fun — standalone comic reader.
   Fully self-contained: no shared files with the main site or the other
   two comic readers, per project convention (see DANNY-README.md). */

* {
  box-sizing: border-box;
}

html,
body {
  margin: 0;
  padding: 0;
}

body {
  background: #ddd;
  font-family: "Open Sans", sans-serif;
}

a {
  color: inherit;
}

/* ==========================================================
   Scale tiers — pure width cascade, but NOT one clean 3-tier
   system: type scale (title/button/pagination/credit sizes)
   switches at 768 and 1024; spacing (--container-gap,
   --main-content-gap, --page-pb) mostly follows the same steps
   but doesn't fully reach the Desktop values until 1440 — see
   the 1024/1440 blocks below for exactly which variables cut
   over where. --container-gap and --footer-gap look similar but
   are genuinely different measurements per Figma: the first is
   the gap between Main Content and Footer, the second is
   Footer's own internal gap between its nav row and credit
   line — they only happen to share the same value at the
   Tablet-Landscape/Desktop tiers, not at Mobile/Tablet-Portrait.
   ========================================================== */

.page {
  --title-height: 18px;
  --name-size: 12px;
  --frame-pad: 6px;
  --container-gap: 16px;
  --footer-gap: 12px;
  --nav-gap: 8px;
  --nav-button-width: auto;
  --nav-button-flex: 1 1 0%;
  --nav-button-height: 44px;
  --nav-text-size: 16px;
  --pagination-width: 72px;
  --pagination-label-size: 10px;
  --pagination-value-size: 16px;
  --credit-line1-size: 14px;
  --credit-line2-size: 12px;
  --container-padding-inline: 24px;
  --container-max-width: none;
  --main-content-gap: 16px;
  --header-justify: center;
  --header-gap: 24px;
  --page-pt: 16px;
  --page-pb: 12px;
}

@media (min-width: 768px) {
  .page {
    --title-height: 20px;
    --name-size: 14px;
    --frame-pad: 10px;
    --container-gap: 24px;
    --footer-gap: 36px;
    --nav-gap: 24px;
    --nav-button-width: 144px;
    --nav-button-flex: 0 0 auto;
    --nav-text-size: 16px;
    --pagination-width: 96px;
    --credit-line1-size: 14px;
    --credit-line2-size: 12px;
    --container-padding-inline: 48px;
    --header-justify: space-between;
    --page-pt: 20px;
    --page-pb: 24px;
  }
}

/* Type scale (title/button/pagination/credit sizes) jumps to the
   Desktop scale here at 1024, but gap/padding stays at the
   Tablet-Portrait values below — Tablet-Landscape's Container gap is
   genuinely 36px (not Desktop's 48px) and its page padding-bottom is
   genuinely 24px (not 48px) per Figma, only actually reaching the
   Desktop spacing at 1440. Two different cascade points, not one —
   easy to miss since every OTHER value here does match Desktop. */
@media (min-width: 1024px) {
  .page {
    --title-height: 24px;
    --name-size: 18px;
    --container-gap: 36px;
    --nav-button-width: 200px;
    --nav-button-height: 48px;
    --nav-text-size: 18px;
    --pagination-label-size: 12px;
    --pagination-value-size: 18px;
    --credit-line1-size: 16px;
    --credit-line2-size: 14px;
    --container-max-width: 996px;
    --container-padding-inline: 0;
  }
}

@media (min-width: 1440px) {
  .page {
    --container-gap: 48px;
    --footer-gap: 48px;
    --main-content-gap: 20px;
    --page-pb: 48px;
  }
}

@media (min-width: 1920px) {
  .page {
    --container-max-width: 1200px;
  }
}

/* ==========================================================
   Structure — same markup at every tier, only these rules
   read the variables above.
   ========================================================== */

.page {
  display: flex;
  flex-direction: column;
  align-items: center;
  padding: var(--page-pt) 0 var(--page-pb);
}

.container {
  display: flex;
  flex-direction: column;
  gap: var(--container-gap);
  width: 100%;
  max-width: var(--container-max-width);
  padding-inline: var(--container-padding-inline);
}

.main-content {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: var(--main-content-gap);
  width: 100%;
  transition: gap 0.35s ease;
}

/* Page 1 hides the header — its title+author would just repeat what
   the comic's own splash panel already says a beat later. Collapsed
   via max-height (not display:none) so it can animate open; the
   generous 80px ceiling comfortably covers the header's rendered
   height at every scale tier. main-content's own gap collapses to 0
   alongside it so no empty gap-sized space is left above the image
   while the header is hidden. */
.header {
  display: flex;
  align-items: center;
  justify-content: var(--header-justify);
  gap: var(--header-gap);
  width: 100%;
  max-height: 80px;
  overflow: hidden;
  opacity: 1;
  transition: max-height 0.35s ease, opacity 0.25s ease;
}

.main-content.header-hidden {
  gap: 0;
}

.main-content.header-hidden .header {
  max-height: 0;
  opacity: 0;
}

.header__title {
  display: block;
  height: var(--title-height);
  width: auto;
}

.header__name {
  margin: 0;
  font-family: "Comic Relief", cursive;
  font-weight: 700;
  font-size: var(--name-size);
  line-height: 1.4;
  color: #1b22b4;
  white-space: nowrap;
}

/* aspect-ratio (matching the real page images' own 2500x3750) drives
   sizing directly, instead of relying on the <img>'s intrinsic size
   propagating up through a shrinking flex item — Safari doesn't
   reliably shrink a flex item whose only sizing signal is a nested
   image's own width/height:auto + max-width/max-height, so on a short
   viewport the frame stayed full width there (worked fine in Chrome).
   aspect-ratio is explicitly specified to interact correctly with
   flex/max-height shrinking in all current browsers, sidestepping
   that inconsistency rather than working around it. */
.image-frame {
  position: relative;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 100%;
  aspect-ratio: 2500 / 3750;
  padding: var(--frame-pad);
  background: #fff;
  border: 1px solid #000;
}

.image-frame__img {
  display: block;
  width: 100%;
  height: 100%;
  transition: opacity 0.2s ease-out;
}

.image-frame__loader {
  position: absolute;
  top: 50%;
  left: 50%;
  width: 72px;
  height: 72px;
  transform: translate(-50%, -50%);
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.15s ease-out;
}

@media (min-width: 768px) {
  .image-frame__loader {
    width: 96px;
    height: 96px;
  }
}

.image-frame.is-loading .image-frame__img {
  opacity: 0.05;
}

.image-frame.is-loading .image-frame__loader {
  opacity: 1;
}

.footer {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--footer-gap);
  width: 100%;
}

.navigation {
  display: flex;
  align-items: flex-start;
  justify-content: center;
  gap: var(--nav-gap);
  width: 100%;
}

.nav-button {
  display: flex;
  flex: var(--nav-button-flex);
  align-items: center;
  justify-content: center;
  gap: 8px;
  width: var(--nav-button-width);
  height: var(--nav-button-height);
  padding: 8px 0;
  background: #d0d0d0;
  border: none;
  box-shadow: inset 1px 1px 0 0 #fff, inset -1px -1px 0 0 rgba(0, 0, 0, 0.5);
  font-family: "Open Sans", sans-serif;
  font-weight: 600;
  font-size: var(--nav-text-size);
  color: #000;
  cursor: pointer;
}

/* (hover: hover) scopes this to devices with a real hovering pointer
   (mouse/trackpad). Without it, tapping a button on a touchscreen
   matches :hover and — since there's no mouse to move away and clear
   it — the "hover" look sticks around after the tap until something
   else is touched. Gating it here means touch never triggers it at
   all, rather than trying to clear it after the fact. */
@media (hover: hover) {
  .nav-button:hover:not(:disabled) {
    color: #1b22b4;
    box-shadow: inset 1px 1px 0 0 rgba(0, 0, 0, 0.5), inset -1px -1px 0 0 #fff;
  }
}

.nav-button:disabled {
  color: #999;
  box-shadow: inset 1px 1px 0 0 rgba(255, 255, 255, 0.5), inset -1px -1px 0 0 rgba(0, 0, 0, 0.25);
  cursor: default;
}

.nav-button__icon {
  display: block;
  fill: currentColor;
}

.pagination {
  display: flex;
  flex: 0 0 auto;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 2px;
  width: var(--pagination-width);
  height: var(--nav-button-height);
  padding: 0 36px;
  border-top: 1px solid rgba(0, 0, 0, 0.5);
  border-bottom: 1px solid rgba(0, 0, 0, 0.5);
  font-family: "Open Sans", sans-serif;
  font-weight: 600;
  line-height: 1;
  color: #1b22b4;
  text-align: center;
  white-space: nowrap;
}

.pagination__label {
  font-size: var(--pagination-label-size);
}

.pagination__value {
  font-size: var(--pagination-value-size);
}

.credit {
  display: flex;
  flex-direction: column;
  align-items: center;
  line-height: 1.4;
  color: #1b22b4;
  text-align: center;
}

.credit__line1 {
  margin: 0;
  font-family: "Comic Relief", cursive;
  font-weight: 700;
  font-size: var(--credit-line1-size);
}

.credit__line2 {
  margin: 0;
  font-family: "Open Sans", sans-serif;
  font-size: var(--credit-line2-size);
  text-decoration: none;
}

@media (hover: hover) {
  .credit__line2:hover {
    color: #777;
    text-decoration: underline;
    text-decoration-style: solid;
    text-underline-position: from-font;
  }
}

/* ==========================================================
   Constrained mode — everything visible on one screen, footer
   anchored to the bottom. Applies below 768px unconditionally,
   and from 768-1023px only on a touch device (a resized desktop
   browser window in that range has no easy pinch-to-zoom, so it
   gets the natural-flow/scrollable treatment instead — see
   .header override further down for the one piece of this that
   still needs to flip back at that width).

   The mechanism: .page is a fixed 100dvh (dynamic viewport height,
   not 100vh — vh is often taller than what's actually visible on
   mobile browsers once address-bar chrome is accounted for).
   .container and .main-content are both flex:1 with
   justify-content:center, so when their content is SHORTER than
   the space available, it centers as a group with even space
   above/below. When content is TALLER than the space available,
   there's no slack left for justify-content to distribute, so
   .image-frame's flex-shrink (from flex:0 1 auto) takes over and
   it gives up height to fit — .header never shrinks (flex:0 0 auto)
   so only the artwork ever gets smaller. min-height:0 is required
   on anything in that chain that needs to shrink — flex items
   default to min-height:auto, which blocks real shrinking below
   content size.

   Critically .image-frame's flex-GROW stays 0, not 1: growing it
   was the first version's bug — flex-grow:1 stretched the frame's
   box to fill all remaining space while the image inside stayed
   correctly aspect-ratio-sized and smaller, leaving a big empty
   gap of white mat around it. With grow:0 the frame only ever
   takes its natural content size (hugging the image tightly) or
   shrinks below it when space is short — it never expands beyond
   it, so any slack shows up as centered space around the whole
   header+frame group instead of empty padding inside the frame.

   .image-frame's own aspect-ratio (not the <img>'s intrinsic size)
   is what makes the shrink preserve proportions and stay centered.
   An earlier version relied on the <img> alone (width/height:auto,
   max-width/max-height:100%) to keep its ratio while the frame
   shrunk around it — Chrome handles that fine, but Safari doesn't
   reliably shrink a flex item whose only sizing signal comes from a
   nested replaced element like that, so the frame stayed full width
   there even though Chrome shrunk it correctly. Declaring the ratio
   directly on the frame itself (interacting with max-height here)
   is explicitly specified to behave consistently across browsers,
   which sidesteps that inconsistency instead of working around it.
   ========================================================== */

@media (max-width: 767px), (min-width: 768px) and (max-width: 1023px) and (pointer: coarse) {
  .page {
    height: 100dvh;
    justify-content: flex-start;
  }

  .container {
    flex: 1 1 auto;
    min-height: 0;
    justify-content: center;
  }

  .main-content {
    flex: 1 1 auto;
    min-height: 0;
    align-items: center;
    justify-content: center;
  }

  .header {
    flex: 0 0 auto;
    justify-content: center;
  }

  .image-frame {
    flex: 0 1 auto;
    width: auto;
    max-width: 100%;
    max-height: 100%;
    min-height: 0;
    min-width: 0;
  }
}
