/* ==========================================================================
   Planet Group Product Catalogue — digital flipbook
   Palette and type taken from the corporate site: Plus Jakarta Sans on a deep
   navy, with the cover's red as the single accent. (This viewer was first built
   in the Marlos brown; every warm value has been replaced.)
   ========================================================================== */

:root {
  --red: #C1272D;          /* the accent on the cover swoosh */
  --red-dark: #8E1B20;
  --ink: #0A1830;          /* deep Planet Group navy — the page floor */
  --ink-soft: #1B3A6B;     /* lifted navy, for the glow behind the book */
  --chrome: rgba(9, 20, 42, 0.72);   /* glass of the top/bottom bars */
  --panel: #0E2143;        /* solid navy of the contents drawer */
  --cream: #EAF1FB;        /* cool near-white text */
  --line: rgba(160, 190, 235, 0.16);
  --hair: rgba(160, 190, 235, 0.10);
  --fill: rgba(160, 190, 235, 0.08);   /* subtle button/hover fill */
  --fill-hi: rgba(160, 190, 235, 0.16);
  --text-dim: rgba(207, 221, 245, 0.60);

  --font: "Plus Jakarta Sans", "Segoe UI", system-ui, -apple-system, Roboto, Helvetica, Arial, sans-serif;

  --topbar-h: 60px;
  --controlbar-h: 56px;
  --radius: 10px;
}

* { box-sizing: border-box; }

html, body {
  height: 100%;
  margin: 0;
}

body {
  display: flex;
  flex-direction: column;
  /* Layered navy: a cool glow rising off the top-centre where the book sits, a
     fainter warm-navy pool low down, over a deep base — plus a whisper of the
     site's dot texture so the field is not a flat slab. */
  background:
    radial-gradient(120% 80% at 50% -8%, var(--ink-soft) 0%, transparent 55%),
    radial-gradient(90% 60% at 50% 118%, #12294f 0%, transparent 60%),
    var(--ink);
  color: var(--cream);
  font-family: var(--font);
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
  overflow: hidden;
}

/* The dot texture as its own fixed layer behind the content (z-index:-1 keeps it
   above the base gradient but under every bar, button and the book). */
body::before {
  content: "";
  position: fixed;
  inset: 0;
  background-image: radial-gradient(rgba(140, 175, 230, 0.14) 1px, transparent 1px);
  background-size: 24px 24px;
  opacity: 0.5;
  pointer-events: none;
  z-index: -1;
}

svg {
  width: 20px;
  height: 20px;
  fill: none;
  stroke: currentColor;
  stroke-width: 2;
  stroke-linecap: round;
  stroke-linejoin: round;
}

/* --------------------------------------------------------------- top bar */

.topbar {
  flex: 0 0 var(--topbar-h);
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  /* viewport-fit=cover is set, so in landscape on a notched phone a flat 14px
     gutter puts the outermost control under the sensor housing. */
  padding-left: max(14px, env(safe-area-inset-left));
  padding-right: max(14px, env(safe-area-inset-right));
  border-bottom: 1px solid var(--line);
  background: var(--chrome);
  backdrop-filter: blur(10px);
  z-index: 30;
}

.brand {
  display: flex;
  align-items: baseline;
  gap: 10px;
  min-width: 0;
  font-size: 14px;
}
.brand strong {
  font-size: 19px;
  font-weight: 800;
  letter-spacing: -0.2px;
  color: var(--cream);
}
.brand span {
  color: var(--text-dim);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* ---------------------------------------------------------------- buttons */

.btn {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 8px 14px;
  border: 1px solid var(--line);
  border-radius: 999px;
  background: var(--fill);
  color: var(--cream);
  font: inherit;
  font-size: 14px;
  font-weight: 600;
  cursor: pointer;
  transition: background 0.16s ease, border-color 0.16s ease, opacity 0.16s ease;
}
.btn:hover:not(:disabled) {
  background: var(--fill-hi);
  border-color: rgba(160, 190, 235, 0.34);
}
.btn:disabled { opacity: 0.32; cursor: default; }
.btn:focus-visible { outline: 2px solid var(--red); outline-offset: 2px; }

.btn-icon { padding: 8px 12px; }

/* The PDF download is the only action the viewer offers on the document itself
   — every catalogue link on the site now lands here rather than on the file, so
   this is the one way to get it. It carries the accent so it never reads as
   view chrome next to the fullscreen control beside it. */
.btn-download {
  background: var(--red);
  border-color: var(--red);
  color: #fff;
}
.btn-download:hover:not(:disabled) {
  background: var(--red-dark);
  border-color: var(--red-dark);
}

/* Narrow-phone wording, swapped in at the bottom of this file. */
.btn-label-short { display: none; }

/* Fullscreen button swaps its glyph via a body-level class. */
.i-collapse { display: none; }
body.is-fullscreen .i-expand { display: none; }
body.is-fullscreen .i-collapse { display: block; }

/* ------------------------------------------------------------------ stage */

.stage {
  flex: 1 1 auto;
  position: relative;
  display: flex;
  align-items: center;
  justify-content: center;
  min-height: 0;
  padding: 18px;
}

.book-wrap {
  position: relative;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 10px;
  max-width: 100%;
  max-height: 100%;
}

/* StPageFlip's `stretch` mode overwrites the book element's own width with
   100%, so the fitting happens on this frame instead. app.js sets its pixel
   width; the book then stretches to fill it. */
.book-frame {
  flex: 0 0 auto;
  filter: drop-shadow(0 22px 40px rgba(0, 0, 0, 0.55));
  opacity: 0;
  transition: opacity 0.4s ease;
}
.book-frame.ready { opacity: 1; }

/* A closed book only fills the right half of the spread area, which reads as
   off-centre against the empty stage. Nudge it back while it is at rest on the
   cover; app.js drops the class the moment a flip starts. */
.book-frame {
  transition: opacity 0.4s ease, transform 0.35s cubic-bezier(0.22, 1, 0.36, 1);
}
.book-frame.centred { transform: translateX(-25%); }

/* The library measures this element to decide how tall the pages may be, so it
   must inherit the frame's height rather than collapsing to zero. */
.book {
  width: 100%;
  height: 100%;
}

/* Page images. object-fit guards against any residual aspect mismatch. */
.page {
  background: var(--cream);
  overflow: hidden;
}
.page img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
  /* Discourages the casual drag-to-desktop save. Not real protection —
     nothing on the web is — but the source PDF is never served, which is. */
  -webkit-user-drag: none;
  user-select: none;
  pointer-events: none;
}
/* Placeholder tint until a lazy page's image arrives. */
.page:not(.loaded) { background: var(--cream); }

/* ------------------------------------------------------------ nav arrows */

.nav-arrow {
  flex: 0 0 auto;
  display: grid;
  place-items: center;
  width: 46px;
  height: 46px;
  border: 1px solid var(--line);
  border-radius: 50%;
  background: var(--chrome);
  backdrop-filter: blur(6px);
  color: var(--cream);
  cursor: pointer;
  transition: background 0.16s ease, border-color 0.16s ease, transform 0.16s ease, opacity 0.16s ease;
  z-index: 20;
}
.nav-arrow:hover:not(:disabled) { background: var(--red); border-color: var(--red); transform: scale(1.06); }
.nav-arrow:disabled { opacity: 0.22; cursor: default; }
.nav-arrow:focus-visible { outline: 2px solid var(--red); outline-offset: 2px; }

/* --------------------------------------------------------------- loader */

.loader {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 12px;
  color: var(--text-dim);
  font-size: 14px;
  pointer-events: none;
}
.loader.hidden { display: none; }
.spinner {
  width: 18px;
  height: 18px;
  border: 2px solid var(--line);
  border-top-color: var(--red);
  border-radius: 50%;
  animation: spin 0.8s linear infinite;
}
@keyframes spin { to { transform: rotate(360deg); } }

/* ---------------------------------------------------------- control bar */

.controlbar {
  flex: 0 0 var(--controlbar-h);
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 16px;
  border-top: 1px solid var(--line);
  background: var(--chrome);
  backdrop-filter: blur(10px);
  z-index: 30;
}
.counter {
  min-width: 116px;
  text-align: center;
  font-variant-numeric: tabular-nums;
  font-size: 14px;
  color: var(--text-dim);
}

/* ------------------------------------------------------- contents menu */

/* An author `display` declaration beats the UA stylesheet's [hidden] rule, so
   the attribute has to be honoured explicitly or the drawer never closes. */
[hidden] { display: none !important; }

.scrim {
  position: fixed;
  inset: 0;
  background: rgba(0, 0, 0, 0.5);
  z-index: 40;
  animation: fade 0.2s ease;
}
@keyframes fade { from { opacity: 0; } }

.menu {
  position: fixed;
  top: 0;
  left: 0;
  bottom: 0;
  width: min(340px, 86vw);
  display: flex;
  flex-direction: column;
  background: var(--panel);
  border-right: 1px solid var(--line);
  box-shadow: 30px 0 60px rgba(0, 0, 0, 0.4);
  z-index: 50;
  animation: slide-in 0.24s cubic-bezier(0.22, 1, 0.36, 1);
}
@keyframes slide-in { from { transform: translateX(-100%); } }

.menu-head {
  flex: 0 0 auto;
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 14px 16px;
  border-bottom: 1px solid var(--line);
}
.menu-head h2 {
  margin: 0;
  font-size: 15px;
  font-weight: 700;
  letter-spacing: 1.4px;
  text-transform: uppercase;
}

.menu-body {
  flex: 1 1 auto;
  overflow-y: auto;
  padding: 8px 10px 20px;
  overscroll-behavior: contain;
}

.menu-group {
  margin: 14px 6px 6px;
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 1.6px;
  text-transform: uppercase;
  color: var(--red);
}

.menu-item {
  display: flex;
  align-items: center;
  gap: 12px;
  width: 100%;
  padding: 7px 8px;
  border: 0;
  border-radius: var(--radius);
  background: transparent;
  color: var(--cream);
  font: inherit;
  text-align: left;
  cursor: pointer;
  transition: background 0.14s ease;
}
.menu-item:hover { background: var(--fill); }
.menu-item:focus-visible { outline: 2px solid var(--red); outline-offset: -2px; }
.menu-item[aria-current="true"] { background: rgba(193, 39, 45, 0.22); }

.menu-item img {
  flex: 0 0 auto;
  width: 38px;
  height: 54px;
  object-fit: cover;
  border-radius: 3px;
  background: var(--cream);
  box-shadow: 0 1px 4px rgba(0, 0, 0, 0.4);
}
.menu-item .mi-text { min-width: 0; flex: 1 1 auto; }
.menu-item .mi-label {
  display: block;
  font-size: 14px;
  font-weight: 600;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.menu-item .mi-sub {
  display: block;
  margin-top: 1px;
  font-size: 12px;
  color: var(--text-dim);
}
.menu-item .mi-page {
  flex: 0 0 auto;
  font-size: 12px;
  font-variant-numeric: tabular-nums;
  color: var(--text-dim);
}

/* ------------------------------------------------------------ responsive */

@media (max-width: 720px) {
  :root { --topbar-h: 54px; }
  .btn-label { display: none; }
  /* ...except the download's. Stripped of its words it is a bare 20px arrow
     beside a near-identical fullscreen glyph, with no hover to reveal the
     aria-label — on a phone that is simply not findable. It keeps its text and
     the brand truncates instead if the bar runs short. */
  .btn-download .btn-label { display: inline; }
  /* 40, not the 44 the touch guideline asks for: at 44 the filled red pill sits
     visibly heavy in a 54px bar. The whole row moves together so the three
     controls stay level. */
  .btn { min-height: 40px; }
  .btn-download { padding-top: 6px; padding-bottom: 6px; }
  .brand { flex: 0 1 auto; }
  .brand strong { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
  .stage { padding: 10px; }
  .nav-arrow { display: none; }  /* swipe instead */
  .brand span { display: none; }
}

@media (max-width: 420px) {
  /* Below this the full wording would push the wordmark into an ellipsis, so the
     download drops to "PDF" — with the accent and the arrow it still reads as
     the action rather than as chrome. */
  .btn-download .btn-label { display: none; }
  .btn-download .btn-label-short { display: inline; }
}

@media (prefers-reduced-motion: reduce) {
  * { animation-duration: 0.01ms !important; transition-duration: 0.01ms !important; }
}

/* ==========================================================================
   StPageFlip base styles (required by the library, which owns these classes)
   ========================================================================== */

.stf__parent {
  position: relative;
  display: block;
  box-sizing: border-box;
  transform: translateZ(0);
  touch-action: pan-y;
}
/* Do NOT give .stf__wrapper `position: absolute`. Upstream's stylesheet targets
   `.sft__wrapper` — a typo — so the wrapper is in practice an unstyled static
   block. Positioning it absolutely collapses it to zero width, which drags
   .stf__block (width: 100%) to 0 too. The library then reads a block width of 0,
   decides the layout is portrait, and no page can ever flip. Leave it static. */
.stf__block {
  position: absolute;
  width: 100%;
  height: 100%;
  box-sizing: border-box;
  perspective: 2000px;
}
.stf__item { display: none; position: absolute; transform-style: preserve-3d; }
.stf__outerShadow,
.stf__innerShadow,
.stf__hardShadow,
.stf__hardInnerShadow { position: absolute; left: 0; top: 0; }
