/*
 * llote docs theme -- a bespoke spiral-bound notebook, not a standard
 * Canary header/nav/#app layout. framework.css's #app/.site-header/.site-nav
 * rules are effectively unused here (see shell.html: no header, no nav) --
 * everything below is genuinely new, not an override of framework defaults.
 *
 * Brand colors come straight from llote's own mark (graphics-bin/logo-source.svg
 * in the llote repo, copied here as img/owl-mark.svg): #FF6600 orange,
 * #2E0F05 near-black brown ink.
 */

:root {
  color-scheme: light;
  --ink: #2e0f05;
  --accent: #ff6600;
  --paper: #fffdf6;
  --paper-line: rgba(70, 110, 190, 0.22);
  --paper-margin: rgba(196, 62, 48, 0.35);
  --wire: #9a9186;
  --desk: #e7e1d4;
  --desk-edge: #d8d0bd;
  --shadow-soft: rgba(46, 15, 5, 0.18);
  --flip-duration: 0.7s;
}

@font-face {
  font-family: "Arvo";
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url("/fonts/arvo-400.woff2") format("woff2");
}

@font-face {
  font-family: "Arvo";
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url("/fonts/arvo-700.woff2") format("woff2");
}

@media (prefers-reduced-motion: reduce) {
  :root {
    --flip-duration: 0.001s;
  }
}

html,
body {
  margin: 0;
  padding: 0;
  min-height: 100%;
  overflow: hidden;
}

body {
  background: radial-gradient(ellipse at 50% 0%, var(--desk) 0%, var(--desk-edge) 100%);
  color: var(--ink);
  font-family: "Arvo", Georgia, "Times New Roman", serif;
  line-height: 1.6;
  display: flex;
  flex-direction: column;
  align-items: center;
  min-height: 100vh;
  padding: 1.5vh 1rem 1rem;
  box-sizing: border-box;
}

* {
  box-sizing: border-box;
}

/* ---------------------------------------------------------------------
   The desk + notebook stage
   --------------------------------------------------------------------- */

.desk {
  display: flex;
  flex-direction: column;
  align-items: center;
  width: 100%;
  flex: 1;
  justify-content: center;
}

.notebook {
  position: relative;
  width: min(97vw, 720px, calc(90vh * 0.75));
  aspect-ratio: 3 / 4;
  perspective: 2200px;
  background: var(--accent);
  border-radius: 6px;
  box-shadow:
    0 2px 4px var(--shadow-soft),
    0 30px 60px -20px rgba(46, 15, 5, 0.45);
}

/* Spiral binding along the left edge, always on top of every page. Real
   ring artwork (img/ring-full.svg, img/ring-half.svg), used in its own
   native landscape orientation -- each ring pokes out sideways from the
   spine, so the tile is centered ON the page edge (half in, half out),
   not rotated into a vertical strip. One ring per tile via
   background-repeat: repeat-y. ring-half is missing the far loop-end
   (occluded by the thick cover board) and is swapped in only while the
   cover page is showing, via #notebook.on-cover toggled from
   root-copy/js/notebook.js. */
.spiral {
  position: absolute;
  left: -24px;
  top: 1%;
  /* Matches .page's own `bottom: 2.25rem` (the reserved control-dock strip)
     so the rings stop flush at the page stack's real bottom edge instead
     of running past it, over the dock. */
  bottom: 2.25rem;
  width: 48px;
  z-index: 900;
  background-image: url("/img/ring-full.svg");
  background-size: 48px 42px;
  /* `space` instead of `repeat-y`: the strip's height is never an exact
     multiple of the tile height, and repeat-y clips the last tile rather
     than skip it -- space distributes the leftover into the gaps instead,
     so every ring is always whole. */
  background-repeat: no-repeat space;
  filter: drop-shadow(0 1px 1px rgba(0, 0, 0, 0.25));
  pointer-events: none;
}

#notebook.on-cover .spiral {
  background-image: url("/img/ring-half.svg");
}

/* Shown briefly at the start of a turn between two interior pages (never
   the cover) -- toggled from root-copy/js/notebook.js's updateSpiralArt(),
   which also reverts it back to ring-full after the same delay used for
   the cover-opening swap. .on-turn is a forward ("right") turn;
   .on-turn-back is backward ("left") and reuses the cover's half-ring art,
   which reads correctly for that direction too. */
#notebook.on-turn .spiral {
  background-image: url("/img/ring-turn.svg");
}

#notebook.on-turn-back .spiral {
  background-image: url("/img/ring-half.svg");
}

/* ---------------------------------------------------------------------
   Pages
   --------------------------------------------------------------------- */

.page {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  bottom: 2.25rem;
  transform-style: preserve-3d;
  transform-origin: left center;
  transform: rotateY(0deg);
  transition: transform var(--flip-duration) cubic-bezier(0.45, 0.05, 0.55, 0.95);
  border-radius: 6px;
}

.page.no-anim {
  transition: none !important;
}

.page.flipped {
  transform: rotateY(-180deg);
}

.face {
  position: absolute;
  inset: 0;
  overflow: auto;
  backface-visibility: hidden;
  border-radius: 6px;
  background-color: var(--paper);
  background-image:
    repeating-linear-gradient(
      to bottom,
      transparent 0,
      transparent 27px,
      var(--paper-line) 28px
    ),
    linear-gradient(to right, transparent 0 42px, var(--paper-margin) 42px 43px, transparent 43px);
}

.face-front {
  padding: 3.25rem 1.75rem 2rem 3rem;
}

.face-back {
  transform: rotateY(180deg);
}

.page-content {
  max-width: 46ch;
  margin: 0 auto;
}

/* Toggled by notebook.js's applyCondensedIfNeeded() when a page's content
   is taller than it has room for -- a single step down, not a shrink-to-
   fit scale. em, not rem, so it only affects text that inherits size from
   .page-content (paragraphs, lists, code) -- .page-content h1 below stays
   its own fixed rem size regardless, same as every other page's heading. */
.page-content.is-condensed {
  font-size: 0.9em;
}

.page-content h1 {
  font-size: 1.9rem;
  margin: 0 0 1rem;
  color: var(--ink);
}

.page-content p,
.page-content ul,
.page-content ol {
  margin: 0 0 1rem;
}

.page-content strong {
  color: var(--accent);
}

.page-content img {
  display: block;
  max-width: 55%;
  margin: 0 auto 1rem;
}

/* Cover page (always PAGES[0], see root-copy/js/notebook.js) gets its own
   treatment -- just the mark and a big friendly wordmark underneath it,
   nothing else. content/index.md puts the image before the "# llote"
   heading, so plain block flow already stacks them mark-then-wordmark. */
.notebook > .page:first-of-type .page-content {
  text-align: center;
  padding-top: 10%;
}

.notebook > .page:first-of-type .page-content img {
  max-width: 70%;
  margin-bottom: 1.5rem;
}

/* Cover is a solid-color board, front and back -- like a real notebook's
   cover vs. its plain-paper interior pages. No ruled-line/margin texture
   here, just the brand color the owl mark's own background already
   matches, so the mark reads as debossed straight into the cover. */
.notebook > .page:first-of-type .face-front,
.notebook > .page:first-of-type .face-back {
  background-color: var(--accent);
  background-image: none;
}

.notebook > .page:first-of-type .page-content h1 {
  font-size: 3.75rem;
  font-weight: 700;
  letter-spacing: -0.01em;
  margin: 0;
}

.page-content code {
  background: rgba(46, 15, 5, 0.08);
  padding: 0.1rem 0.35rem;
  border-radius: 4px;
  font-size: 0.9em;
}

/* The built-in "code" widget (widgets/code.css) reads framework.css's dark-
   theme tokens (--bg-elevated/--text-dim/--border), which this paper theme
   never redefines site-wide -- overridden here instead, scoped to the
   widget, so the rest of the light paper palette stays untouched. */
.page-content .code-widget-lang {
  color: color-mix(in srgb, var(--ink) 55%, transparent);
}

.page-content .code-widget pre {
  background: var(--ink);
  border-color: var(--ink);
}

.page-content .code-widget code {
  color: var(--paper);
}

/* The built-in "downloads" widget (widgets/downloads.css) has the same
   dark-theme-token problem as the code widget above -- fixed the same way,
   scoped here instead of touching the shared widget file. */
.page-content .downloads-widget {
  background: none;
  border-color: color-mix(in srgb, var(--ink) 25%, transparent);
}

.page-content .downloads-widget h3 {
  color: var(--ink);
}

.page-content .downloads-widget a.download-button {
  background: color-mix(in srgb, var(--ink) 5%, var(--paper));
}

.page-content .copy-command-label {
  color: color-mix(in srgb, var(--ink) 55%, transparent);
}

.page-content .copy-command-text {
  background: var(--paper);
  border-color: color-mix(in srgb, var(--ink) 25%, transparent);
  color: var(--ink);
}

.page-content .copy-command-button:hover {
  color: var(--paper);
}

/* The "corner-tag" widget (widgets/corner-tag.css) has the same
   dark-theme-token problem as the widgets above -- fixed the same way.
   Full-strength ink, not the muted treatment the other widgets get above,
   and no all-caps -- this is meant to read like a plain running-header
   label, not a stamp. */
.page-content .corner-tag-widget {
  color: var(--ink);
  text-transform: none;
}

/* The "page-number" widget (widgets/page-number.css) has the same
   dark-theme-token problem as the widgets above -- fixed the same way,
   matched to corner-tag's full-strength-ink treatment since it's meant to
   read as the same running-header style, just the opposite corner. */
.page-content .page-number-widget {
  color: var(--ink);
}

/* Depth cue: a shadow that rises and falls once per flip, synced via the
   .turning class added right when a flip starts and removed on
   transitionend (see root-copy/js/notebook.js). */
.shadow {
  position: absolute;
  inset: 0;
  pointer-events: none;
  opacity: 0;
  background: linear-gradient(to right, rgba(0, 0, 0, 0.45), transparent 55%);
}

.page.turning .shadow {
  animation: pageCurl var(--flip-duration) ease;
}

@keyframes pageCurl {
  0% {
    opacity: 0;
  }
  48% {
    opacity: 0.4;
  }
  100% {
    opacity: 0;
  }
}

/* ---------------------------------------------------------------------
   Controls
   --------------------------------------------------------------------- */

/* Docked to the notebook's own bottom edge (see .page's `bottom: 2.25rem`
   above, which reserves this strip) instead of a separate row below the
   notebook -- takes less total vertical space and lets the notebook itself
   grow into what that used to cost. z-index below every .page (see
   applyStacking() in root-copy/js/notebook.js: its total-i/total+i values
   are always >= 1) so a turning page's corner swings up and over this dock
   -- like it would over a real notebook's binding -- instead of the dock
   cutting across the animation. */
.notebook-controls {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  height: 2.25rem;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 0.75rem;
  background: var(--ink);
  border-radius: 0 0 6px 6px;
  z-index: 0;
}

.notebook-nav-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 1.5rem;
  height: 1.5rem;
  border-radius: 50%;
  background: color-mix(in srgb, var(--paper) 14%, transparent);
  color: var(--paper);
  font-size: 0.8rem;
  text-decoration: none;
  transition: transform 0.15s ease, opacity 0.15s ease, background 0.15s ease;
}

.notebook-nav-btn:hover {
  background: color-mix(in srgb, var(--paper) 24%, transparent);
  text-decoration: none;
}

.notebook-nav-btn[aria-disabled="true"] {
  opacity: 0.35;
  pointer-events: none;
}

.notebook-indicator {
  font-size: 0.68rem;
  color: var(--paper);
  text-align: center;
}

.site-footer {
  padding: 1rem 0 0;
  color: var(--ink);
  opacity: 0.55;
  font-size: 0.8rem;
  text-align: center;
}

/* ---------------------------------------------------------------------
   Responsive
   --------------------------------------------------------------------- */

@media (max-width: 480px) {
  .notebook {
    width: 96vw;
  }

  .face-front {
    padding: 2.75rem 1.25rem 1.5rem 2.25rem;
  }

  .page-content h1 {
    font-size: 1.5rem;
  }
}
