@import url('https://fonts.googleapis.com/css2?family=Geist:wght@500;600&family=Instrument+Serif&display=swap');

/* Tip 006: square cards that open a little, like a book, when hovered. */

.tip-stage:has(> .tip-credit) { padding: 0; }

.area-top,
.area-bottom {
  position: absolute;
  left: 0;
  right: 0;
}

/* Above: the books on a gallery wall, each under its own spotlight: a
   narrow beam from the ceiling opening into a pool of warm light. The
   pools sit over the three books (centres 212, 540 and 868). */
.area-top {
  top: 0;
  height: 720px;
  --spot: rgba(255, 253, 248, 1);
  --beam: rgba(255, 251, 242, 0.6);
  background:
    radial-gradient(150px 250px at 212px 350px, var(--spot), rgba(255, 244, 222, 0) 100%),
    radial-gradient(150px 250px at 540px 350px, var(--spot), rgba(255, 244, 222, 0) 100%),
    radial-gradient(150px 250px at 868px 350px, var(--spot), rgba(255, 244, 222, 0) 100%),
    linear-gradient(180deg, #f1eade, #f6f1e8 60%, #f2ece1);
}

/* Plaster: a fine warm grain across the wall. Laid on normally (not
   blended), so the wall never has to be re-composited under the books. */
.area-top::after {
  content: "";
  position: absolute;
  inset: 0;
  background:
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='220' height='220'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='3' stitchTiles='stitch'/%3E%3CfeColorMatrix values='0 0 0 0 0.55 0 0 0 0 0.36 0 0 0 0 0.2 0 0 0 0.09 0'/%3E%3C/filter%3E%3Crect width='220' height='220' filter='url(%23n)'/%3E%3C/svg%3E");
  pointer-events: none;
}

/* The beams, fading out where the books stand in their way. */
.area-top::before {
  content: "";
  position: absolute;
  inset: 0;
  background:
    conic-gradient(from 166deg at 212px -60px, transparent 0deg, var(--beam) 10deg 18deg, transparent 28deg, transparent),
    conic-gradient(from 166deg at 540px -60px, transparent 0deg, var(--beam) 10deg 18deg, transparent 28deg, transparent),
    conic-gradient(from 166deg at 868px -60px, transparent 0deg, var(--beam) 10deg 18deg, transparent 28deg, transparent);
  -webkit-mask: linear-gradient(180deg, #000 0, #000 30%, transparent 52%);
  mask: linear-gradient(180deg, #000 0, #000 30%, transparent 52%);
}

/* Below: the rule and the plan view, in dark mode. */
.area-bottom {
  top: 720px;
  bottom: 0;
  background: #151515;
}

/* ---------- Cards ---------- */

.shelf {
  position: absolute;
  top: 220px;
  left: 0;
  right: 0;
  display: flex;
  justify-content: center;
  gap: 48px;
}

/* Each card keeps its own perspective, so it opens toward the viewer
   whichever column it sits in. */
.book {
  position: relative;
  width: 280px;
  height: 280px;
  perspective: 1100px;
  perspective-origin: 30% 50%;
}

.book-body {
  position: absolute;
  inset: 0;
  transform-style: preserve-3d;
}

/* Light from above throws the book's shadow down the wall. A tight
   shadow at rest hands over to a longer, softer one as the cover stands
   off the wall; scripts move them with opacity and transform only, so the
   blur is drawn once. */
.shadow {
  --ink: 62, 50, 40;
  position: absolute;
  inset: 0;
  z-index: -1;
  border-radius: 32px;
  transform-origin: 30% 0;
  will-change: opacity, transform;
  pointer-events: none;
}

/* Each shadow is two solid blurred shapes in a near-neutral warm grey: a
   tight, darker contact shadow at the foot and a faint, wide ambient one.
   Shut, it hugs the edge like any flat card's; open, it drops and spreads
   as the cover stands off the surface.
   (Solid, not box-shadow, which is hollow and would show as a ring once
   the cover swings off it.) */
.shadow::before,
.shadow::after {
  content: "";
  position: absolute;
  border-radius: 32px;
}

.shadow-near::before { inset: 50% 4px 0 4px; background: rgba(var(--ink), calc(0.22 * var(--depth, 1))); filter: blur(4px); transform: translateY(2px); }
.shadow-near::after { inset: 12px 0 -2px 0; background: rgba(var(--ink), calc(0.12 * var(--depth, 1))); filter: blur(14px); transform: translateY(6px); }
.shadow-far { opacity: 0; }
.shadow-far::before { inset: 45% 6px -6px 6px; background: rgba(var(--ink), calc(0.2 * var(--depth, 1))); filter: blur(12px); transform: translateY(12px); }
.shadow-far::after { inset: 18px -14px -22px -14px; background: rgba(var(--ink), calc(0.16 * var(--depth, 1))); filter: blur(38px); transform: translateY(26px); }

/* Cover, pages and back cover share the left edge as their spine. */
.layer {
  position: absolute;
  inset: 0;
  box-sizing: border-box;
  border-radius: 32px;
  corner-shape: superellipse(1.25);
  transform-origin: 0 50%;
  backface-visibility: hidden;
}

/* Bookcloth: fine woven grain over the cover colour. */
.book {
  --cloth: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='160' height='160'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.9 0.35' numOctaves='2' stitchTiles='stitch'/%3E%3CfeColorMatrix values='0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 0 0 0 0.09 0'/%3E%3C/filter%3E%3Crect width='160' height='160' filter='url(%23n)'/%3E%3C/svg%3E");
  --paper: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='160' height='160'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='1.2' numOctaves='2' stitchTiles='stitch'/%3E%3CfeColorMatrix values='0 0 0 0 0.4 0 0 0 0 0.36 0 0 0 0 0.3 0 0 0 0.06 0'/%3E%3C/filter%3E%3Crect width='160' height='160' filter='url(%23n)'/%3E%3C/svg%3E");
}

/* A hardcover whose whole face is an ASCII picture, with the title on it.
   Light from above leaves its top edge bright and its foot in shade. */
.cover {
  overflow: hidden;
  background: var(--cover);
}

.cover .art {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
}

.cover::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 2;
  border-radius: inherit;
  background: linear-gradient(180deg, rgba(255, 250, 238, 0.16) 0%, rgba(255, 250, 238, 0) 30%, rgba(46, 22, 8, 0) 55%, rgba(46, 22, 8, 0.48) 100%);
  pointer-events: none;
}

/* The bevel, drawn along the same path the layer is clipped to. */
.bevel {
  position: absolute;
  inset: 0;
  z-index: 4;
  width: 100%;
  height: 100%;
  pointer-events: none;
}

.title {
  position: absolute;
  left: 40px;
  right: 20px;
  bottom: 22px;
  z-index: 3;
  color: var(--ink, #f4eee0);
  font: 400 36px/1 'Instrument Serif', var(--tip-font-serif);
  letter-spacing: -0.01em;
  white-space: nowrap;
  text-shadow: 0 1px 10px color-mix(in srgb, var(--cover) 60%, transparent);
}

.back {
  background: var(--cloth), color-mix(in srgb, var(--cover) 72%, #000000);
  box-shadow: inset 0 -2px 0 rgba(0, 0, 0, 0.2), inset 0 0 0 1px rgba(0, 0, 0, 0.12);
}

/* Pages are a little smaller than the covers, like a book block, and
   shade toward the spine. Radii nest: 32 outside, 32 - 8 = 24 inside. */
.page {
  inset: 8px 8px 8px 4px;
  padding: 24px 20px 24px 28px;
  overflow: hidden;
  border-radius: 24px;
  background:
    repeating-linear-gradient(90deg, rgba(20, 22, 16, 0) 0 2px, rgba(20, 22, 16, 0.07) 2px 3px) right / 14px 100% no-repeat,
    linear-gradient(90deg, #ddd8cc 0%, #f4f1e9 10%, #fbf9f4 30%, #f6f3ec 100%),
    var(--paper);
  background-blend-mode: normal, multiply, normal;
  box-shadow: inset 0 0 0 1px rgba(20, 22, 16, 0.1), inset -1px 0 0 rgba(255, 255, 255, 0.8);
}

/* The leaf in front casts a shadow onto this one, deepest near the spine,
   fading as the two spread apart. */
.page::after {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: inherit;
  background: linear-gradient(90deg, rgba(20, 22, 16, 0.32), rgba(20, 22, 16, 0.08) 55%, rgba(20, 22, 16, 0) 85%);
  opacity: var(--shade, 0);
  pointer-events: none;
}

/* Page contents: a chapter heading over justified lines of type. */
.chapter {
  display: block;
  margin: 2px 0 14px;
  color: #8a8478;
  font: italic 600 16px/1 var(--tip-font-accent);
  letter-spacing: 0.02em;
}

.page .line {
  display: block;
  height: 5px;
  margin-bottom: 9px;
  border-radius: 999px;
  background: #cfcabd;
}

.page .gap { display: block; height: 10px; }

/* ---------- Documentation set ---------- */

/* Later sets start hidden, and out of the paint entirely; scripts fade
   them in and out. */
.tip-stage [data-step="2"],
.tip-stage [data-step="3"] { opacity: 0; visibility: hidden; }

/* A cool grey wall with a faint dot grid and soft light from above. */
.wall-doc {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  height: 720px;
  background:
    radial-gradient(rgba(60, 66, 76, 0.12) 1px, transparent 1.4px) 0 0 / 24px 24px,
    radial-gradient(ellipse 70% 60% at 50% 30%, rgba(255, 255, 255, 0.9), rgba(255, 255, 255, 0) 100%),
    linear-gradient(180deg, #e3e5e8, #eceef0 60%, #e6e8eb);
}

.is-doc { --cover: #f3f3f1; --ink: #1d1f23; --soft: #8b8f97; --rule: #c9ccd1; }
.is-doc.tone-mist { --cover: #dfe1e4; --ink: #1d1f23; --soft: #7d828b; --rule: #b9bdc4; }
.is-doc.tone-graphite { --cover: #2a2c30; --ink: #f1f2f3; --soft: #8d929b; --rule: #4b4f56; }

/* Neutral shadows on the cool wall. */
.is-doc .shadow,
.is-plain .shadow { --ink: 30, 34, 40; }
/* Ordinary cards sit close to the page: a lighter shadow. */
.is-plain .shadow { --depth: 0.5; }

/* A plain board: title, kind, number and version, and one line diagram. */
.is-doc .cover {
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  padding: 24px 26px;
  color: var(--ink);
}

.is-doc .cover::after {
  background: linear-gradient(180deg, rgba(255, 255, 255, 0.18) 0%, rgba(255, 255, 255, 0) 30%, rgba(20, 24, 30, 0) 60%, rgba(20, 24, 30, 0.1) 100%);
}

.doc-head {
  display: flex;
  justify-content: space-between;
  padding-bottom: 10px;
  border-bottom: 1px solid var(--rule);
  color: var(--soft);
  font: 500 13px/1 var(--tip-font-mono);
  letter-spacing: 0.04em;
}

.doc-mark {
  align-self: flex-end;
  width: 84px;
  height: 82px;
  fill: none;
  stroke: var(--rule);
  stroke-width: 1.5;
  stroke-linecap: round;
}

.doc-mark .on { stroke: var(--ink); }
.doc-mark rect.on,
.doc-mark circle.on { fill: var(--ink); }

.doc-text { display: grid; gap: 10px; }
.doc-text b { font: 600 27px/1.08 'Geist', var(--tip-font-sans); letter-spacing: -0.02em; }
.doc-text small { color: var(--soft); font: 500 14px/1 'Geist', var(--tip-font-sans); }

.is-doc .back { background: color-mix(in srgb, var(--cover) 88%, #000000); }

.is-doc .page {
  background:
    repeating-linear-gradient(90deg, rgba(30, 34, 40, 0) 0 2px, rgba(30, 34, 40, 0.06) 2px 3px) right / 14px 100% no-repeat,
    linear-gradient(90deg, #dcdee1 0%, #f3f4f5 10%, #fbfbfb 30%, #f6f7f8 100%);
}

.is-doc .chapter { color: #7d828b; font: 500 13px/1 'Geist', var(--tip-font-sans); letter-spacing: 0.02em; }
.is-doc .page .line { background: #d3d6da; }

/* The three sets, as a segmented control whose thumb slides between them. */
.modes {
  position: absolute;
  top: 72px;
  left: 50%;
  z-index: 5;
  display: grid;
  grid-template-columns: 1fr 1fr 1fr;
  padding: 4px;
  border-radius: 16px;
  corner-shape: superellipse(1.25);
  background: rgba(255, 255, 255, 0.62);
  box-shadow: inset 0 0 0 1px rgba(30, 34, 40, 0.08);
  transform: translateX(-50%);
}

.modes span {
  position: relative;
  z-index: 1;
  padding: 10px 20px;
  color: rgba(29, 31, 35, 0.48);
  font: 500 18px/1 'Geist', var(--tip-font-sans);
  text-align: center;
  white-space: nowrap;
}

.modes span { cursor: pointer; transition: color 160ms ease; }
.modes span:hover { color: #1d1f23; }
.modes span.is-on { color: #1d1f23; }

/* Thumb: 4 inside a 16 control, so 12. */
.modes-thumb {
  position: absolute;
  top: 4px;
  bottom: 4px;
  left: 4px;
  width: calc((100% - 8px) / 3);
  border-radius: 12px;
  corner-shape: superellipse(1.25);
  background: #ffffff;
  box-shadow: 0 1px 2px rgba(30, 34, 40, 0.1), 0 4px 12px -4px rgba(30, 34, 40, 0.16);
  transform: translateX(calc(100% * var(--mode, 0)));
}

/* ---------- Everyday set ---------- */

/* An ordinary app surface. */
.wall-plain {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  height: 720px;
  background: linear-gradient(180deg, #f5f6f8, #f8f9fa);
}

/* Plain product cards: white, a hairline edge, a soft shadow, 20 radius
   (pages 8 in, so 12). The edge is drawn by the same path as the clip. */
.is-plain { --cover: #ffffff; }
.is-plain .layer { border-radius: 20px; }
.is-plain .page { border-radius: 12px; }
.is-plain .back { background: #eef0f2; }

/* On plain and minimal cards the back board sits a little inside the
   cover, so it never peeks out past the cover's foreshortened corners. */
.is-plain .back,
.is-doc .back { inset: 6px; }
.is-plain .back { border-radius: 14px; }
.is-doc .back { border-radius: 26px; }
.is-plain .cover::after { background: none; }

.is-plain .cover {
  display: flex;
  flex-direction: column;
  padding: 24px;
  color: #16181d;
}

/* Icon and arrow on one centre line, the title and description right under
   them, and a meta line held to the foot by a hairline. */
.plain-top {
  display: flex;
  justify-content: space-between;
  align-items: center;
}

.plain-icon {
  display: grid;
  place-items: center;
  width: 48px;
  height: 48px;
  border-radius: 12px;
  corner-shape: superellipse(1.25);
  background: #f2f4f6;
  color: #3d424b;
}

.plain-icon svg,
.plain-arrow {
  width: 24px;
  height: 24px;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.8;
}

.plain-arrow { color: #9aa0a9; }

.plain-text { display: grid; gap: 6px; margin-top: 20px; }

.plain-foot {
  display: flex;
  justify-content: space-between;
  margin-top: auto;
  padding-top: 16px;
  border-top: 1px solid #edeff2;
  color: #8a909a;
  font: 500 14px/1 'Geist', var(--tip-font-sans);
}
.plain-text b { font: 600 24px/1.15 'Geist', var(--tip-font-sans); letter-spacing: -0.015em; }
.plain-text small { color: #6b717c; font: 500 15px/1.4 'Geist', var(--tip-font-sans); }

.is-plain .page {
  background: linear-gradient(90deg, #e9ebee 0%, #f7f8f9 10%, #ffffff 30%);
}
.is-plain .chapter { color: #6b717c; font: 600 13px/1 'Geist', var(--tip-font-sans); }
.is-plain .page .line { background: #e1e4e8; }

/* ---------- Cursor ---------- */

.tip-pointer .hand {
  width: 76px;
  height: 76px;
  transition: none;
}

.tip-pointer .hand-point { left: -31px; top: -12px; transform-origin: 31px 12px; }

.tip-pointer:not([data-cursor="arrow"]) svg:not(.hand),
.tip-pointer:not([data-cursor="point"]) .hand-point { display: none; }

/* ---------- Rule and plan ---------- */

.caption {
  position: absolute;
  left: 0;
  right: 0;
  top: 788px;
  display: grid;
  justify-items: center;
}

.caption .code {
  margin: 0;
  padding: 24px 40px;
  border-radius: 24px;
  corner-shape: superellipse(1.25);
  background: #1f1f1f;
  box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.06);
  color: #d4d4d4;
  font: 500 30px/1.6 var(--tip-font-mono);
  text-align: left;
}

.code .fn { color: #9ecbff; }
.code .num { color: #fcd116; }

.plan {
  position: absolute;
  left: 180px;
  top: 972px;
  width: 720px;
  height: 300px;
  overflow: visible;
}

.plan .leaf { stroke: #6b6b6b; stroke-width: 2.5; stroke-linecap: round; }
.plan .leaf.is-cover { stroke: #f5f5f5; stroke-width: 3.5; }
.plan .leaf.is-back { stroke: #3a3a3a; stroke-width: 3.5; }
.plan .spine { fill: #f5f5f5; }
.plan .arc { fill: none; stroke: rgba(255, 255, 255, 0.18); stroke-width: 2; stroke-dasharray: 2 8; }
.plan text {
  fill: #f5f5f5;
  font: 500 21px 'Geist', var(--tip-font-sans);
  font-variant-numeric: tabular-nums;
}
.plan text.dim { fill: #7a7a7a; }

.tip-credit { bottom: 34px; color: #8f8f8f; }
.tip-credit img { filter: invert(1); }
