/* ============================================================
   Dhnapond Tangsitthichai — Webfolio 2026
   Slide deck rendered 1:1 from the UI-Design exports (1920 artboard).
   ============================================================ */

:root {
  --page-max: 1920px;
  --bg: #eef3f7;
  --accent: #58bdd6;
  --accent-soft: #fcd057;
  --ink: #2f6b80;
  --text-primary-normal: #17708a; /* Colors/Brand/Text/Primary/Normal */
}

* {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}

html {
  scroll-behavior: smooth;
  background: var(--bg);
}

body {
  background: var(--bg);
  font-family: "Readex Pro", "Athiti", system-ui, -apple-system, "Segoe UI", sans-serif;
  color: var(--ink);
  overflow-x: hidden;
  -webkit-font-smoothing: antialiased;
}

/* ---------- deck ---------- */

.deck {
  width: 100%;
  display: block;
  container-type: inline-size;
}

/* full-width band for the page background; the artwork stays 1920 wide at most */
.slide__inner {
  position: relative;
  width: 100%;
  max-width: var(--page-max);
  margin: 0 auto;
}

.slide {
  position: relative;
  display: block;
  width: 100%;
  line-height: 0; /* kill inline gaps so pages butt up exactly */
  font-size: 0;
}

.slide__inner > img,
.slide__inner > svg.page {
  display: block;
  width: 100%;
  height: auto;
}

.slide__inner > img {
  user-select: none;
  -webkit-user-drag: none;
}

svg.page text {
  text-rendering: geometricPrecision;
}

.slide__inner > svg.page {
  overflow: hidden;
  isolation: isolate; /* keep the artwork's blend modes inside its own page */
}

/* Reserves the page's height so anchors land correctly before it has loaded. */
.slide--lazy .slide__inner {
  aspect-ratio: 16 / 9;
}

/* covers scale with the full width of the screen, past 1920 too */
.slide--wide .slide__inner {
  max-width: none;
}

/* ---------- work-name links (inside the contents + divider pages) ---------- */

.wl {
  cursor: pointer;
}

.wl:hover .wl-glyph,
.wl:focus-visible .wl-glyph {
  fill: var(--text-primary-normal);
}

/* ---------- download button on cover-1 ----------
   Over the artboard rect x1552 y218 w224 h47. The state images are 384x203 with
   their button at 80,80, so they sit offset behind this hit area. */

.hotspot-download {
  position: absolute;
  left: 80.8333%;
  top: 20.1852%;
  width: 11.6667%;
  height: 4.3519%;
  border-radius: 100px;
  display: block;
  font-size: 0;
  cursor: pointer;
}

.hotspot-download {
  animation: download-glow 2s ease-in-out infinite alternate;
}

/* loads the hover and pressed images up front, so the first hover never shows a blank */
.hotspot-download::before {
  content: "";
  position: absolute;
  width: 1px;
  height: 1px;
  opacity: 0;
  pointer-events: none;
  background-image: url("../ui/download-hover.svg"), url("../ui/download-pressed.svg");
}

@keyframes download-glow {
  from {
    box-shadow: 0 0 8px 0 rgba(252, 208, 87, 0.25);
  }
  to {
    box-shadow: 0 0 28px 8px rgba(252, 208, 87, 0.65);
  }
}

.hotspot-download::after {
  content: "";
  position: absolute;
  left: -35.714%;
  top: -165.96%;
  width: 171.429%;
  height: 431.915%;
  background: url("../ui/download-default.svg") center / 100% 100% no-repeat;
  pointer-events: none;
}

.hotspot-download:hover::after,
.hotspot-download:focus-visible::after {
  background-image: url("../ui/download-hover.svg");
}

/* the pressed file is 392x211 with its button at 84,84 (it adds a ring) */
.hotspot-download:active::after {
  background-image: url("../ui/download-pressed.svg");
  left: -37.5%;
  top: -174.47%;
  width: 175%;
  height: 448.94%;
}

/* ---------- back to top ----------
   The hit area is the design's circle at a fixed size (icon 32px). The state images (168px, circle at 40; pressed 176px, circle at 44)
   sit behind it at their real size, shadow included. */

.to-top {
  position: fixed;
  right: 48px;
  bottom: 48px;
  z-index: 45;
  /* the 40px icon of the 88px design circle, drawn at 32px: 88 x 32 / 40 */
  width: 70.4px;
  height: 70.4px;
  padding: 0;
  border: 0;
  border-radius: 50%;
  background: none;
  cursor: pointer;
  opacity: 0;
  transform: translateY(16px);
  pointer-events: none;
  transition: opacity 0.3s ease, transform 0.3s ease;
}

/* phones: the whole button is 32px; its images scale with it */
@media (max-width: 767px) {
  .to-top {
    right: 16px;
    bottom: 16px;
    width: 32px;
    height: 32px;
  }
}

.to-top.is-visible {
  opacity: 1;
  transform: none;
  pointer-events: auto;
}

.to-top::after {
  content: "";
  position: absolute;
  left: -45.4545%;
  top: -45.4545%;
  width: 190.909%;
  height: 190.909%;
  background: url("../ui/up-default.svg") center / 100% 100% no-repeat;
  pointer-events: none;
}

.to-top:hover::after,
.to-top:focus-visible::after {
  background-image: url("../ui/up-hover.svg");
}

.to-top:active::after {
  background-image: url("../ui/up-pressed.svg");
  left: -50%;
  top: -50%;
  width: 200%;
  height: 200%;
}

/* loads the other two states up front */
.to-top::before {
  content: "";
  position: absolute;
  width: 1px;
  height: 1px;
  opacity: 0;
  background-image: url("../ui/up-hover.svg"), url("../ui/up-pressed.svg");
}

.to-top:focus-visible {
  outline: 3px solid var(--accent-soft);
  outline-offset: 4px;
}

/* ---------- reading progress ---------- */

.progress {
  position: fixed;
  top: 0;
  left: 0;
  height: 3px;
  width: 100%;
  z-index: 40;
  background: transparent;
  pointer-events: none;
}

.progress__bar {
  height: 100%;
  width: 0;
  background: linear-gradient(90deg, var(--accent) 0%, #8fd6a4 55%, var(--accent-soft) 100%);
  transition: width 0.12s linear;
}

/* ---------- misc ---------- */

a:focus-visible {
  outline: 3px solid var(--accent-soft);
  outline-offset: 2px;
}

@media print {
  .progress {
    display: none;
  }
}

@media (prefers-reduced-motion: reduce) {
  .hotspot-download {
    animation: none;
    box-shadow: 0 0 18px 4px rgba(252, 208, 87, 0.45);
  }
  html {
    scroll-behavior: auto;
  }
  * {
    transition: none !important;
  }
}
