/* Guide pages (site/guide/*, generated by scripts/build-guide-site.mjs).
 * Rides on styles.css tokens — this file only adds the docs layout + article
 * typography. The topbar is always shown here (class "shown" baked in). */

.guide-body {
  padding-top: var(--topbar-h);
}

.guide-layout {
  display: grid;
  grid-template-columns: 240px minmax(0, 1fr);
  gap: 48px;
  padding-top: 40px;
  padding-bottom: 72px;
  /* Sidebar (240) + gap (48) + the 860px content column + padding. */
  max-width: 1196px;
}

/* ------------------------------------------------------------- Sidebar */

.guide-sidebar {
  position: sticky;
  top: calc(var(--topbar-h) + 21px);
  align-self: start;
  /* At the top of the page (not yet stuck) the nav starts well below the
     chapter title instead of hugging the topbar; once scrolling sticks it,
     only the sticky `top` above governs. */
  margin-top: 128px;
  font-size: 0.92rem;
}

.guide-group {
  margin: 22px 0 6px;
  font-size: 0.72rem;
  font-weight: 700;
  letter-spacing: 0.09em;
  text-transform: uppercase;
  color: var(--muted);
}

.guide-sidebar ul {
  list-style: none;
  margin: 0;
  padding: 0;
}

.guide-sidebar a {
  display: block;
  padding: 5px 10px;
  border-radius: 8px;
  color: var(--fg);
  text-decoration: none;
}

.guide-sidebar a:hover {
  background: var(--bg-raised);
  color: var(--fg-bright);
}

.guide-sidebar a.active {
  background: color-mix(in oklab, var(--primary) 14%, transparent);
  color: var(--primary-soft);
  font-weight: 600;
}

/* ------------------------------------------------------------- Article */

.guide-content {
  min-width: 0;
  max-width: 860px;
}

/* The app screenshots are 2560px @2x (1280 CSS px): inline they fill the
   860px text column (≈66% of native) so their edges sit flush with the
   text, overriding the markdown's width="900" attribute — click for the
   100% lightbox (guide.js). External (Daz-side) photos keep their own
   size — no upscaling. */
.guide-content img[src^='screenshots/'] {
  width: 100%;
}

/* Small UI-detail shots (screenshots/detail-*.png) keep their natural size —
   stretching a 250px chip to column width would only blur it. */
.guide-content img[src^='screenshots/detail-'] {
  width: auto;
  max-width: 100%;
}

/* Side-by-side pairs (the align="top" images): vertical breathing room for
   when the narrow column wraps them into a stack. */
.guide-content img[align='top'] {
  margin-block: 10px;
}

.guide-content img {
  cursor: zoom-in;
}

/* ------------------------------------------------- Interaction clips */

/* The four guide clips are animated WebPs, and an animated WebP cannot be
   paused: dropped in as a plain <img> it loops at the reader forever. The build
   (`clickToPlayClips` in build-guide-site.mjs) therefore ships the clip's first
   frame as a still with a real <button> over it, and guide.js swaps the src on
   click. Nothing on a guide page moves until the reader asks it to — which also
   means there is no prefers-reduced-motion case left to answer here. */

.guide-content .clip {
  position: relative;
  display: inline-block;
  /* Kill the inline-box descender gap so the button's `inset: 0` lands exactly
     on the image edges instead of a few pixels below them. */
  line-height: 0;
  max-width: 100%;
}

/* Not the `zoom-in` every other guide image gets: a clip's click plays it, and
   clips deliberately do NOT open the lightbox (guide.js bails on `.clip`). */
.guide-content .clip img {
  cursor: pointer;
}

.clip-play {
  position: absolute;
  inset: 0;
  width: 100%;
  padding: 0;
  border: 0;
  border-radius: var(--radius);
  background: color-mix(in oklab, #000 34%, transparent);
  cursor: pointer;
  transition: background 140ms ease;
}

/* The disc. */
.clip-play::before {
  content: '';
  position: absolute;
  inset-inline-start: 50%;
  inset-block-start: 50%;
  width: 54px;
  height: 54px;
  transform: translate(-50%, -50%);
  border: 1px solid color-mix(in oklab, #fff 42%, transparent);
  border-radius: 50%;
  background: color-mix(in oklab, #000 58%, transparent);
  transition: opacity 140ms ease;
}

/* The glyph: a play triangle, nudged right of centre so it LOOKS centred in the
   disc (a triangle's optical centre is left of its bounding box). */
.clip-play::after {
  content: '';
  position: absolute;
  inset-inline-start: 50%;
  inset-block-start: 50%;
  width: 18px;
  height: 20px;
  transform: translate(-38%, -50%);
  background: #fff;
  clip-path: polygon(0 0, 100% 50%, 0 100%);
  transition: opacity 140ms ease;
}

.clip-play:hover {
  background: color-mix(in oklab, #000 22%, transparent);
}

.clip-play:focus-visible {
  outline: 2px solid var(--primary-soft);
  outline-offset: 2px;
}

/* Playing: the clip is why the reader is here, so nothing sits on top of it.
   The button stays (it is the stop control) and shows itself again on hover or
   keyboard focus, with the glyph swapped to a stop square. */
.clip.is-playing .clip-play {
  background: transparent;
}

.clip.is-playing .clip-play::before,
.clip.is-playing .clip-play::after {
  opacity: 0;
}

.clip.is-playing .clip-play:hover::before,
.clip.is-playing .clip-play:focus-visible::before,
.clip.is-playing .clip-play:hover::after,
.clip.is-playing .clip-play:focus-visible::after {
  opacity: 1;
}

.clip.is-playing .clip-play:hover::after,
.clip.is-playing .clip-play:focus-visible::after {
  width: 16px;
  height: 16px;
  transform: translate(-50%, -50%);
  clip-path: inset(0 round 2px);
}

/* ------------------------------------------------------------- Lightbox */

.guide-lightbox {
  position: fixed;
  inset: 0;
  z-index: 200;
  display: none;
  overflow: auto;
  padding: 32px;
  background: color-mix(in oklab, #000 78%, transparent);
  backdrop-filter: blur(6px);
  -webkit-backdrop-filter: blur(6px);
  cursor: zoom-out;
  text-align: center;
}

.guide-lightbox.open {
  display: flex;
  flex-direction: column;
}

/* Golden-section placement: the flexible spacers split the free vertical
   space 382:618, so the image sits in the upper part of the viewport. With
   an image taller than the viewport the spacers collapse to zero and the
   overlay simply scrolls (top stays reachable). */
.guide-lightbox::before {
  content: '';
  flex: 382 0 0;
}

.guide-lightbox::after {
  content: '';
  flex: 618 0 0;
}

.guide-lightbox .lightbox-inner {
  flex: none;
  /* Full width, NOT shrink-to-fit: the img's percentage max-width must resolve
     against a DEFINITE box. Fit-content made that circular and the image
     overflowed the wrapper to the right on phones (left margin, none right);
     the overlay's text-align keeps the image centered instead. */
  width: 100%;
}

.guide-lightbox img {
  display: inline-block;
  /* Never wider than the overlay's content box (its padding = the margin-x):
     on a phone the full-size screenshot used to overflow into a sideways
     scroll — now it fits the viewport and only scrolls vertically. */
  max-width: 100%;
  height: auto;
  border: 1px solid color-mix(in oklab, var(--border) 70%, transparent);
  border-radius: var(--radius);
  box-shadow: 0 24px 80px rgb(0 0 0 / 0.55);
}

/* Tighter margin-x on small screens — 32px each side eats a fifth of a phone. */
@media (max-width: 640px) {
  .guide-lightbox {
    padding: 16px;
  }
}

/* Rotated ("turn your phone") mode: a rotation-LOCKED phone never flips the
   browser to landscape, so a WIDE image in a portrait viewport rotates 90°
   (image + caption together) to use the screen's long axis — the video-player
   recipe. guide.js toggles the class from viewport + image geometry; with
   auto-rotate on, the viewport itself goes landscape and it never applies. */
.guide-lightbox.rotated {
  padding: 0;
  overflow: hidden;
}

.guide-lightbox.rotated::before,
.guide-lightbox.rotated::after {
  content: none;
}

.guide-lightbox.rotated .lightbox-inner {
  position: absolute;
  top: 50%;
  left: 50%;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  /* The box is the viewport with its axes swapped, then turned upright. */
  width: 100vh;
  height: 100vw;
  padding: 16px;
  transform: translate(-50%, -50%) rotate(90deg);
}

.guide-lightbox.rotated img {
  /* !important: guide.js sets an inline width on app screenshots — forced
     width + max-height would distort the aspect once rotated. */
  width: auto !important;
  max-width: 100%;
  max-height: 100%;
  /* Shrinkable flex item: image + caption must fit the box TOGETHER — with a
     rigid image the caption pushed the pair off-center and clipped the edge. */
  min-height: 0;
  flex: 0 1 auto;
}

.guide-lightbox.rotated .lightbox-caption {
  flex: none;
  margin: 10px 0 0;
}

.guide-lightbox .lightbox-caption {
  margin: 14px auto 0;
  max-width: 900px;
  color: var(--fg);
  font-style: italic;
  font-size: 0.95rem;
}

.guide-content h1 {
  /* Drop the chapter title to the sidebar's start (same offset the sidebar nav
     uses) so at the very top its baseline lines up with the "GUIDES" label
     across the gutter, instead of hugging the topbar. */
  margin: 111px 0 18px;
  font-size: clamp(1.7rem, 4vw, 2.3rem);
  font-weight: 800;
  letter-spacing: -0.015em;
  color: var(--fg-bright);
}

/* Sticky chapter titles: an h2 sticks right under the topbar and stays until
   its section ends — the next chapter's title pushes it away (each h2 chunk
   is wrapped in a .guide-section by build-guide-site.mjs, which bounds the
   sticky range). The opaque background covers content scrolling beneath. */
.guide-content h2 {
  position: sticky;
  /* -1px tucks the title under the topbar's border so no seam shows. */
  top: calc(var(--topbar-h) - 1px);
  z-index: 5;
  margin: 44px 0 12px;
  padding-top: 36px;
  padding-bottom: 20px;
  border-top: 1px solid color-mix(in oklab, var(--border) 45%, transparent);
  background: var(--bg);
  font-size: 1.45rem;
  font-weight: 750;
  color: var(--fg-bright);
}

/* The inter-chapter gap lives INSIDE each section (::after) instead of on the
   next h2's top margin — the gap then counts toward the sticky range, so a
   stuck title keeps sticking through it and only gets pushed away when the
   next chapter's divider actually reaches it. */
.guide-section:not(:last-of-type)::after {
  content: '';
  display: block;
  height: 44px;
}

.guide-section + .guide-section h2 {
  margin-top: 0;
}

/* Hash navigation lands the title below the topbar. h1/h2 clear only the
   topbar: an h1 has no chapter title above it, and a targeted h2 IS the one
   that docks (landing it lower would leave a gap, then it'd stick up anyway). */
.guide-content h1,
.guide-content h2 {
  scroll-margin-top: calc(var(--topbar-h) + 16px);
}

.guide-content h3 {
  margin: 28px 0 8px;
  font-size: 1.12rem;
  color: var(--fg-bright);
}

/* h3–h6 live INSIDE a section, so their h2 is docked under the topbar (≈84px)
   when you jump to one — clear that too (same offset as accordions), else the
   stuck h2 covers the heading the hash meant to reveal. EVERY id'd heading
   level needs this: an h4 without it scrolls clean under the fixed chrome and
   the visitor lands "somewhere random" (measured on #rom-overrides). */
.guide-content h3,
.guide-content h4,
.guide-content h5,
.guide-content h6 {
  scroll-margin-top: calc(var(--topbar-h) + 88px);
}

.guide-content .anchor {
  margin-left: 8px;
  color: var(--muted);
  text-decoration: none;
  opacity: 0;
}

.guide-content h1:hover .anchor,
.guide-content h2:hover .anchor,
.guide-content h3:hover .anchor {
  opacity: 1;
}

.guide-content a {
  color: var(--primary-soft);
  text-decoration: none;
}

.guide-content a:hover {
  text-decoration: underline;
}

.guide-content img {
  max-width: 100%;
  height: auto;
  border: 1px solid color-mix(in oklab, var(--border) 70%, transparent);
  border-radius: var(--radius);
}

.guide-content sub {
  color: var(--muted);
}

/* Screenshot paragraphs (image + <sub> caption): breathing room before the
   following text picks up again. */
.guide-content p[align='center'] {
  margin-block: 28px 36px;
}

.guide-content code {
  padding: 0.12em 0.38em;
  background: var(--bg-raised);
  border: 1px solid color-mix(in oklab, var(--border) 55%, transparent);
  border-radius: 6px;
  font-size: 0.88em;
}

.guide-content pre {
  padding: 14px 16px;
  background: var(--bg-raised);
  border: 1px solid color-mix(in oklab, var(--border) 55%, transparent);
  border-radius: var(--radius);
  overflow-x: auto;
}

.guide-content pre code {
  padding: 0;
  background: none;
  border: 0;
}

.guide-content blockquote {
  margin: 16px 0;
  padding: 2px 18px;
  border-left: 3px solid var(--border);
  color: var(--muted);
}

.guide-content hr {
  margin: 36px 0;
  border: 0;
  border-top: 1px solid color-mix(in oklab, var(--border) 45%, transparent);
}

/* Data tables (markdown `| … |`). The <details> wrapper tables are unstyled
   below instead. */
.guide-content table {
  width: 100%;
  margin: 16px 0;
  border-collapse: collapse;
  font-size: 0.95rem;
}

.guide-content th,
.guide-content td {
  padding: 8px 12px;
  border: 1px solid color-mix(in oklab, var(--border) 55%, transparent);
  text-align: left;
  vertical-align: top;
}

.guide-content th {
  background: var(--bg-raised);
  color: var(--fg-bright);
}

/* Collapsed detail sections — GitHub-style <details><summary> + the guide's
   single-cell <table><tr><td> wrapper inside (rendered as a plain box). */
.guide-content details {
  margin: 16px 0;
  border: 1px solid color-mix(in oklab, var(--border) 70%, transparent);
  border-radius: var(--radius);
  background: color-mix(in oklab, var(--bg-raised) 60%, transparent);
}

.guide-content details {
  /* Hash navigation / the reveal scroll land below the sticky topbar AND the
     chapter title stuck beneath it (~56px tall). */
  scroll-margin-top: calc(var(--topbar-h) + 88px);
}

.guide-content details summary {
  position: relative;
  padding: 12px 44px 12px 16px;
  cursor: pointer;
  color: var(--fg-bright);
}

/* Accordion anchor: the same "#" glyph the headings carry, in the summary's
   top right, shown on hover. Clicking it puts the accordion's #anchor in the
   URL and copies the full link to the clipboard (guide.js) — clicking
   anywhere else on the title still toggles the box. */
/* Scoped under .guide-content so this outranks the `.guide-content a` link
   color — otherwise the glyph renders orange instead of the muted gray. */
.guide-content .details-anchor {
  position: absolute;
  top: 50%;
  right: 14px;
  transform: translateY(-50%);
  color: var(--muted);
  font-weight: 600;
  line-height: 1;
  text-decoration: none;
  opacity: 0;
  transition:
    opacity 120ms ease,
    color 120ms ease;
}

/* Stays the headings' muted gray on hover — only the copied flash colors it. */
.guide-content summary:hover .details-anchor {
  opacity: 1;
}

/* Brief "copied" confirmation after a click (guide.js toggles the class) —
   heading anchors and accordion anchors alike. */
.guide-content .details-anchor.copied,
.guide-content .anchor.copied {
  color: var(--primary);
  opacity: 1;
}

.guide-content details[open] summary {
  border-bottom: 1px solid color-mix(in oklab, var(--border) 45%, transparent);
  /* Docks underneath the stuck chapter title (h2 box ≈ 84px tall) while the
     accordion's content scrolls; the <details> bounds the sticky range, so
     the box's end pushes the bar away. Opaque take on the summary surface —
     the translucent details background would let content shine through. */
  position: sticky;
  top: calc(var(--topbar-h) + 82px);
  z-index: 4;
  background: color-mix(in oklab, var(--bg-raised) 60%, var(--bg));
  border-radius: var(--radius) var(--radius) 0 0;
}

/* Push the docked bar away 48px BEFORE the box actually ends: sticky is
   bounded by the details' CONTENT box, so trading 48px of it for padding
   (with the body pulled back over the padding) ends the range early while
   the rendered box stays pixel-identical. */
.guide-content details[open] {
  padding-bottom: 48px;
}

.guide-content details[open] > table {
  margin-bottom: -48px;
}

.guide-content details > table,
.guide-content details > table tr,
.guide-content details > table td {
  display: block;
  width: auto;
  margin: 0;
  padding: 0;
  border: 0;
}

/* The expanded body sits one shade darker than the summary bar (but still
   off the page background), so open accordions read as an inset area. */
.guide-content details > table {
  padding: 10px 16px 14px;
  background: color-mix(in oklab, var(--bg-raised) 25%, var(--bg));
  border-radius: 0 0 var(--radius) var(--radius);
}

/* GitHub-style alerts (> [!NOTE] / [!TIP] / …). */
.alert {
  margin: 16px 0;
  padding: 12px 18px;
  border-left: 3px solid var(--border);
  border-radius: 0 var(--radius) var(--radius) 0;
  background: color-mix(in oklab, var(--bg-raised) 70%, transparent);
}

.alert .alert-title {
  margin: 0 0 4px;
  font-weight: 700;
  font-size: 0.9rem;
}

.alert p {
  margin: 6px 0;
}

.alert-note {
  border-left-color: #4a8fd6;
}
.alert-note .alert-title {
  color: #7ab3e8;
}

.alert-tip {
  border-left-color: #3fa96f;
}
.alert-tip .alert-title {
  color: #6cc794;
}

.alert-important {
  border-left-color: #9a7ae8;
}
.alert-important .alert-title {
  color: #b9a3f2;
}

.alert-warning {
  border-left-color: #d9a326;
}
.alert-warning .alert-title {
  color: #e8c063;
}

.alert-caution {
  border-left-color: #d65454;
}
.alert-caution .alert-title {
  color: #e88484;
}

/* ------------------------------------------------------------- Pager */

.guide-pager {
  display: flex;
  justify-content: space-between;
  gap: 16px;
  margin-top: 56px;
  padding-top: 20px;
  border-top: 1px solid color-mix(in oklab, var(--border) 45%, transparent);
}

.pager-link {
  display: flex;
  flex-direction: column;
  gap: 2px;
  max-width: 46%;
  padding: 10px 16px;
  border: 1px solid color-mix(in oklab, var(--border) 70%, transparent);
  border-radius: var(--radius);
  text-decoration: none !important;
}

.pager-link span {
  font-size: 0.78rem;
  color: var(--muted);
}

.pager-link strong {
  color: var(--fg-bright);
}

.pager-link:hover {
  border-color: var(--primary);
}

.pager-link.next {
  margin-left: auto;
  text-align: right;
}

/* The topbar action cluster (search pill, divider, Download) and the search
   modal are SHARED with the landing page — styled in styles.css. */

/* ------------------------------------------------------------- Mobile */

@media (max-width: 900px) {
  .guide-layout {
    grid-template-columns: 1fr;
    gap: 24px;
  }

  .guide-sidebar {
    position: static;
    /* The 128px desktop offset only exists to line the nav up with the chapter
       title across the gutter — stacked above the article on mobile it's just
       a big empty gap under the topbar, so drop it right down. */
    margin-top: 24px;
    padding-bottom: 8px;
    border-bottom: 1px solid color-mix(in oklab, var(--border) 45%, transparent);
  }
}
